@flaredev/cli 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +47 -47
  2. package/dist/index.js +33 -6
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -1,47 +1,47 @@
1
- # @flaredev/cli
2
-
3
- The `flare` command for [Flare](https://flare-docs.codetotech.com), a
4
- batteries-included fullstack framework on Cloudflare Workers (vinext, D1,
5
- Drizzle, Better Auth, R2). It scaffolds apps, generates resources with an admin
6
- dashboard and REST API, runs migrations and deploys.
7
-
8
- ## Install
9
-
10
- ```sh
11
- npm install -g @flaredev/cli # or: pnpm add -g @flaredev/cli
12
- ```
13
-
14
- Or with the install scripts (they check for Node.js 22+ and use npm or pnpm):
15
-
16
- ```sh
17
- # macOS / Linux
18
- curl -fsSL https://flare-docs.codetotech.com/install.sh | bash
19
- ```
20
-
21
- ```powershell
22
- # Windows PowerShell
23
- irm https://flare-docs.codetotech.com/install.ps1 | iex
24
- ```
25
-
26
- Or skip the install entirely:
27
-
28
- ```sh
29
- npm create flare-framework@latest my-app
30
- npx @flaredev/cli create my-app
31
- ```
32
-
33
- ## Use
34
-
35
- ```sh
36
- flare create shop
37
- cd shop
38
- flare gen resource Product --fields "name:string, price:int, sku:string!"
39
- flare migrate
40
- flare dev
41
- flare deploy
42
- ```
43
-
44
- Run `flare --help` for every command, or read the
45
- [CLI reference](https://flare-docs.codetotech.com/reference/cli/).
46
-
47
- Requires Node.js 22 or later.
1
+ # @flaredev/cli
2
+
3
+ The `flare` command for [Flare](https://flare-docs.codetotech.com), a
4
+ batteries-included fullstack framework on Cloudflare Workers (vinext, D1,
5
+ Drizzle, Better Auth, R2). It scaffolds apps, generates resources with an admin
6
+ dashboard and REST API, runs migrations and deploys.
7
+
8
+ ## Install
9
+
10
+ ```sh
11
+ npm install -g @flaredev/cli # or: pnpm add -g @flaredev/cli
12
+ ```
13
+
14
+ Or with the install scripts (they check for Node.js 22+ and use npm or pnpm):
15
+
16
+ ```sh
17
+ # macOS / Linux
18
+ curl -fsSL https://flare-docs.codetotech.com/install.sh | bash
19
+ ```
20
+
21
+ ```powershell
22
+ # Windows PowerShell
23
+ irm https://flare-docs.codetotech.com/install.ps1 | iex
24
+ ```
25
+
26
+ Or skip the install entirely:
27
+
28
+ ```sh
29
+ npm create flare-framework@latest my-app
30
+ npx @flaredev/cli create my-app
31
+ ```
32
+
33
+ ## Use
34
+
35
+ ```sh
36
+ flare create shop
37
+ cd shop
38
+ flare gen resource Product --fields 'name:string, price:int, sku:string!'
39
+ flare migrate
40
+ flare dev
41
+ flare deploy
42
+ ```
43
+
44
+ Run `flare --help` for every command, or read the
45
+ [CLI reference](https://flare-docs.codetotech.com/reference/cli/).
46
+
47
+ Requires Node.js 22 or later.
package/dist/index.js CHANGED
@@ -157,6 +157,15 @@ function childEnv(env = process.env) {
157
157
  }
158
158
  return next;
159
159
  }
160
+ function runQuiet(command, args, cwd) {
161
+ const env = childEnv();
162
+ const result = process.platform === "win32" ? spawnSync([command, ...args].join(" "), { cwd, env, shell: true, encoding: "utf8" }) : spawnSync(command, args, { cwd, env, encoding: "utf8" });
163
+ return { code: result.status ?? 1, output: `${result.stdout ?? ""}${result.stderr ?? ""}` };
164
+ }
165
+ function installArgs(pm) {
166
+ if (pm === "npm") return ["install", "--no-audit", "--no-fund", "--loglevel=error"];
167
+ return ["install"];
168
+ }
160
169
 
161
170
  // src/commands/create.ts
162
171
  function toAppName(dir) {
@@ -221,24 +230,42 @@ ${devVarsEntries(authProviders)}`
221
230
  if (packageManager === "pnpm" && !inWorkspace) {
222
231
  writeFileSync2(join2(dir, "pnpm-workspace.yaml"), "allowBuilds:\n esbuild: true\n workerd: true\n sharp: false\n");
223
232
  }
233
+ const log = options2.log ?? ((message) => console.log(message));
224
234
  if (options2.install !== false) {
225
- const code = run(packageManager, ["install"], dir);
235
+ log(`${pc.green("\u2714")} Wrote the app to ${relative(process.cwd(), dir) || "."}`);
236
+ log(`${pc.cyan("\u25CF")} Installing dependencies with ${packageManager}. The first install downloads the Workers runtime and toolchain, so it can take a few minutes.
237
+ `);
238
+ const started = Date.now();
239
+ const code = run(packageManager, installArgs(packageManager), dir);
226
240
  if (code !== 0) throw new Error(`${packageManager} install failed (exit code ${code}).`);
227
- const typegen = run(packageManager, ["run", "cf-typegen"], dir);
228
- if (typegen !== 0) throw new Error(`wrangler types failed (exit code ${typegen}).`);
241
+ log(`${pc.green("\u2714")} Installed dependencies ${pc.dim(`(${formatDuration(Date.now() - started)})`)}`);
242
+ const typegen = runQuiet(packageManager, ["run", "cf-typegen"], dir);
243
+ if (typegen.code !== 0) {
244
+ process.stderr.write(typegen.output);
245
+ throw new Error(`wrangler types failed (exit code ${typegen.code}).`);
246
+ }
247
+ log(`${pc.green("\u2714")} Generated types for the Cloudflare bindings`);
229
248
  }
230
249
  return { dir, name, packageManager, inWorkspace };
231
250
  }
251
+ function formatDuration(ms) {
252
+ const seconds = Math.round(ms / 1e3);
253
+ return seconds < 60 ? `${seconds}s` : `${Math.floor(seconds / 60)}m ${String(seconds % 60).padStart(2, "0")}s`;
254
+ }
232
255
  function printNextSteps(result, installed) {
233
256
  const rel = relative(process.cwd(), result.dir) || ".";
234
257
  const pm = result.packageManager;
258
+ const step = (command, note) => ` ${command.padEnd(30)}${pc.dim(note)}`;
235
259
  console.log(`
236
- ${pc.green("\u2714")} Created ${pc.bold(result.name)} in ${rel}
260
+ ${pc.green("\u2714")} Created ${pc.bold(result.name)}
237
261
  `);
238
262
  console.log("Next steps:");
239
263
  console.log(` cd ${rel}`);
240
264
  if (!installed) console.log(` ${pm} install`);
241
- console.log(` ${pm} run dev`);
265
+ console.log(step(`${pm} run dev`, "start it at http://localhost:3000"));
266
+ console.log(step("npx flare gen resource ...", "add your first resource"));
267
+ console.log(`
268
+ Quickstart: ${pc.cyan("https://flare-docs.codetotech.com/start/quickstart/")}`);
242
269
  }
243
270
 
244
271
  // src/commands/gen-billing.ts
@@ -3760,7 +3787,7 @@ function createCli() {
3760
3787
  const result = createApp(dir, { pm: options2.pm, install, authProviders: options2.authProviders });
3761
3788
  printNextSteps(result, install);
3762
3789
  });
3763
- cli.command("gen <generator> [name]", "Generate code. Generators: resource, migration, policy, billing, security").option("--fields <fields>", 'resource: fields, e.g. "name:string, email:string!, status:enum(lead,customer)"').option("--force", "resource/policy/billing/security: overwrite hand-edited generated blocks").option("--from-schema", "migration: diff the current tables instead of a blank migration").option("--roles <roles>", "policy: roles allowed to read, create and update, e.g. admin,staff").option("--delete-roles <roles>", "policy: roles allowed to delete (default: the first --roles entry)").option("--provider <provider>", "billing: payment provider (default: stripe)").option("--mode <mode>", "billing: subscriptions (the default; includes one-time checkout)").option("--skip-install", "billing: write files without installing the stripe dependency").option("--skip-migration", "billing/security: skip generating the schema migration").example('flare gen resource Contact --fields "name:string, email:string!, company:belongsTo(Company)?"').example("flare gen migration backfill_contact_status").example("flare gen migration add_phone_to_contacts --from-schema").example("flare gen policy Invoice --roles admin,staff --delete-roles admin").example("flare gen billing --provider stripe --mode subscriptions").example("flare gen security").action(
3790
+ cli.command("gen <generator> [name]", "Generate code. Generators: resource, migration, policy, billing, security").option("--fields <fields>", "resource: fields, e.g. 'name:string, email:string!, status:enum(lead,customer)' (single quotes: bash treats ! in double quotes as history)").option("--force", "resource/policy/billing/security: overwrite hand-edited generated blocks").option("--from-schema", "migration: diff the current tables instead of a blank migration").option("--roles <roles>", "policy: roles allowed to read, create and update, e.g. admin,staff").option("--delete-roles <roles>", "policy: roles allowed to delete (default: the first --roles entry)").option("--provider <provider>", "billing: payment provider (default: stripe)").option("--mode <mode>", "billing: subscriptions (the default; includes one-time checkout)").option("--skip-install", "billing: write files without installing the stripe dependency").option("--skip-migration", "billing/security: skip generating the schema migration").example("flare gen resource Contact --fields 'name:string, email:string!, company:belongsTo(Company)?'").example("flare gen migration backfill_contact_status").example("flare gen migration add_phone_to_contacts --from-schema").example("flare gen policy Invoice --roles admin,staff --delete-roles admin").example("flare gen billing --provider stripe --mode subscriptions").example("flare gen security").action(
3764
3791
  async (generator, name, options2) => {
3765
3792
  if (generator === "billing")
3766
3793
  return genBilling({ provider: options2.provider, mode: options2.mode, force: options2.force, skipInstall: options2.skipInstall, skipMigration: options2.skipMigration });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flaredev/cli",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "The flare command-line tool: create, generate, migrate, and deploy Flare apps",
5
5
  "license": "MIT",
6
6
  "author": "Muke Johnbaptist",
@@ -40,7 +40,7 @@
40
40
  "jiti": "^2.7.0",
41
41
  "jsonc-parser": "^3.3.1",
42
42
  "picocolors": "^1.1.1",
43
- "@flaredev/core": "0.1.1"
43
+ "@flaredev/core": "0.1.2"
44
44
  },
45
45
  "engines": {
46
46
  "node": ">=22"