@asterflow/cli 2.0.2 → 2.1.0

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.
package/dist/mjs/index.js CHANGED
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  // packages/cli/src/index.ts
3
- import Ze from "yargs";
4
- import { hideBin as et } from "yargs/helpers";
3
+ import et from "yargs";
4
+ import { hideBin as tt } from "yargs/helpers";
5
5
  // packages/cli/src/commands/add.ts
6
6
  import { exec as ke } from "child_process";
7
- import { existsSync as xe } from "fs";
8
- import { readFile as ve, writeFile as je } from "fs/promises";
9
- import { join as Pe, resolve as $e } from "path";
10
- import { promisify as Ie } from "util";
7
+ import { existsSync as ve } from "fs";
8
+ import { readFile as je, writeFile as $e } from "fs/promises";
9
+ import { join as Pe, resolve as Ie } from "path";
10
+ import { promisify as Ae } from "util";
11
11
  // packages/cli/package.json
12
- var D = {
12
+ var F = {
13
13
  name: "@asterflow/cli",
14
- version: "2.0.2",
14
+ version: "2.1.0",
15
15
  description: "CLI for scaffolding AsterFlow projects, adding plugins, and generating the static fs-routing manifest.",
16
16
  keywords: [
17
17
  "asterflow",
@@ -67,11 +67,11 @@ var D = {
67
67
  }
68
68
  };
69
69
  // packages/cli/src/helpers/npmVersion.ts
70
- var ge = "https://registry.npmjs.org", fe = 5e3, [B, W] = D.version.split(".").map(Number);
71
- async function ye(e) {
72
- let t = new AbortController(), r = setTimeout(() => t.abort(), fe);
70
+ var Y = "https://registry.npmjs.org", J = 5e3, [B, W] = F.version.split(".").map(Number);
71
+ async function he(e) {
72
+ let t = new AbortController(), n = setTimeout(() => t.abort(), J);
73
73
  try {
74
- let s = await fetch(`${ge}/${encodeURIComponent(e)}`, {
74
+ let s = await fetch(`${Y}/${encodeURIComponent(e)}`, {
75
75
  signal: t.signal,
76
76
  headers: { Accept: "application/vnd.npm.install-v1+json" }
77
77
  });
@@ -81,21 +81,37 @@ async function ye(e) {
81
81
  } catch {
82
82
  return [];
83
83
  } finally {
84
- clearTimeout(r);
84
+ clearTimeout(n);
85
85
  }
86
86
  }
87
- async function j(e) {
88
- let t = await ye(e), r = -1;
87
+ async function $(e) {
88
+ let t = await he(e), n = -1;
89
89
  for (let l of t) {
90
- let f = /^(\d+)\.(\d+)\.(\d+)$/.exec(l);
91
- if (!f) continue;
92
- let [, d, c, p] = f;
93
- Number(d) !== B || Number(c) !== W || (r = Math.max(r, Number(p)));
90
+ let g = /^(\d+)\.(\d+)\.(\d+)$/.exec(l);
91
+ if (!g) continue;
92
+ let [, p, c, d] = g;
93
+ Number(p) !== B || Number(c) !== W || (n = Math.max(n, Number(d)));
94
+ }
95
+ return `^${n >= 0 ? `${B}.${W}.${n}` : F.version}`;
96
+ }
97
+ async function q(e, t) {
98
+ let n = new AbortController(), s = setTimeout(() => n.abort(), J);
99
+ try {
100
+ let l = await fetch(`${Y}/${encodeURIComponent(e)}`, {
101
+ signal: n.signal,
102
+ headers: { Accept: "application/vnd.npm.install-v1+json" }
103
+ });
104
+ if (!l.ok) return `^${t}`;
105
+ let p = (await l.json())["dist-tags"]?.latest;
106
+ return p ? `^${p}` : `^${t}`;
107
+ } catch {
108
+ return `^${t}`;
109
+ } finally {
110
+ clearTimeout(s);
94
111
  }
95
- return `^${r >= 0 ? `${B}.${W}.${r}` : D.version}`;
96
112
  }
97
113
  // packages/cli/src/registry/plugins.ts
98
- var b = {
114
+ var w = {
99
115
  fs: {
100
116
  id: "fs",
101
117
  packageName: "@asterflow/fs",
@@ -112,187 +128,191 @@ var b = {
112
128
  useSnippet: ".use(multipartPlugin, { limits: { fileSize: 10 * 1024 * 1024 } })",
113
129
  usageNote: "Build upload routes with Method.create(Method.POST).multipart({...}).handler(...) - see src/routes/upload.ts for a working example."
114
130
  }
115
- }, st = Object.keys(b);
131
+ }, ot = Object.keys(w);
116
132
  // packages/cli/src/utils/log.ts
117
- import $ from "chalk";
133
+ import A from "chalk";
118
134
  var m = {
119
- info: (e) => console.log($.cyan(e)),
120
- success: (e) => console.log($.green(e)),
121
- warn: (e) => console.log($.yellow(e)),
122
- error: (e) => console.error($.red(e)),
123
- step: (e) => console.log($.gray(` ${e}`))
135
+ info: (e) => console.log(A.cyan(e)),
136
+ success: (e) => console.log(A.green(e)),
137
+ warn: (e) => console.log(A.yellow(e)),
138
+ error: (e) => console.error(A.red(e)),
139
+ step: (e) => console.log(A.gray(` ${e}`))
124
140
  };
125
141
  // packages/cli/src/utils/packageManager.ts
126
- import { existsSync as he } from "fs";
142
+ import { existsSync as we } from "fs";
127
143
  import { join as be } from "path";
128
- var we = {
144
+ var xe = {
129
145
  "bun.lock": "bun",
130
146
  "bun.lockb": "bun",
131
147
  "pnpm-lock.yaml": "pnpm",
132
148
  "yarn.lock": "yarn",
133
149
  "package-lock.json": "npm"
134
150
  };
135
- function O(e) {
136
- for (let [t, r] of Object.entries(we))
137
- if (he(be(e, t))) return r;
151
+ function M(e) {
152
+ for (let [t, n] of Object.entries(xe))
153
+ if (we(be(e, t))) return n;
138
154
  return "bun";
139
155
  }
140
- function Y(e, t) {
141
- return e ?? O(t);
156
+ function z(e, t) {
157
+ return e ?? M(t);
142
158
  }
143
- function J(e) {
159
+ function H(e) {
144
160
  return e === "yarn" ? "yarn" : `${e} install`;
145
161
  }
146
- function q(e, t) {
147
- let r = t.join(" ");
162
+ function K(e, t) {
163
+ let n = t.join(" ");
148
164
  switch (e) {
149
165
  case "bun":
150
- return `bun add ${r}`;
166
+ return `bun add ${n}`;
151
167
  case "pnpm":
152
- return `pnpm add ${r}`;
168
+ return `pnpm add ${n}`;
153
169
  case "yarn":
154
- return `yarn add ${r}`;
170
+ return `yarn add ${n}`;
155
171
  case "npm":
156
- return `npm install ${r}`;
172
+ return `npm install ${n}`;
157
173
  }
158
174
  }
159
175
  // packages/cli/src/commands/add.ts
160
- var Ae = Ie(ke);
161
- async function z({ names: e, directory: t }) {
162
- let r = $e(t ?? "."), s = Pe(r, "package.json"), l = e.split(",").map((o) => o.trim()).filter(Boolean);
176
+ var Ce = Ae(ke);
177
+ async function Q({ names: e, directory: t }) {
178
+ let n = Ie(t ?? "."), s = Pe(n, "package.json"), l = e.split(",").map((o) => o.trim()).filter(Boolean);
163
179
  if (l.length === 0) {
164
180
  m.error("No plugin names given. Usage: asterflow add fs,multipart"), process.exitCode = 1;
165
181
  return;
166
182
  }
167
- let f = l.filter((o) => !b[o]);
168
- if (f.length > 0) {
169
- m.error(`Unknown plugin${f.length > 1 ? "s" : ""}: ${f.join(", ")}`), m.step(`Available plugins: ${Object.keys(b).join(", ")}`), process.exitCode = 1;
183
+ let g = l.filter((o) => !w[o]);
184
+ if (g.length > 0) {
185
+ m.error(`Unknown plugin${g.length > 1 ? "s" : ""}: ${g.join(", ")}`), m.step(`Available plugins: ${Object.keys(w).join(", ")}`), process.exitCode = 1;
170
186
  return;
171
187
  }
172
- if (!xe(s)) {
188
+ if (!ve(s)) {
173
189
  m.error(`No package.json found at ${s}. Run this from an AsterFlow project (or \`asterflow init\` first).`), process.exitCode = 1;
174
190
  return;
175
191
  }
176
- let d = l.map((o) => b[o]), c = await ve(s, "utf-8"), p = JSON.parse(c);
177
- p.dependencies ??= {};
178
- let w = d.filter((o) => p.dependencies[o.packageName]), y = d.filter((o) => !p.dependencies[o.packageName]), k = await Promise.all(y.map((o) => j(o.packageName)));
179
- if (y.forEach((o, u) => {
180
- p.dependencies[o.packageName] = k[u];
181
- }), p.dependencies = Object.fromEntries(Object.entries(p.dependencies).sort(([o], [u]) => o.localeCompare(u))), y.length > 0) {
182
- await je(s, `${JSON.stringify(p, null, 2)}
183
- `), m.success(`Added to package.json: ${y.map((g) => g.packageName).join(", ")}`);
184
- let o = O(r), u = q(o, y.map((g) => g.packageName));
185
- m.info(`Installing (${u})...`);
192
+ let p = l.map((o) => w[o]), c = await je(s, "utf-8"), d = JSON.parse(c);
193
+ d.dependencies ??= {};
194
+ let b = p.filter((o) => d.dependencies[o.packageName]), u = p.filter((o) => !d.dependencies[o.packageName]), k = await Promise.all(u.map((o) => $(o.packageName)));
195
+ if (u.forEach((o, y) => {
196
+ d.dependencies[o.packageName] = k[y];
197
+ }), d.dependencies = Object.fromEntries(Object.entries(d.dependencies).sort(([o], [y]) => o.localeCompare(y))), u.length > 0) {
198
+ await $e(s, `${JSON.stringify(d, null, 2)}
199
+ `), m.success(`Added to package.json: ${u.map((h) => h.packageName).join(", ")}`);
200
+ let o = M(n), y = K(o, u.map((h) => h.packageName));
201
+ m.info(`Installing (${y})...`);
186
202
  try {
187
- await Ae(u, { cwd: r }), m.success("Dependencies installed.");
188
- } catch (g) {
189
- m.error(`Install failed - run manually: ${u}`), m.step(g instanceof Error ? g.message : String(g));
203
+ await Ce(y, { cwd: n }), m.success("Dependencies installed.");
204
+ } catch (h) {
205
+ m.error(`Install failed - run manually: ${y}`), m.step(h instanceof Error ? h.message : String(h));
190
206
  }
191
207
  }
192
- w.length > 0 && m.warn(`Already present, skipped: ${w.map((o) => o.packageName).join(", ")}`), m.info("Wire it up:");
193
- for (let o of d)
208
+ b.length > 0 && m.warn(`Already present, skipped: ${b.map((o) => o.packageName).join(", ")}`), m.info("Wire it up:");
209
+ for (let o of p)
194
210
  m.step(`import { ${o.importName} } from '${o.packageName}'`), m.step(`app${o.useSnippet}`), m.step(o.usageNote);
195
211
  }
196
212
  // packages/cli/src/commands/generate.ts
197
- import { generateRouteManifest as Ee } from "@asterflow/fs";
198
- import { watch as Re } from "fs";
199
- import { join as Ne, resolve as H } from "path";
200
- var Se = "src/routes", K = "src/routes.gen.ts";
201
- async function Q({ directory: e, out: t, watch: r }) {
202
- let s = H(e ?? Se), l = H(t ?? K), f = async () => {
213
+ import { generateRouteManifest as Re } from "@asterflow/fs";
214
+ import { watch as Ee } from "fs";
215
+ import { join as Te, resolve as X } from "path";
216
+ var Ne = "src/routes", Z = "src/routes.gen.ts";
217
+ async function ee({ directory: e, out: t, watch: n }) {
218
+ let s = X(e ?? Ne), l = X(t ?? Z), g = async () => {
203
219
  try {
204
- await Ee({ routesDir: s, outFile: l }), m.success(`Generated ${Ne(t ?? K)}`);
220
+ await Re({ routesDir: s, outFile: l }), m.success(`Generated ${Te(t ?? Z)}`);
205
221
  } catch (c) {
206
- m.error(c instanceof Error ? c.message : String(c)), r || (process.exitCode = 1);
222
+ m.error(c instanceof Error ? c.message : String(c)), n || (process.exitCode = 1);
207
223
  }
208
224
  };
209
- if (await f(), !r) return;
225
+ if (await g(), !n) return;
210
226
  m.info(`Watching ${s} for changes...`);
211
- let d;
212
- Re(s, { recursive: !0 }, () => {
213
- clearTimeout(d), d = setTimeout(f, 100);
227
+ let p;
228
+ Ee(s, { recursive: !0 }, () => {
229
+ clearTimeout(p), p = setTimeout(g, 100);
214
230
  });
215
231
  }
216
232
  // packages/cli/src/commands/init.ts
217
233
  import * as i from "@clack/prompts";
218
- import le from "ci-info";
219
- import { exec as Je } from "child_process";
220
- import { appendFile as qe, mkdir as N, writeFile as L } from "fs/promises";
221
- import { basename as G, dirname as pe, join as v, resolve as ze } from "path";
222
- import { promisify as He } from "util";
234
+ import de from "ci-info";
235
+ import { exec as qe } from "child_process";
236
+ import { appendFile as ze, mkdir as S, writeFile as G } from "fs/promises";
237
+ import { basename as V, dirname as me, join as v, resolve as He } from "path";
238
+ import { promisify as Ke } from "util";
223
239
  // packages/cli/src/generators/appEntry.ts
224
- function X({ adapter: e, plugins: t, stub: r }) {
240
+ function te({ adapter: e, plugins: t, stub: n }) {
225
241
  let s = t.some((c) => c.id === "fs"), l = [
226
242
  "import { AsterFlow } from 'asterflow'",
227
243
  "import { adapters } from '@asterflow/adapter'",
228
244
  ...e.imports,
229
245
  ...t.map((c) => `import { ${c.importName} } from '${c.packageName}'`),
230
246
  ...s ? ["import routes from './routes.gen'"] : []
231
- ], f = [
247
+ ], g = [
232
248
  ...t.map((c) => c.useSnippet.replace(/^\./, "")),
233
- ...!s && r ? [`method('get', {
249
+ ...!s && n ? [`method('get', {
234
250
  path: '/',
235
251
  handler({ response }) {
236
252
  return response.success({ message: 'Hello from AsterFlow!' })
237
253
  }
238
254
  })`] : [],
239
255
  `listen${e.listenCall}`
240
- ], d = e.preamble ? `${e.preamble}
256
+ ], p = e.preamble ? `${e.preamble}
241
257
  ` : "";
242
258
  return `${l.join(`
243
259
  `)}
244
- ${d}export default new AsterFlow({ driver: ${e.driverExpression} })
245
- .${f.join(`
260
+ ${p}export default new AsterFlow({ driver: ${e.driverExpression} })
261
+ .${g.join(`
246
262
  .`)}
247
263
  `;
248
264
  }
249
265
  // packages/cli/src/generators/packageJson.ts
250
- async function Z({ name: e, adapter: t, plugins: r }) {
251
- let s = r.some((u) => u.id === "fs"), [l, f, d, c] = await Promise.all([
252
- j("asterflow"),
253
- j("@asterflow/adapter"),
254
- s ? j("@asterflow/cli") : Promise.resolve(null),
255
- Promise.all(r.map((u) => j(u.packageName)))
256
- ]), p = {
266
+ async function ne({ name: e, adapter: t, plugins: n }) {
267
+ let s = n.some((x) => x.id === "fs"), [l, g, p, c, d, b] = await Promise.all([
268
+ $("asterflow"),
269
+ $("@asterflow/adapter"),
270
+ s ? $("@asterflow/cli") : Promise.resolve(null),
271
+ s ? $("@asterflow/router") : Promise.resolve(null),
272
+ q("tsdown", "0.23.0"),
273
+ Promise.all(n.map((x) => $(x.packageName)))
274
+ ]), u = {
257
275
  asterflow: l,
258
- "@asterflow/adapter": f,
276
+ "@asterflow/adapter": g,
259
277
  zod: "^3.25.67"
260
278
  };
261
- t.dependency && (p[t.dependency] = "latest"), r.forEach((u, g) => {
262
- p[u.packageName] = c[g];
279
+ t.dependency && (u[t.dependency] = "latest"), s && c && (u["@asterflow/router"] = c), n.forEach((x, P) => {
280
+ u[x.packageName] = b[P];
263
281
  });
264
- let w = Object.fromEntries(Object.entries(p).sort(([u], [g]) => u.localeCompare(g))), y = s ? {
265
- predev: "asterflow generate",
266
- dev: "bun run src/index.ts",
267
- prebuild: "asterflow generate"
268
- } : { dev: "bun run src/index.ts" }, k = {
282
+ let k = Object.fromEntries(Object.entries(u).sort(([x], [P]) => x.localeCompare(P))), o = {
283
+ ...s ? { predev: "asterflow generate", dev: "bun run src/index.ts", prebuild: "asterflow generate" } : { dev: "bun run src/index.ts" },
284
+ build: "tsdown",
285
+ start: `${t.runCommand} dist/index.mjs`
286
+ }, y = {
269
287
  typescript: "^5.8.3",
270
- "@types/bun": "latest"
288
+ "@types/bun": "latest",
289
+ "@types/node": "latest",
290
+ tsdown: d
271
291
  };
272
- return s && d && (k["@asterflow/cli"] = d), `${JSON.stringify({
292
+ return s && p && (y["@asterflow/cli"] = p), `${JSON.stringify({
273
293
  name: e,
274
294
  version: "0.1.0",
275
295
  type: "module",
276
296
  private: !0,
277
- scripts: y,
278
- dependencies: w,
279
- devDependencies: k
297
+ scripts: o,
298
+ dependencies: k,
299
+ devDependencies: y
280
300
  }, null, 2)}
281
301
  `;
282
302
  }
283
303
  // packages/cli/src/helpers/copyTemplate.ts
284
- import { readFile as Te, writeFile as Ce } from "fs/promises";
285
- import { join as ee } from "path";
286
- var De = ee(__dirname, "..", "..", "templates");
287
- async function F(e) {
288
- return Te(ee(De, e), "utf-8");
304
+ import { readFile as Se, writeFile as De } from "fs/promises";
305
+ import { join as re } from "path";
306
+ var Oe = re(__dirname, "..", "..", "templates");
307
+ async function _(e) {
308
+ return Se(re(Oe, e), "utf-8");
289
309
  }
290
- async function M(e, t) {
291
- let r = await F(e);
292
- await Ce(t, r);
310
+ async function T(e, t) {
311
+ let n = await _(e);
312
+ await De(t, n);
293
313
  }
294
314
  // packages/cli/src/registry/templates.ts
295
- var te = {
315
+ var ie = {
296
316
  hello: {
297
317
  id: "hello",
298
318
  path: "/",
@@ -306,60 +326,60 @@ var te = {
306
326
  plugin: "multipart",
307
327
  summary: "File upload handled by @asterflow/multipart."
308
328
  }
309
- }, I = Object.keys(te);
310
- function R(e) {
329
+ }, C = Object.keys(ie);
330
+ function N(e) {
311
331
  let t = new Set(e);
312
- return I.map((r) => te[r]).filter((r) => !r.plugin || t.has(r.plugin));
332
+ return C.map((n) => ie[n]).filter((n) => !n.plugin || t.has(n.plugin));
313
333
  }
314
- function re(e) {
334
+ function se(e) {
315
335
  let t = e.path.replace(/^\/+|\/+$/g, "");
316
336
  return t.length === 0 ? "index.ts" : `${t}/index.ts`;
317
337
  }
318
338
  // packages/cli/src/generators/routes.ts
319
- async function ne({ pluginIds: e, templateIds: t }) {
339
+ async function oe({ pluginIds: e, templateIds: t }) {
320
340
  if (!e.includes("fs")) return [];
321
- let r = R(e).filter((s) => t.includes(s.id));
322
- return Promise.all(r.map(async (s) => ({
323
- fileName: re(s),
324
- content: await F(s.source)
341
+ let n = N(e).filter((s) => t.includes(s.id));
342
+ return Promise.all(n.map(async (s) => ({
343
+ fileName: se(s),
344
+ content: await _(s.source)
325
345
  })));
326
346
  }
327
347
  // packages/cli/src/helpers/git.ts
328
- import { execSync as P } from "child_process";
329
- import { rmSync as Oe } from "fs";
330
- import { join as Fe } from "path";
331
- function Me(e) {
348
+ import { execSync as I } from "child_process";
349
+ import { rmSync as Fe } from "fs";
350
+ import { join as Me } from "path";
351
+ function _e(e) {
332
352
  try {
333
- return P("git rev-parse --is-inside-work-tree", { cwd: e, stdio: "ignore" }), !0;
353
+ return I("git rev-parse --is-inside-work-tree", { cwd: e, stdio: "ignore" }), !0;
334
354
  } catch {
335
355
  return !1;
336
356
  }
337
357
  }
338
- function _e(e) {
358
+ function Le(e) {
339
359
  try {
340
- return P("git config init.defaultBranch", { cwd: e, stdio: "ignore" }), !0;
360
+ return I("git config init.defaultBranch", { cwd: e, stdio: "ignore" }), !0;
341
361
  } catch {
342
362
  return !1;
343
363
  }
344
364
  }
345
- function ie(e) {
365
+ function ae(e) {
346
366
  let t = !1;
347
367
  try {
348
- return P("git --version", { stdio: "ignore" }), Me(e) ? !1 : (P("git init", { cwd: e, stdio: "ignore" }), t = !0, _e(e) || P("git checkout -b main", { cwd: e, stdio: "ignore" }), P("git add -A", { cwd: e, stdio: "ignore" }), P('git commit -m "Initial commit from create-asterflow-app"', { cwd: e, stdio: "ignore" }), !0);
368
+ return I("git --version", { stdio: "ignore" }), _e(e) ? !1 : (I("git init", { cwd: e, stdio: "ignore" }), t = !0, Le(e) || I("git checkout -b main", { cwd: e, stdio: "ignore" }), I("git add -A", { cwd: e, stdio: "ignore" }), I('git commit -m "Initial commit from create-asterflow-app"', { cwd: e, stdio: "ignore" }), !0);
349
369
  } catch {
350
370
  if (t)
351
371
  try {
352
- Oe(Fe(e, ".git"), { recursive: !0, force: !0 });
372
+ Fe(Me(e, ".git"), { recursive: !0, force: !0 });
353
373
  } catch {
354
374
  }
355
375
  return !1;
356
376
  }
357
377
  }
358
378
  // packages/cli/src/helpers/isFolderEmpty.ts
359
- import { lstatSync as Le, readdirSync as Ge } from "fs";
379
+ import { lstatSync as Ge, readdirSync as Ve } from "fs";
360
380
  import { join as Ue } from "path";
361
- import se from "chalk";
362
- var Ve = new Set([
381
+ import le from "chalk";
382
+ var Be = new Set([
363
383
  ".DS_Store",
364
384
  ".git",
365
385
  ".gitattributes",
@@ -374,37 +394,37 @@ var Ve = new Set([
374
394
  "LICENSE",
375
395
  "Thumbs.db"
376
396
  ]);
377
- function oe(e, t) {
378
- let r = Ge(e).filter((s) => !Ve.has(s) && !s.endsWith(".iml"));
379
- if (r.length === 0) return !0;
380
- console.log(`The directory ${se.green(t)} contains files that could conflict:`), console.log();
381
- for (let s of r) {
382
- let l = Le(Ue(e, s)).isDirectory();
383
- console.log(` ${se.cyan(s)}${l ? "/" : ""}`);
397
+ function ce(e, t) {
398
+ let n = Ve(e).filter((s) => !Be.has(s) && !s.endsWith(".iml"));
399
+ if (n.length === 0) return !0;
400
+ console.log(`The directory ${le.green(t)} contains files that could conflict:`), console.log();
401
+ for (let s of n) {
402
+ let l = Ge(Ue(e, s)).isDirectory();
403
+ console.log(` ${le.cyan(s)}${l ? "/" : ""}`);
384
404
  }
385
405
  return console.log(), console.log("Either try using a new directory name, or remove the files listed above."), console.log(), !1;
386
406
  }
387
407
  // packages/cli/src/helpers/isWriteable.ts
388
- import { constants as Be } from "fs";
389
- import { access as We } from "fs/promises";
390
- async function ae(e) {
408
+ import { constants as We } from "fs";
409
+ import { access as Ye } from "fs/promises";
410
+ async function pe(e) {
391
411
  try {
392
- return await We(e, Be.W_OK), !0;
412
+ return await Ye(e, We.W_OK), !0;
393
413
  } catch {
394
414
  return !1;
395
415
  }
396
416
  }
397
417
  // packages/cli/src/helpers/validateProjectName.ts
398
- import Ye from "validate-npm-package-name";
399
- function _(e) {
400
- let t = Ye(e);
418
+ import Je from "validate-npm-package-name";
419
+ function L(e) {
420
+ let t = Je(e);
401
421
  return t.validForNewPackages ? { valid: !0 } : {
402
422
  valid: !1,
403
423
  problems: [...t.errors ?? [], ...t.warnings ?? []]
404
424
  };
405
425
  }
406
426
  // packages/cli/src/registry/adapters.ts
407
- var A = {
427
+ var R = {
408
428
  bun: {
409
429
  id: "bun",
410
430
  label: "Bun (native Bun.serve)",
@@ -412,6 +432,7 @@ var A = {
412
432
  imports: [],
413
433
  driverExpression: "adapters.bun",
414
434
  preamble: null,
435
+ runCommand: "bun",
415
436
  listenCall: `({ port: 3333 }, (err) => {
416
437
  if (err) {
417
438
  console.error(err)
@@ -427,6 +448,7 @@ var A = {
427
448
  imports: [],
428
449
  driverExpression: "adapters.node",
429
450
  preamble: null,
451
+ runCommand: "node",
430
452
  listenCall: `({ port: 3333 }, (err) => {
431
453
  if (err) {
432
454
  console.error(err)
@@ -442,6 +464,7 @@ var A = {
442
464
  imports: ["import express from 'express'"],
443
465
  driverExpression: "adapters.express",
444
466
  preamble: "const server = express()",
467
+ runCommand: "node",
445
468
  listenCall: `(server, 3333, () => {
446
469
  console.log('Server listening on http://localhost:3333')
447
470
  })`
@@ -453,6 +476,7 @@ var A = {
453
476
  imports: ["import fastify from 'fastify'"],
454
477
  driverExpression: "adapters.fastify",
455
478
  preamble: "const server = fastify()",
479
+ runCommand: "node",
456
480
  listenCall: `(server, { port: 3333 }, (err) => {
457
481
  if (err) {
458
482
  console.error(err)
@@ -461,191 +485,191 @@ var A = {
461
485
  console.log('Server listening on http://localhost:3333')
462
486
  })`
463
487
  }
464
- }, E = Object.keys(A);
488
+ }, E = Object.keys(R);
465
489
  // packages/cli/src/commands/init.ts
466
- var Ke = He(Je), x = {
490
+ var Qe = Ke(qe), j = {
467
491
  adapter: "bun",
468
492
  plugins: ["fs", "multipart"],
469
493
  install: !0,
470
494
  git: !0
471
495
  };
472
- async function ce(e) {
496
+ async function ue(e) {
473
497
  i.intro("Create a new AsterFlow project");
474
- let t = ze(e.directory ?? "."), r = G(t) === "." ? "my-asterflow-app" : G(t);
475
- if (!await ae(pe(t))) {
498
+ let t = He(e.directory ?? "."), n = V(t) === "." ? "my-asterflow-app" : V(t);
499
+ if (!await pe(me(t))) {
476
500
  i.cancel(`The path ${t} is not writable. Check folder permissions and try again.`), process.exitCode = 1;
477
501
  return;
478
502
  }
479
- if (await N(t, { recursive: !0 }), !oe(t, G(t))) {
503
+ if (await S(t, { recursive: !0 }), !ce(t, V(t))) {
480
504
  process.exitCode = 1;
481
505
  return;
482
506
  }
483
- let s = process.argv.some((n) => n.startsWith("--")), l = le.isCI || !!e.yes || s, f = s && !e.yes && !le.isCI;
507
+ let s = process.argv.some((r) => r.startsWith("--")), l = de.isCI || !!e.yes || s, g = s && !e.yes && !de.isCI;
484
508
  if (e.name) {
485
- let n = _(e.name);
486
- if (!n.valid) {
509
+ let r = L(e.name);
510
+ if (!r.valid) {
487
511
  i.cancel(`Invalid project name "${e.name}":
488
- ${n.problems.map((a) => ` - ${a}`).join(`
512
+ ${r.problems.map((a) => ` - ${a}`).join(`
489
513
  `)}`), process.exitCode = 1;
490
514
  return;
491
515
  }
492
516
  }
493
- let d = e.name;
494
- if (d === void 0)
517
+ let p = e.name;
518
+ if (p === void 0)
495
519
  if (l)
496
- d = r;
520
+ p = n;
497
521
  else {
498
- let n = await i.text({
522
+ let r = await i.text({
499
523
  message: "Project name",
500
- placeholder: r,
501
- defaultValue: r,
524
+ placeholder: n,
525
+ defaultValue: n,
502
526
  validate: (a) => {
503
- let h = _(a || r);
504
- return h.valid ? void 0 : `Invalid project name: ${h.problems[0]}`;
527
+ let f = L(a || n);
528
+ return f.valid ? void 0 : `Invalid project name: ${f.problems[0]}`;
505
529
  }
506
530
  });
507
- if (i.isCancel(n)) return i.cancel("Cancelled.");
508
- d = n;
531
+ if (i.isCancel(r)) return i.cancel("Cancelled.");
532
+ p = r;
509
533
  }
510
- if (e.adapter && !A[e.adapter]) {
534
+ if (e.adapter && !R[e.adapter]) {
511
535
  i.cancel(`Unknown adapter "${e.adapter}". Available: ${E.join(", ")}`), process.exitCode = 1;
512
536
  return;
513
537
  }
514
538
  let c = e.adapter;
515
539
  if (!c)
516
540
  if (l)
517
- c = x.adapter;
541
+ c = j.adapter;
518
542
  else {
519
- let n = await i.select({
543
+ let r = await i.select({
520
544
  message: "Which adapter do you want to use?",
521
- options: Object.values(A).map((a) => ({ value: a.id, label: a.label })),
522
- initialValue: x.adapter
545
+ options: Object.values(R).map((a) => ({ value: a.id, label: a.label })),
546
+ initialValue: j.adapter
523
547
  });
524
- if (i.isCancel(n)) return i.cancel("Cancelled.");
525
- c = n;
548
+ if (i.isCancel(r)) return i.cancel("Cancelled.");
549
+ c = r;
526
550
  }
527
- let p;
551
+ let d;
528
552
  if (e.plugins !== void 0) {
529
- p = e.plugins.split(",").map((a) => a.trim()).filter(Boolean);
530
- let n = p.filter((a) => !b[a]);
531
- if (n.length > 0) {
532
- i.cancel(`Unknown plugin${n.length > 1 ? "s" : ""}: ${n.join(", ")}. Available: ${Object.keys(b).join(", ")}`), process.exitCode = 1;
553
+ d = e.plugins.split(",").map((a) => a.trim()).filter(Boolean);
554
+ let r = d.filter((a) => !w[a]);
555
+ if (r.length > 0) {
556
+ i.cancel(`Unknown plugin${r.length > 1 ? "s" : ""}: ${r.join(", ")}. Available: ${Object.keys(w).join(", ")}`), process.exitCode = 1;
533
557
  return;
534
558
  }
535
559
  } else if (l)
536
- p = x.plugins;
560
+ d = j.plugins;
537
561
  else {
538
- let n = await i.multiselect({
562
+ let r = await i.multiselect({
539
563
  message: "Which plugins do you want to install? (space to select, enter to confirm)",
540
- options: Object.values(b).map((a) => ({ value: a.id, label: a.packageName, hint: a.description })),
541
- initialValues: x.plugins,
564
+ options: Object.values(w).map((a) => ({ value: a.id, label: a.packageName, hint: a.description })),
565
+ initialValues: j.plugins,
542
566
  required: !1
543
567
  });
544
- if (i.isCancel(n)) return i.cancel("Cancelled.");
545
- p = n;
568
+ if (i.isCancel(r)) return i.cancel("Cancelled.");
569
+ d = r;
546
570
  }
547
- p.length === 0 && (p = x.plugins);
548
- let w = R(p), y;
571
+ d.length === 0 && (d = j.plugins);
572
+ let b = N(d), u;
549
573
  if (e.routes !== void 0) {
550
- let n = e.routes.split(",").map((h) => h.trim()).filter(Boolean);
551
- y = n.includes("none") ? [] : n;
552
- let a = y.filter((h) => !w.some((me) => me.id === h));
574
+ let r = e.routes.split(",").map((f) => f.trim()).filter(Boolean);
575
+ u = r.includes("none") ? [] : r;
576
+ let a = u.filter((f) => !b.some((fe) => fe.id === f));
553
577
  if (a.length > 0) {
554
- i.cancel(`Unknown route template${a.length > 1 ? "s" : ""}: ${a.join(", ")}. Available: ${w.map((h) => h.id).join(", ")}`), process.exitCode = 1;
578
+ i.cancel(`Unknown route template${a.length > 1 ? "s" : ""}: ${a.join(", ")}. Available: ${b.map((f) => f.id).join(", ")}`), process.exitCode = 1;
555
579
  return;
556
580
  }
557
581
  } else if (l)
558
- y = w.map((n) => n.id);
582
+ u = b.map((r) => r.id);
559
583
  else {
560
- let n = await i.multiselect({
584
+ let r = await i.multiselect({
561
585
  message: "Which example routes do you want to scaffold? (space to select, enter to confirm)",
562
- options: w.map((a) => ({ value: a.id, label: a.path, hint: a.summary })),
563
- initialValues: w.map((a) => a.id),
586
+ options: b.map((a) => ({ value: a.id, label: a.path, hint: a.summary })),
587
+ initialValues: b.map((a) => a.id),
564
588
  required: !1
565
589
  });
566
- if (i.isCancel(n)) return i.cancel("Cancelled.");
567
- y = n;
590
+ if (i.isCancel(r)) return i.cancel("Cancelled.");
591
+ u = r;
568
592
  }
569
593
  let k = e.install;
570
594
  if (k === void 0)
571
595
  if (l)
572
- k = x.install;
596
+ k = j.install;
573
597
  else {
574
- let n = await i.confirm({ message: "Install dependencies now?", initialValue: x.install });
575
- if (i.isCancel(n)) return i.cancel("Cancelled.");
576
- k = n;
598
+ let r = await i.confirm({ message: "Install dependencies now?", initialValue: j.install });
599
+ if (i.isCancel(r)) return i.cancel("Cancelled.");
600
+ k = r;
577
601
  }
578
602
  let o = e.git;
579
603
  if (o === void 0)
580
604
  if (l)
581
- o = x.git;
605
+ o = j.git;
582
606
  else {
583
- let n = await i.confirm({ message: "Initialize a git repository?", initialValue: x.git });
584
- if (i.isCancel(n)) return i.cancel("Cancelled.");
585
- o = n;
607
+ let r = await i.confirm({ message: "Initialize a git repository?", initialValue: j.git });
608
+ if (i.isCancel(r)) return i.cancel("Cancelled.");
609
+ o = r;
586
610
  }
587
- f && Qe({
611
+ g && Xe({
588
612
  adapter: e.adapter === void 0,
589
613
  plugins: e.plugins === void 0,
590
614
  routes: e.routes === void 0,
591
615
  install: e.install === void 0,
592
616
  git: e.git === void 0
593
- }, { adapterId: c, pluginIds: p, templateIds: y, install: k, git: o });
594
- let u = A[c], g = p.map((n) => b[n]), U = i.spinner();
595
- U.start("Scaffolding project");
596
- let T = v(t, "src");
597
- await N(T, { recursive: !0 }), await L(v(t, "package.json"), await Z({ name: d, adapter: u, plugins: g })), await M("tsconfig.json", v(t, "tsconfig.json")), await L(v(T, "index.ts"), X({ adapter: u, plugins: g, stub: y.length > 0 })), await M("gitignore", v(t, ".gitignore")), g.some((n) => n.id === "fs") && await qe(v(t, ".gitignore"), `src/routes.gen.ts
617
+ }, { adapterId: c, pluginIds: d, templateIds: u, install: k, git: o });
618
+ let y = R[c], h = d.map((r) => w[r]), x = i.spinner();
619
+ x.start("Scaffolding project");
620
+ let P = v(t, "src");
621
+ await S(P, { recursive: !0 }), await G(v(t, "package.json"), await ne({ name: p, adapter: y, plugins: h })), await T("tsconfig.json", v(t, "tsconfig.json")), await T("tsdown.config.ts", v(t, "tsdown.config.ts")), await G(v(P, "index.ts"), te({ adapter: y, plugins: h, stub: u.length > 0 })), await T("gitignore", v(t, ".gitignore")), h.some((r) => r.id === "fs") && await ze(v(t, ".gitignore"), `src/routes.gen.ts
598
622
  `);
599
- let V = await ne({ pluginIds: p, templateIds: y });
600
- if (V.length > 0) {
601
- let n = v(T, "routes");
602
- await N(n, { recursive: !0 });
603
- for (let a of V) {
604
- let h = v(n, a.fileName);
605
- await N(pe(h), { recursive: !0 }), await L(h, a.content);
623
+ let U = await oe({ pluginIds: d, templateIds: u });
624
+ if (U.length > 0) {
625
+ let r = v(P, "routes");
626
+ await S(r, { recursive: !0 });
627
+ for (let a of U) {
628
+ let f = v(r, a.fileName);
629
+ await S(me(f), { recursive: !0 }), await G(f, a.content);
606
630
  }
607
631
  }
608
- U.stop("Project scaffolded");
609
- let C = Y(e.packageManager, t);
632
+ x.stop("Project scaffolded");
633
+ let O = z(e.packageManager, t);
610
634
  if (k) {
611
- let n = J(C), a = i.spinner();
612
- a.start(`Installing dependencies (${n})`);
635
+ let r = H(O), a = i.spinner();
636
+ a.start(`Installing dependencies (${r})`);
613
637
  try {
614
- await Ke(n, { cwd: t }), a.stop("Dependencies installed");
615
- } catch (h) {
616
- a.stop("Failed to install dependencies"), i.log.error(h instanceof Error ? h.message : String(h));
638
+ await Qe(r, { cwd: t }), a.stop("Dependencies installed");
639
+ } catch (f) {
640
+ a.stop("Failed to install dependencies"), i.log.error(f instanceof Error ? f.message : String(f));
617
641
  }
618
642
  }
619
- o && ie(t) && i.log.success("Initialized a git repository.");
620
- for (let n of g)
621
- i.log.info(`${n.packageName}: ${n.usageNote}`);
622
- Xe({ name: d, targetDir: t, packageManager: C, useYarn: C === "yarn" });
643
+ o && ae(t) && i.log.success("Initialized a git repository.");
644
+ for (let r of h)
645
+ i.log.info(`${r.packageName}: ${r.usageNote}`);
646
+ Ze({ name: p, targetDir: t, packageManager: O, useYarn: O === "yarn" });
623
647
  }
624
- function Qe(e, t) {
625
- let r = [];
626
- e.adapter && r.push(` --adapter <id> ${t.adapterId} (available: ${E.join(", ")})`), e.plugins && r.push(` --plugins <ids> ${t.pluginIds.length > 0 ? t.pluginIds.join(",") : "none"} (available: ${Object.keys(b).join(", ")})`), e.routes && r.push(` --routes <ids> ${t.templateIds.length > 0 ? t.templateIds.join(",") : "none"} (available: ${I.join(", ")})`), e.install && r.push(` --no-install skip installing dependencies (default: ${t.install ? "installs" : "skips"})`), e.git && r.push(` --no-git skip git init (default: ${t.git ? "inits" : "skips"})`), r.length !== 0 && i.note(r.join(`
648
+ function Xe(e, t) {
649
+ let n = [];
650
+ e.adapter && n.push(` --adapter <id> ${t.adapterId} (available: ${E.join(", ")})`), e.plugins && n.push(` --plugins <ids> ${t.pluginIds.length > 0 ? t.pluginIds.join(",") : "none"} (available: ${Object.keys(w).join(", ")})`), e.routes && n.push(` --routes <ids> ${t.templateIds.length > 0 ? t.templateIds.join(",") : "none"} (available: ${C.join(", ")})`), e.install && n.push(` --no-install skip installing dependencies (default: ${t.install ? "installs" : "skips"})`), e.git && n.push(` --no-git skip git init (default: ${t.git ? "inits" : "skips"})`), n.length !== 0 && i.note(n.join(`
627
651
  `), "Using defaults for unprovided options");
628
652
  }
629
- function Xe({ name: e, targetDir: t, packageManager: r, useYarn: s }) {
630
- let l = `${r} ${s ? "" : "run "}dev`;
653
+ function Ze({ name: e, targetDir: t, packageManager: n, useYarn: s }) {
654
+ let l = `${n} ${s ? "" : "run "}dev`;
631
655
  i.note(`cd ${t}
632
656
  ${l}`, "Next steps"), i.outro(`Success! Created ${e} at ${t}`);
633
657
  }
634
658
  // packages/cli/src/commands/list.ts
635
- import S from "chalk";
636
- function de() {
637
- console.log(S.bold(`
659
+ import D from "chalk";
660
+ function ge() {
661
+ console.log(D.bold(`
638
662
  Available AsterFlow plugins:
639
663
  `));
640
- for (let e of Object.values(b))
641
- console.log(` ${S.cyan(e.id.padEnd(12))} ${S.gray(e.packageName)}`), console.log(` ${" ".repeat(12)} ${e.description}
664
+ for (let e of Object.values(w))
665
+ console.log(` ${D.cyan(e.id.padEnd(12))} ${D.gray(e.packageName)}`), console.log(` ${" ".repeat(12)} ${e.description}
642
666
  `);
643
- console.log(S.gray(`Install with: asterflow add <name>[,<name>...]
667
+ console.log(D.gray(`Install with: asterflow add <name>[,<name>...]
644
668
  `));
645
669
  }
646
670
  // packages/cli/src/index.ts
647
671
  (async () => {
648
- await Ze(et(process.argv)).scriptName("asterflow").command(
672
+ await et(tt(process.argv)).scriptName("asterflow").command(
649
673
  "init [directory]",
650
674
  "Scaffold a new AsterFlow project",
651
675
  (e) => e.positional("directory", {
@@ -662,7 +686,7 @@ Available AsterFlow plugins:
662
686
  describe: "Comma-separated plugin ids, e.g. fs,multipart"
663
687
  }).option("routes", {
664
688
  type: "string",
665
- describe: `Comma-separated route template ids to scaffold, or "none" (${I.join(", ")})`
689
+ describe: `Comma-separated route template ids to scaffold, or "none" (${C.join(", ")})`
666
690
  }).option("install", {
667
691
  type: "boolean",
668
692
  describe: "Install dependencies (default: yes)"
@@ -678,7 +702,7 @@ Available AsterFlow plugins:
678
702
  }),
679
703
  async (e) => {
680
704
  let t = e.useNpm ? "npm" : e.usePnpm ? "pnpm" : e.useYarn ? "yarn" : e.useBun ? "bun" : void 0;
681
- await ce({
705
+ await ue({
682
706
  directory: e.directory,
683
707
  name: e.name,
684
708
  adapter: e.adapter,
@@ -703,14 +727,14 @@ Available AsterFlow plugins:
703
727
  describe: "Project directory (defaults to the current directory)"
704
728
  }),
705
729
  async (e) => {
706
- await z({ names: e.names, directory: e.directory });
730
+ await Q({ names: e.names, directory: e.directory });
707
731
  }
708
732
  ).command(
709
733
  "list",
710
734
  "List available plugins",
711
735
  () => {
712
736
  },
713
- () => de()
737
+ () => ge()
714
738
  ).command(
715
739
  "generate [directory]",
716
740
  "Generate the static route manifest consumed by @asterflow/fs (fs-routing)",
@@ -727,7 +751,7 @@ Available AsterFlow plugins:
727
751
  describe: "Regenerate whenever a file under the routes directory changes"
728
752
  }),
729
753
  async (e) => {
730
- await Q({ directory: e.directory, out: e.out, watch: e.watch });
754
+ await ee({ directory: e.directory, out: e.out, watch: e.watch });
731
755
  }
732
756
  ).demandCommand(1, "Specify a command: init, add, list or generate").strict().help().alias("help", "h").parse();
733
757
  })().catch((e) => {