create-taserjs 0.0.1 → 0.0.3

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 (123) hide show
  1. package/README.md +2 -0
  2. package/dist/cjs/addons/arktype/index.cjs +6 -0
  3. package/dist/cjs/addons/arktype/index.cjs.map +1 -0
  4. package/dist/cjs/addons/drizzle/index.cjs +9 -2
  5. package/dist/cjs/addons/drizzle/index.cjs.map +1 -1
  6. package/dist/cjs/addons/kysely/index.cjs +9 -2
  7. package/dist/cjs/addons/kysely/index.cjs.map +1 -1
  8. package/dist/cjs/addons/pino/index.cjs.map +1 -1
  9. package/dist/cjs/addons/prisma/index.cjs +84 -24
  10. package/dist/cjs/addons/prisma/index.cjs.map +1 -1
  11. package/dist/cjs/addons/registry.cjs +17 -13
  12. package/dist/cjs/addons/registry.cjs.map +1 -1
  13. package/dist/cjs/addons/types.d.cts +1 -1
  14. package/dist/cjs/addons/valibot/index.cjs +6 -0
  15. package/dist/cjs/addons/valibot/index.cjs.map +1 -0
  16. package/dist/cjs/addons/validators.cjs +2 -2
  17. package/dist/cjs/addons/validators.cjs.map +1 -1
  18. package/dist/cjs/addons/winston/index.cjs.map +1 -1
  19. package/dist/cjs/addons/zod/index.cjs.map +1 -1
  20. package/dist/cjs/cli.cjs +7 -0
  21. package/dist/cjs/cli.cjs.map +1 -1
  22. package/dist/cjs/commands/create.cjs +45 -11
  23. package/dist/cjs/commands/create.cjs.map +1 -1
  24. package/dist/cjs/commands/create.d.cts +2 -0
  25. package/dist/cjs/core/json-output.cjs.map +1 -1
  26. package/dist/cjs/core/package-manager.cjs +5 -13
  27. package/dist/cjs/core/package-manager.cjs.map +1 -1
  28. package/dist/cjs/core/package-manager.d.cts +3 -2
  29. package/dist/cjs/core/parse-options.cjs +17 -7
  30. package/dist/cjs/core/parse-options.cjs.map +1 -1
  31. package/dist/cjs/core/parse-options.d.cts +4 -3
  32. package/dist/cjs/core/project-config.cjs +2 -1
  33. package/dist/cjs/core/project-config.cjs.map +1 -1
  34. package/dist/cjs/core/resolve-packages.cjs +41 -7
  35. package/dist/cjs/core/resolve-packages.cjs.map +1 -1
  36. package/dist/cjs/core/resolve-packages.d.cts +2 -2
  37. package/dist/cjs/core/scaffold-engine.cjs +37 -8
  38. package/dist/cjs/core/scaffold-engine.cjs.map +1 -1
  39. package/dist/cjs/core/types.cjs +11 -3
  40. package/dist/cjs/core/types.cjs.map +1 -1
  41. package/dist/cjs/core/types.d.cts +8 -8
  42. package/dist/cjs/core/validate-project-name.cjs.map +1 -1
  43. package/dist/cjs/frameworks/index.cjs +138 -17
  44. package/dist/cjs/frameworks/index.cjs.map +1 -1
  45. package/dist/cjs/frameworks/index.d.cts +3 -3
  46. package/dist/cjs/scaffold.d.cts +1 -1
  47. package/dist/cjs/templates/base.cjs +15 -12
  48. package/dist/cjs/templates/base.cjs.map +1 -1
  49. package/dist/cjs/types.d.cts +1 -1
  50. package/dist/esm/addons/arktype/index.js +7 -0
  51. package/dist/esm/addons/arktype/index.js.map +1 -0
  52. package/dist/esm/addons/drizzle/index.js +9 -2
  53. package/dist/esm/addons/drizzle/index.js.map +1 -1
  54. package/dist/esm/addons/kysely/index.js +9 -2
  55. package/dist/esm/addons/kysely/index.js.map +1 -1
  56. package/dist/esm/addons/pino/index.js.map +1 -1
  57. package/dist/esm/addons/prisma/index.js +84 -24
  58. package/dist/esm/addons/prisma/index.js.map +1 -1
  59. package/dist/esm/addons/registry.js +8 -4
  60. package/dist/esm/addons/registry.js.map +1 -1
  61. package/dist/esm/addons/types.d.ts +1 -1
  62. package/dist/esm/addons/valibot/index.js +7 -0
  63. package/dist/esm/addons/valibot/index.js.map +1 -0
  64. package/dist/esm/addons/validators.js +2 -2
  65. package/dist/esm/addons/validators.js.map +1 -1
  66. package/dist/esm/addons/winston/index.js.map +1 -1
  67. package/dist/esm/addons/zod/index.js.map +1 -1
  68. package/dist/esm/cli.js +7 -0
  69. package/dist/esm/cli.js.map +1 -1
  70. package/dist/esm/commands/create.d.ts +2 -0
  71. package/dist/esm/commands/create.js +47 -13
  72. package/dist/esm/commands/create.js.map +1 -1
  73. package/dist/esm/core/json-output.js.map +1 -1
  74. package/dist/esm/core/package-manager.d.ts +3 -2
  75. package/dist/esm/core/package-manager.js +5 -14
  76. package/dist/esm/core/package-manager.js.map +1 -1
  77. package/dist/esm/core/parse-options.d.ts +4 -3
  78. package/dist/esm/core/parse-options.js +17 -8
  79. package/dist/esm/core/parse-options.js.map +1 -1
  80. package/dist/esm/core/project-config.js +2 -1
  81. package/dist/esm/core/project-config.js.map +1 -1
  82. package/dist/esm/core/resolve-packages.d.ts +2 -2
  83. package/dist/esm/core/resolve-packages.js +41 -7
  84. package/dist/esm/core/resolve-packages.js.map +1 -1
  85. package/dist/esm/core/scaffold-engine.js +38 -9
  86. package/dist/esm/core/scaffold-engine.js.map +1 -1
  87. package/dist/esm/core/types.d.ts +8 -8
  88. package/dist/esm/core/types.js +11 -3
  89. package/dist/esm/core/types.js.map +1 -1
  90. package/dist/esm/core/validate-project-name.js.map +1 -1
  91. package/dist/esm/frameworks/index.d.ts +3 -3
  92. package/dist/esm/frameworks/index.js +138 -17
  93. package/dist/esm/frameworks/index.js.map +1 -1
  94. package/dist/esm/scaffold.d.ts +1 -1
  95. package/dist/esm/templates/base.js +15 -12
  96. package/dist/esm/templates/base.js.map +1 -1
  97. package/dist/esm/types.d.ts +1 -1
  98. package/package.json +13 -13
  99. package/src/addons/arktype/index.ts +2 -2
  100. package/src/addons/drizzle/index.ts +60 -47
  101. package/src/addons/kysely/index.ts +49 -36
  102. package/src/addons/pino/index.ts +12 -12
  103. package/src/addons/prisma/index.ts +128 -55
  104. package/src/addons/registry.ts +39 -35
  105. package/src/addons/types.ts +14 -14
  106. package/src/addons/valibot/index.ts +2 -2
  107. package/src/addons/validators.ts +11 -11
  108. package/src/addons/winston/index.ts +12 -12
  109. package/src/addons/zod/index.ts +2 -2
  110. package/src/cli.ts +28 -25
  111. package/src/commands/create.ts +185 -150
  112. package/src/core/json-output.ts +4 -4
  113. package/src/core/package-manager.ts +39 -35
  114. package/src/core/parse-options.ts +62 -43
  115. package/src/core/project-config.ts +13 -13
  116. package/src/core/resolve-packages.ts +79 -41
  117. package/src/core/scaffold-engine.ts +108 -36
  118. package/src/core/types.ts +61 -36
  119. package/src/core/validate-project-name.ts +40 -40
  120. package/src/frameworks/index.ts +164 -29
  121. package/src/scaffold.ts +3 -3
  122. package/src/templates/base.ts +65 -56
  123. package/src/types.ts +5 -4
@@ -1,233 +1,258 @@
1
- import path from 'node:path'
1
+ import path from "node:path";
2
2
 
3
- import * as p from '@clack/prompts'
4
- import color from 'picocolors'
3
+ import * as p from "@clack/prompts";
4
+ import color from "picocolors";
5
5
 
6
- import { getCapabilitiesCatalog } from '../addons/registry.js'
7
- import { printCapabilitiesCatalog, printJsonError, printScaffoldResult } from '../core/json-output.js'
6
+ import { getCapabilitiesCatalog } from "../addons/registry.js";
7
+ import {
8
+ printCapabilitiesCatalog,
9
+ printJsonError,
10
+ printScaffoldResult,
11
+ } from "../core/json-output.js";
8
12
  import {
9
13
  parseDbFlag,
10
- parseFrameworkFlag,
11
14
  parseLoggerFlag,
15
+ parseTypeFlag,
16
+ parseValidatorFlag,
12
17
  type ParsedCreateArgs,
13
18
  resolveScaffoldDefaults,
14
- } from '../core/parse-options.js'
15
- import { scaffoldProject } from '../core/scaffold-engine.js'
16
- import type { DbDriver, DbOdm, Framework, LoggerId, ScaffoldResult, ValidatorId } from '../core/types.js'
17
- import { DB_DRIVERS, DB_ODMS, FRAMEWORKS, LOGGERS, VALIDATORS } from '../core/types.js'
18
- import { validateProjectName } from '../core/validate-project-name.js'
19
- import { resolveUserAgent, runScript } from '../core/package-manager.js'
20
-
21
- function isFramework(value: unknown): value is Framework {
22
- return typeof value === 'string' && (FRAMEWORKS as readonly string[]).includes(value)
19
+ } from "../core/parse-options.js";
20
+ import { scaffoldProject } from "../core/scaffold-engine.js";
21
+ import type {
22
+ DbDriver,
23
+ DbOdm,
24
+ LoggerId,
25
+ ProjectType,
26
+ ScaffoldResult,
27
+ ValidatorId,
28
+ } from "../core/types.js";
29
+ import { DB_DRIVERS, DB_ODMS, LOGGERS, PROJECT_TYPES, VALIDATORS } from "../core/types.js";
30
+ import { validateProjectName } from "../core/validate-project-name.js";
31
+ import { resolveUserAgent, runScript } from "../core/package-manager.js";
32
+
33
+ function isProjectType(value: unknown): value is ProjectType {
34
+ return typeof value === "string" && (PROJECT_TYPES as readonly string[]).includes(value);
23
35
  }
24
36
 
25
37
  function isDbOdm(value: unknown): value is DbOdm {
26
- return typeof value === 'string' && (DB_ODMS as readonly string[]).includes(value)
38
+ return typeof value === "string" && (DB_ODMS as readonly string[]).includes(value);
27
39
  }
28
40
 
29
41
  function isDbDriver(value: unknown): value is DbDriver {
30
- return typeof value === 'string' && (DB_DRIVERS as readonly string[]).includes(value)
42
+ return typeof value === "string" && (DB_DRIVERS as readonly string[]).includes(value);
31
43
  }
32
44
 
33
45
  function isLoggerId(value: unknown): value is LoggerId {
34
- return typeof value === 'string' && (LOGGERS as readonly string[]).includes(value)
46
+ return typeof value === "string" && (LOGGERS as readonly string[]).includes(value);
35
47
  }
36
48
 
37
49
  function isValidatorId(value: unknown): value is ValidatorId {
38
- return typeof value === 'string' && (VALIDATORS as readonly string[]).includes(value)
50
+ return typeof value === "string" && (VALIDATORS as readonly string[]).includes(value);
39
51
  }
40
52
 
41
- async function promptInteractiveOptions(
42
- args: ParsedCreateArgs,
43
- ): Promise<ParsedCreateArgs> {
44
- const projectName = args.projectName
45
- ?? await p.text({
46
- message: 'Project name',
47
- placeholder: 'my-taser-app',
48
- defaultValue: 'my-taser-app',
53
+ async function promptInteractiveOptions(args: ParsedCreateArgs): Promise<ParsedCreateArgs> {
54
+ const projectName =
55
+ args.projectName ??
56
+ (await p.text({
57
+ message: "Project name",
58
+ placeholder: "my-taser-app",
59
+ defaultValue: "my-taser-app",
49
60
  validate(value) {
50
- return validateProjectName(value)
61
+ return validateProjectName(value);
51
62
  },
52
- })
63
+ }));
53
64
 
54
65
  if (p.isCancel(projectName)) {
55
- p.cancel('Scaffold cancelled.')
56
- process.exit(0)
66
+ p.cancel("Scaffold cancelled.");
67
+ process.exit(0);
57
68
  }
58
69
 
59
- const framework = args.framework
60
- ?? await p.select({
61
- message: 'Framework adapter',
70
+ const type =
71
+ args.type ??
72
+ (await p.select({
73
+ message: "Project type (runtime / framework)",
62
74
  options: [
63
- { value: 'node', label: 'Plain Node.js', hint: 'default' },
64
- { value: 'express', label: 'Express' },
65
- { value: 'hono', label: 'Hono' },
66
- { value: 'fastify', label: 'Fastify' },
75
+ { value: "node", label: "Node.js", hint: "default" },
76
+ { value: "express", label: "Express" },
77
+ { value: "fastify", label: "Fastify" },
78
+ { value: "hono", label: "Hono" },
79
+ { value: "bun", label: "Bun" },
80
+ { value: "deno", label: "Deno" },
81
+ { value: "aws-lambda", label: "AWS Lambda" },
82
+ { value: "cloudflare-workers", label: "Cloudflare Workers" },
83
+ { value: "netlify", label: "Netlify" },
84
+ { value: "vercel", label: "Vercel" },
85
+ { value: "azure-functions", label: "Azure Functions" },
86
+ { value: "google-cloud-run", label: "Google Cloud Run" },
67
87
  ],
68
- initialValue: 'node',
69
- })
88
+ initialValue: "node",
89
+ }));
70
90
 
71
- if (p.isCancel(framework) || !isFramework(framework)) {
72
- p.cancel('Scaffold cancelled.')
73
- process.exit(0)
91
+ if (p.isCancel(type) || !isProjectType(type)) {
92
+ p.cancel("Scaffold cancelled.");
93
+ process.exit(0);
74
94
  }
75
95
 
76
- const dbChoice = args.db
77
- ?? await p.select({
78
- message: 'Database',
96
+ const dbChoice =
97
+ args.db ??
98
+ (await p.select({
99
+ message: "Database",
79
100
  options: [
80
- { value: 'none', label: 'None', hint: 'default' },
81
- { value: 'drizzle', label: 'Drizzle' },
82
- { value: 'prisma', label: 'Prisma' },
83
- { value: 'kysely', label: 'Kysely' },
101
+ { value: "none", label: "None", hint: "default" },
102
+ { value: "drizzle", label: "Drizzle" },
103
+ { value: "prisma", label: "Prisma" },
104
+ { value: "kysely", label: "Kysely" },
84
105
  ],
85
- initialValue: 'none',
86
- })
106
+ initialValue: "none",
107
+ }));
87
108
 
88
109
  if (p.isCancel(dbChoice)) {
89
- p.cancel('Scaffold cancelled.')
90
- process.exit(0)
110
+ p.cancel("Scaffold cancelled.");
111
+ process.exit(0);
91
112
  }
92
113
 
93
- let db: DbOdm | undefined
94
- let driver: DbDriver | undefined
114
+ let db: DbOdm | undefined;
115
+ let driver: DbDriver | undefined;
95
116
 
96
- if (dbChoice !== 'none' && isDbOdm(dbChoice)) {
97
- db = dbChoice
98
- const driverChoice = args.driver
99
- ?? await p.select({
100
- message: 'Database driver',
117
+ if (dbChoice !== "none" && isDbOdm(dbChoice)) {
118
+ db = dbChoice;
119
+ const driverChoice =
120
+ args.driver ??
121
+ (await p.select({
122
+ message: "Database driver",
101
123
  options: [
102
- { value: 'sqlite', label: 'SQLite', hint: 'default' },
103
- { value: 'postgres', label: 'PostgreSQL' },
104
- { value: 'mysql', label: 'MySQL' },
124
+ { value: "sqlite", label: "SQLite", hint: "default" },
125
+ { value: "postgres", label: "PostgreSQL" },
126
+ { value: "mysql", label: "MySQL" },
105
127
  ],
106
- initialValue: 'sqlite',
107
- })
128
+ initialValue: "sqlite",
129
+ }));
108
130
 
109
131
  if (p.isCancel(driverChoice) || !isDbDriver(driverChoice)) {
110
- p.cancel('Scaffold cancelled.')
111
- process.exit(0)
132
+ p.cancel("Scaffold cancelled.");
133
+ process.exit(0);
112
134
  }
113
- driver = driverChoice
135
+ driver = driverChoice;
114
136
  }
115
137
 
116
- const loggerChoice = args.logger
117
- ?? await p.select({
118
- message: 'Logger',
138
+ const loggerChoice =
139
+ args.logger ??
140
+ (await p.select({
141
+ message: "Logger",
119
142
  options: [
120
- { value: 'none', label: 'None', hint: 'default' },
121
- { value: 'pino', label: 'Pino' },
122
- { value: 'winston', label: 'Winston' },
143
+ { value: "none", label: "None", hint: "default" },
144
+ { value: "pino", label: "Pino" },
145
+ { value: "winston", label: "Winston" },
123
146
  ],
124
- initialValue: 'none',
125
- })
147
+ initialValue: "none",
148
+ }));
126
149
 
127
150
  if (p.isCancel(loggerChoice)) {
128
- p.cancel('Scaffold cancelled.')
129
- process.exit(0)
151
+ p.cancel("Scaffold cancelled.");
152
+ process.exit(0);
130
153
  }
131
154
 
132
- const logger = loggerChoice === 'none' ? undefined : isLoggerId(loggerChoice) ? loggerChoice : undefined
155
+ const logger =
156
+ loggerChoice === "none" ? undefined : isLoggerId(loggerChoice) ? loggerChoice : undefined;
133
157
 
134
- const validatorChoice = args.validator
135
- ?? await p.select({
136
- message: 'Validator',
158
+ const validatorChoice =
159
+ args.validator ??
160
+ (await p.select({
161
+ message: "Validator",
137
162
  options: [
138
- { value: 'none', label: 'None', hint: 'default' },
139
- { value: 'zod', label: 'Zod' },
140
- { value: 'arktype', label: 'Arktype' },
141
- { value: 'valibot', label: 'Valibot' },
163
+ { value: "none", label: "None", hint: "default" },
164
+ { value: "zod", label: "Zod" },
165
+ { value: "arktype", label: "Arktype" },
166
+ { value: "valibot", label: "Valibot" },
142
167
  ],
143
- initialValue: 'none',
144
- })
168
+ initialValue: "none",
169
+ }));
145
170
 
146
171
  if (p.isCancel(validatorChoice)) {
147
- p.cancel('Scaffold cancelled.')
148
- process.exit(0)
172
+ p.cancel("Scaffold cancelled.");
173
+ process.exit(0);
149
174
  }
150
175
 
151
- const validator = validatorChoice === 'none' ? undefined : isValidatorId(validatorChoice) ? validatorChoice : undefined
176
+ const validator =
177
+ validatorChoice === "none"
178
+ ? undefined
179
+ : isValidatorId(validatorChoice)
180
+ ? validatorChoice
181
+ : undefined;
152
182
 
153
183
  return {
154
184
  projectName: String(projectName).trim(),
155
- framework,
185
+ type,
156
186
  yes: args.yes,
157
187
  noInstall: args.noInstall,
158
188
  json: args.json,
159
189
  ...(db ? { db, driver: driver! } : {}),
160
190
  ...(logger ? { logger } : {}),
161
191
  ...(validator ? { validator } : {}),
162
- }
192
+ };
163
193
  }
164
194
 
165
- export async function runCreateCommand(args: ParsedCreateArgs): Promise<ScaffoldResult | undefined> {
195
+ export async function runCreateCommand(
196
+ args: ParsedCreateArgs,
197
+ ): Promise<ScaffoldResult | undefined> {
166
198
  if (args.json && !args.projectName) {
167
- printCapabilitiesCatalog(getCapabilitiesCatalog())
168
- return undefined
199
+ printCapabilitiesCatalog(getCapabilitiesCatalog());
200
+ return undefined;
169
201
  }
170
202
 
171
- const cwd = process.cwd()
172
- const interactive = !args.yes
203
+ const cwd = process.cwd();
204
+ const interactive = !args.yes;
173
205
  const resolved = interactive
174
206
  ? await promptInteractiveOptions(args)
175
207
  : {
176
208
  ...args,
177
209
  projectName: args.projectName?.trim(),
178
- framework: args.framework ?? 'node',
179
- }
210
+ type: args.type ?? "node",
211
+ };
180
212
 
181
213
  if (!resolved.projectName) {
182
- const message = 'Project name is required'
214
+ const message = "Project name is required";
183
215
  if (args.json) {
184
- printJsonError(message)
185
- process.exit(1)
216
+ printJsonError(message);
217
+ process.exit(1);
186
218
  }
187
- throw new Error(message)
219
+ throw new Error(message);
188
220
  }
189
221
 
190
- const nameError = validateProjectName(resolved.projectName, cwd)
222
+ const nameError = validateProjectName(resolved.projectName, cwd);
191
223
  if (nameError) {
192
224
  if (args.json) {
193
- printJsonError(nameError)
194
- process.exit(1)
225
+ printJsonError(nameError);
226
+ process.exit(1);
195
227
  }
196
- throw new Error(nameError)
228
+ throw new Error(nameError);
197
229
  }
198
230
 
199
- const targetDir = path.resolve(cwd, resolved.projectName)
231
+ const targetDir = path.resolve(cwd, resolved.projectName);
200
232
  const scaffoldCtx = resolveScaffoldDefaults({
201
233
  ...resolved,
202
234
  projectName: resolved.projectName,
203
- })
204
- scaffoldCtx.targetDir = targetDir
235
+ });
236
+ scaffoldCtx.targetDir = targetDir;
205
237
 
206
238
  if (!args.json) {
207
- const spinner = p.spinner()
208
- spinner.start('Scaffolding project')
239
+ const spinner = p.spinner();
240
+ spinner.start("Scaffolding project");
209
241
  try {
210
242
  const result = await scaffoldProject({
211
243
  ...scaffoldCtx,
212
244
  targetDir,
213
245
  skipInstall: args.noInstall,
214
246
  agent: resolveUserAgent(),
215
- })
216
- spinner.stop('Project created')
217
- const cdPath = path.relative(cwd, targetDir) || '.'
218
- p.note(
219
- [
220
- `cd ${cdPath}`,
221
- runScript(resolveUserAgent(), 'dev'),
222
- ].join('\n'),
223
- 'Next steps',
224
- )
225
- p.outro(color.green('Done.'))
226
- return result
227
- }
228
- catch (error) {
229
- spinner.stop('Scaffold failed')
230
- throw error
247
+ });
248
+ spinner.stop("Project created");
249
+ const cdPath = path.relative(cwd, targetDir) || ".";
250
+ p.note([`cd ${cdPath}`, runScript(resolveUserAgent(), "dev")].join("\n"), "Next steps");
251
+ p.outro(color.green("Done."));
252
+ return result;
253
+ } catch (error) {
254
+ spinner.stop("Scaffold failed");
255
+ throw error;
231
256
  }
232
257
  }
233
258
 
@@ -236,42 +261,52 @@ export async function runCreateCommand(args: ParsedCreateArgs): Promise<Scaffold
236
261
  targetDir,
237
262
  skipInstall: args.noInstall,
238
263
  agent: resolveUserAgent(),
239
- })
240
- printScaffoldResult(result)
241
- return result
264
+ });
265
+ printScaffoldResult(result);
266
+ return result;
242
267
  }
243
268
 
244
- export function buildParsedArgsFromCli(values: {
245
- framework?: string
246
- db?: string
247
- logger?: string
248
- y?: boolean
249
- noInstall?: boolean
250
- json?: boolean
251
- }, positionals: string[]): ParsedCreateArgs {
269
+ export function buildParsedArgsFromCli(
270
+ values: {
271
+ type?: string;
272
+ framework?: string;
273
+ db?: string;
274
+ logger?: string;
275
+ validator?: string;
276
+ y?: boolean;
277
+ noInstall?: boolean;
278
+ json?: boolean;
279
+ },
280
+ positionals: string[],
281
+ ): ParsedCreateArgs {
252
282
  const args: ParsedCreateArgs = {
253
283
  yes: values.y ?? false,
254
284
  noInstall: values.noInstall ?? false,
255
285
  json: values.json ?? false,
256
- }
286
+ };
257
287
 
258
288
  if (positionals[0]) {
259
- args.projectName = positionals[0]
289
+ args.projectName = positionals[0];
260
290
  }
261
291
 
262
- if (values.framework) {
263
- args.framework = parseFrameworkFlag(values.framework)
292
+ const typeFlag = values.type ?? values.framework;
293
+ if (typeFlag) {
294
+ args.type = parseTypeFlag(typeFlag);
264
295
  }
265
296
 
266
297
  if (values.db) {
267
- const parsed = parseDbFlag(values.db)
268
- args.db = parsed.db
269
- args.driver = parsed.driver
298
+ const parsed = parseDbFlag(values.db);
299
+ args.db = parsed.db;
300
+ args.driver = parsed.driver;
270
301
  }
271
302
 
272
303
  if (values.logger) {
273
- args.logger = parseLoggerFlag(values.logger)
304
+ args.logger = parseLoggerFlag(values.logger);
305
+ }
306
+
307
+ if (values.validator) {
308
+ args.validator = parseValidatorFlag(values.validator);
274
309
  }
275
310
 
276
- return args
311
+ return args;
277
312
  }
@@ -1,13 +1,13 @@
1
- import type { CapabilitiesCatalog, ScaffoldResult } from './types.js'
1
+ import type { CapabilitiesCatalog, ScaffoldResult } from "./types.js";
2
2
 
3
3
  export function printCapabilitiesCatalog(catalog: CapabilitiesCatalog): void {
4
- console.log(JSON.stringify(catalog, null, 2))
4
+ console.log(JSON.stringify(catalog, null, 2));
5
5
  }
6
6
 
7
7
  export function printScaffoldResult(result: ScaffoldResult): void {
8
- console.log(JSON.stringify(result, null, 2))
8
+ console.log(JSON.stringify(result, null, 2));
9
9
  }
10
10
 
11
11
  export function printJsonError(message: string): void {
12
- console.error(JSON.stringify({ error: message }))
12
+ console.error(JSON.stringify({ error: message }));
13
13
  }
@@ -1,68 +1,72 @@
1
- import { spawn } from 'node:child_process'
1
+ import { spawn } from "node:child_process";
2
2
 
3
- import type { Agent, ResolvedCommand } from 'package-manager-detector'
4
- import { resolveCommand } from 'package-manager-detector/commands'
5
- import { getUserAgent } from 'package-manager-detector/detect'
3
+ import type { Agent, ResolvedCommand } from "package-manager-detector";
4
+ import { resolveCommand } from "package-manager-detector/commands";
5
+ import { getUserAgent } from "package-manager-detector/detect";
6
6
 
7
7
  export function resolveUserAgent(): Agent {
8
- return getUserAgent() || 'npm'
8
+ return getUserAgent() || "npm";
9
9
  }
10
10
 
11
11
  function runCommand(command: string, args: string[], cwd: string): Promise<void> {
12
12
  return new Promise((resolve, reject) => {
13
13
  const child = spawn(command, args, {
14
14
  cwd,
15
- stdio: 'inherit',
15
+ stdio: "inherit",
16
16
  shell: false,
17
17
  env: process.env,
18
- })
19
- child.on('error', reject)
20
- child.on('close', (code) => {
18
+ });
19
+ child.on("error", reject);
20
+ child.on("close", (code) => {
21
21
  if (code === 0) {
22
- resolve()
23
- return
22
+ resolve();
23
+ return;
24
24
  }
25
- reject(new Error(`${command} ${args.join(' ')} exited with code ${code}`))
26
- })
27
- })
25
+ reject(new Error(`${command} ${args.join(" ")} exited with code ${code}`));
26
+ });
27
+ });
28
28
  }
29
29
 
30
- const fallback = {
31
- agent: 'npm',
32
- install: (packages: string[], dev: boolean) => {
33
- return ['install', ...packages, dev ? '-D' : '']
34
- },
35
- }
36
-
37
- function resolveInstallCommand(agent: Agent, packages: string[], dev: boolean): ResolvedCommand {
38
- const command = resolveCommand(agent, 'install', packages)
39
- if (command) return command
30
+ export function resolveInstallCommand(
31
+ agent: Agent,
32
+ packages: string[],
33
+ dev: boolean,
34
+ ): ResolvedCommand {
35
+ const args = dev ? ["-D", ...packages] : packages;
36
+ const command = resolveCommand(agent, "add", args);
37
+ if (command) return command;
40
38
 
41
- return { command: fallback.agent, args: fallback.install(packages, dev) }
39
+ return {
40
+ command: "npm",
41
+ args: ["install", ...args],
42
+ };
42
43
  }
43
44
 
44
45
  export async function installPackages(
45
46
  agent: Agent,
46
47
  cwd: string,
47
- { dependencies, devDependencies }: {
48
- dependencies: string[]
49
- devDependencies: string[]
48
+ {
49
+ dependencies,
50
+ devDependencies,
51
+ }: {
52
+ dependencies: string[];
53
+ devDependencies: string[];
50
54
  },
51
55
  ): Promise<void> {
52
56
  if (dependencies.length > 0) {
53
- const { command, args } = resolveInstallCommand(agent, dependencies, false)
54
- await runCommand(command, args, cwd)
57
+ const { command, args } = resolveInstallCommand(agent, dependencies, false);
58
+ await runCommand(command, args, cwd);
55
59
  }
56
60
  if (devDependencies.length > 0) {
57
- const { command, args } = resolveInstallCommand(agent, devDependencies, true)
58
- await runCommand(command, args, cwd)
61
+ const { command, args } = resolveInstallCommand(agent, devDependencies, true);
62
+ await runCommand(command, args, cwd);
59
63
  }
60
64
  }
61
65
 
62
66
  export function runScript(agent: Agent, script: string): string {
63
- const resolved = resolveCommand(agent, 'run', [script])
67
+ const resolved = resolveCommand(agent, "run", [script]);
64
68
  if (!resolved) {
65
- throw new Error(`Unable to resolve run command for ${agent}`)
69
+ throw new Error(`Unable to resolve run command for ${agent}`);
66
70
  }
67
- return `${resolved.command} ${resolved.args.join(' ')}`
71
+ return `${resolved.command} ${resolved.args.join(" ")}`;
68
72
  }