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