clone

a deno framework for local-first web apps that open instantly, work offline and sync when users choose

main
lofi / package / create.ts
create.ts 2.5K
1#!/usr/bin/env -S deno run -A23/**4 * The `deno run -A jsr:@nzip/lofi/create <name>` command: scaffolds a new5 * local-first PWA project from the validated starter template. Pass `--sync` to6 * also provision a managed Jazz app and write it into the project's `.env`, so7 * the app can offer synced, backed-up accounts from the first boot.8 *9 * @module10 */1112import { join } from "node:path";13import { createProject } from "./create_core.ts";14import {15 JAZZ_CLAIM_WINDOW_DAYS,16 JAZZ_DASHBOARD_URL,17 ProvisionError,18 provisionJazzApp,19} from "./tooling/provision.ts";2021function usage(): never {22 console.error("usage: deno run -A jsr:@nzip/lofi/create [--sync] <name>");23 Deno.exit(2);24}2526function parseArgs(args: string[]): { name: string; sync: boolean } {27 let name: string | undefined;28 let sync = false;29 for (const arg of args) {30 if (arg === "--sync") sync = true;31 else if (arg.startsWith("-")) usage();32 else if (name === undefined) name = arg;33 else usage();34 }35 if (name === undefined) usage();36 return { name, sync };37}3839const { name, sync } = parseArgs(Deno.args);4041try {42 const developmentPrefix = Deno.env.get("LOFI_CREATE_DEVELOPMENT") === "1"43 ? Deno.env.get("LOFI_CREATE_PACKAGE_PREFIX")44 : undefined;45 if (46 developmentPrefix &&47 (!developmentPrefix.startsWith("file:") || !developmentPrefix.endsWith("/"))48 ) {49 throw new Error("internal development package prefix must be a trailing-slash file URL");50 }51 const result = await createProject({52 cwd: Deno.cwd(),53 name,54 packagePrefix: developmentPrefix,55 });56 console.log(`Created ${result.displayPath}`);5758 if (sync) {59 console.log("");60 console.log("Provisioning a managed Jazz app for sync…");61 const provisioned = await provisionJazzApp({ path: join(result.destination, ".env") });62 console.log(` Jazz app ${provisioned.app.appId} → wrote .env`);63 console.log(64 ` Claim it within ${JAZZ_CLAIM_WINDOW_DAYS} days at ${JAZZ_DASHBOARD_URL} (admin secret is in .env); unclaimed apps expire.`,65 );66 }6768 console.log("");69 console.log("Next:");70 for (const command of result.nextCommands) console.log(` ${command}`);71} catch (error) {72 if (error instanceof ProvisionError) {73 console.error(`error: project created, but sync provisioning failed: ${error.message}`);74 console.error("Run `deno task jazz:provision` from the project once resolved.");75 Deno.exit(1);76 }77 console.error(`error: ${error instanceof Error ? error.message : String(error)}`);78 Deno.exit(1);79}