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.
- package/README.md +2 -0
- package/dist/cjs/addons/arktype/index.cjs +6 -0
- package/dist/cjs/addons/arktype/index.cjs.map +1 -0
- package/dist/cjs/addons/drizzle/index.cjs +9 -2
- package/dist/cjs/addons/drizzle/index.cjs.map +1 -1
- package/dist/cjs/addons/kysely/index.cjs +9 -2
- package/dist/cjs/addons/kysely/index.cjs.map +1 -1
- package/dist/cjs/addons/pino/index.cjs.map +1 -1
- package/dist/cjs/addons/prisma/index.cjs +84 -24
- package/dist/cjs/addons/prisma/index.cjs.map +1 -1
- package/dist/cjs/addons/registry.cjs +17 -13
- package/dist/cjs/addons/registry.cjs.map +1 -1
- package/dist/cjs/addons/types.d.cts +1 -1
- package/dist/cjs/addons/valibot/index.cjs +6 -0
- package/dist/cjs/addons/valibot/index.cjs.map +1 -0
- package/dist/cjs/addons/validators.cjs +2 -2
- package/dist/cjs/addons/validators.cjs.map +1 -1
- package/dist/cjs/addons/winston/index.cjs.map +1 -1
- package/dist/cjs/addons/zod/index.cjs.map +1 -1
- package/dist/cjs/cli.cjs +7 -0
- package/dist/cjs/cli.cjs.map +1 -1
- package/dist/cjs/commands/create.cjs +45 -11
- package/dist/cjs/commands/create.cjs.map +1 -1
- package/dist/cjs/commands/create.d.cts +2 -0
- package/dist/cjs/core/json-output.cjs.map +1 -1
- package/dist/cjs/core/package-manager.cjs +5 -13
- package/dist/cjs/core/package-manager.cjs.map +1 -1
- package/dist/cjs/core/package-manager.d.cts +3 -2
- package/dist/cjs/core/parse-options.cjs +17 -7
- package/dist/cjs/core/parse-options.cjs.map +1 -1
- package/dist/cjs/core/parse-options.d.cts +4 -3
- package/dist/cjs/core/project-config.cjs +2 -1
- package/dist/cjs/core/project-config.cjs.map +1 -1
- package/dist/cjs/core/resolve-packages.cjs +41 -7
- package/dist/cjs/core/resolve-packages.cjs.map +1 -1
- package/dist/cjs/core/resolve-packages.d.cts +2 -2
- package/dist/cjs/core/scaffold-engine.cjs +37 -8
- package/dist/cjs/core/scaffold-engine.cjs.map +1 -1
- package/dist/cjs/core/types.cjs +11 -3
- package/dist/cjs/core/types.cjs.map +1 -1
- package/dist/cjs/core/types.d.cts +8 -8
- package/dist/cjs/core/validate-project-name.cjs.map +1 -1
- package/dist/cjs/frameworks/index.cjs +138 -17
- package/dist/cjs/frameworks/index.cjs.map +1 -1
- package/dist/cjs/frameworks/index.d.cts +3 -3
- package/dist/cjs/scaffold.d.cts +1 -1
- package/dist/cjs/templates/base.cjs +15 -12
- package/dist/cjs/templates/base.cjs.map +1 -1
- package/dist/cjs/types.d.cts +1 -1
- package/dist/esm/addons/arktype/index.js +7 -0
- package/dist/esm/addons/arktype/index.js.map +1 -0
- package/dist/esm/addons/drizzle/index.js +9 -2
- package/dist/esm/addons/drizzle/index.js.map +1 -1
- package/dist/esm/addons/kysely/index.js +9 -2
- package/dist/esm/addons/kysely/index.js.map +1 -1
- package/dist/esm/addons/pino/index.js.map +1 -1
- package/dist/esm/addons/prisma/index.js +84 -24
- package/dist/esm/addons/prisma/index.js.map +1 -1
- package/dist/esm/addons/registry.js +8 -4
- package/dist/esm/addons/registry.js.map +1 -1
- package/dist/esm/addons/types.d.ts +1 -1
- package/dist/esm/addons/valibot/index.js +7 -0
- package/dist/esm/addons/valibot/index.js.map +1 -0
- package/dist/esm/addons/validators.js +2 -2
- package/dist/esm/addons/validators.js.map +1 -1
- package/dist/esm/addons/winston/index.js.map +1 -1
- package/dist/esm/addons/zod/index.js.map +1 -1
- package/dist/esm/cli.js +7 -0
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/commands/create.d.ts +2 -0
- package/dist/esm/commands/create.js +47 -13
- package/dist/esm/commands/create.js.map +1 -1
- package/dist/esm/core/json-output.js.map +1 -1
- package/dist/esm/core/package-manager.d.ts +3 -2
- package/dist/esm/core/package-manager.js +5 -14
- package/dist/esm/core/package-manager.js.map +1 -1
- package/dist/esm/core/parse-options.d.ts +4 -3
- package/dist/esm/core/parse-options.js +17 -8
- package/dist/esm/core/parse-options.js.map +1 -1
- package/dist/esm/core/project-config.js +2 -1
- package/dist/esm/core/project-config.js.map +1 -1
- package/dist/esm/core/resolve-packages.d.ts +2 -2
- package/dist/esm/core/resolve-packages.js +41 -7
- package/dist/esm/core/resolve-packages.js.map +1 -1
- package/dist/esm/core/scaffold-engine.js +38 -9
- package/dist/esm/core/scaffold-engine.js.map +1 -1
- package/dist/esm/core/types.d.ts +8 -8
- package/dist/esm/core/types.js +11 -3
- package/dist/esm/core/types.js.map +1 -1
- package/dist/esm/core/validate-project-name.js.map +1 -1
- package/dist/esm/frameworks/index.d.ts +3 -3
- package/dist/esm/frameworks/index.js +138 -17
- package/dist/esm/frameworks/index.js.map +1 -1
- package/dist/esm/scaffold.d.ts +1 -1
- package/dist/esm/templates/base.js +15 -12
- package/dist/esm/templates/base.js.map +1 -1
- package/dist/esm/types.d.ts +1 -1
- package/package.json +13 -13
- package/src/addons/arktype/index.ts +2 -2
- package/src/addons/drizzle/index.ts +60 -47
- package/src/addons/kysely/index.ts +49 -36
- package/src/addons/pino/index.ts +12 -12
- package/src/addons/prisma/index.ts +128 -55
- package/src/addons/registry.ts +39 -35
- package/src/addons/types.ts +14 -14
- package/src/addons/valibot/index.ts +2 -2
- package/src/addons/validators.ts +11 -11
- package/src/addons/winston/index.ts +12 -12
- package/src/addons/zod/index.ts +2 -2
- package/src/cli.ts +28 -25
- package/src/commands/create.ts +185 -150
- package/src/core/json-output.ts +4 -4
- package/src/core/package-manager.ts +39 -35
- package/src/core/parse-options.ts +62 -43
- package/src/core/project-config.ts +13 -13
- package/src/core/resolve-packages.ts +79 -41
- package/src/core/scaffold-engine.ts +108 -36
- package/src/core/types.ts +61 -36
- package/src/core/validate-project-name.ts +40 -40
- package/src/frameworks/index.ts +164 -29
- package/src/scaffold.ts +3 -3
- package/src/templates/base.ts +65 -56
- package/src/types.ts +5 -4
package/src/commands/create.ts
CHANGED
|
@@ -1,233 +1,258 @@
|
|
|
1
|
-
import path from
|
|
1
|
+
import path from "node:path";
|
|
2
2
|
|
|
3
|
-
import * as p from
|
|
4
|
-
import color from
|
|
3
|
+
import * as p from "@clack/prompts";
|
|
4
|
+
import color from "picocolors";
|
|
5
5
|
|
|
6
|
-
import { getCapabilitiesCatalog } from
|
|
7
|
-
import {
|
|
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
|
|
15
|
-
import { scaffoldProject } from
|
|
16
|
-
import type {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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 ===
|
|
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 ===
|
|
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 ===
|
|
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 ===
|
|
50
|
+
return typeof value === "string" && (VALIDATORS as readonly string[]).includes(value);
|
|
39
51
|
}
|
|
40
52
|
|
|
41
|
-
async function promptInteractiveOptions(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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(
|
|
56
|
-
process.exit(0)
|
|
66
|
+
p.cancel("Scaffold cancelled.");
|
|
67
|
+
process.exit(0);
|
|
57
68
|
}
|
|
58
69
|
|
|
59
|
-
const
|
|
60
|
-
??
|
|
61
|
-
|
|
70
|
+
const type =
|
|
71
|
+
args.type ??
|
|
72
|
+
(await p.select({
|
|
73
|
+
message: "Project type (runtime / framework)",
|
|
62
74
|
options: [
|
|
63
|
-
{ value:
|
|
64
|
-
{ value:
|
|
65
|
-
{ value:
|
|
66
|
-
{ value:
|
|
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:
|
|
69
|
-
})
|
|
88
|
+
initialValue: "node",
|
|
89
|
+
}));
|
|
70
90
|
|
|
71
|
-
if (p.isCancel(
|
|
72
|
-
p.cancel(
|
|
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 =
|
|
77
|
-
??
|
|
78
|
-
|
|
96
|
+
const dbChoice =
|
|
97
|
+
args.db ??
|
|
98
|
+
(await p.select({
|
|
99
|
+
message: "Database",
|
|
79
100
|
options: [
|
|
80
|
-
{ value:
|
|
81
|
-
{ value:
|
|
82
|
-
{ value:
|
|
83
|
-
{ value:
|
|
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:
|
|
86
|
-
})
|
|
106
|
+
initialValue: "none",
|
|
107
|
+
}));
|
|
87
108
|
|
|
88
109
|
if (p.isCancel(dbChoice)) {
|
|
89
|
-
p.cancel(
|
|
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 !==
|
|
97
|
-
db = dbChoice
|
|
98
|
-
const driverChoice =
|
|
99
|
-
??
|
|
100
|
-
|
|
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:
|
|
103
|
-
{ value:
|
|
104
|
-
{ value:
|
|
124
|
+
{ value: "sqlite", label: "SQLite", hint: "default" },
|
|
125
|
+
{ value: "postgres", label: "PostgreSQL" },
|
|
126
|
+
{ value: "mysql", label: "MySQL" },
|
|
105
127
|
],
|
|
106
|
-
initialValue:
|
|
107
|
-
})
|
|
128
|
+
initialValue: "sqlite",
|
|
129
|
+
}));
|
|
108
130
|
|
|
109
131
|
if (p.isCancel(driverChoice) || !isDbDriver(driverChoice)) {
|
|
110
|
-
p.cancel(
|
|
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 =
|
|
117
|
-
??
|
|
118
|
-
|
|
138
|
+
const loggerChoice =
|
|
139
|
+
args.logger ??
|
|
140
|
+
(await p.select({
|
|
141
|
+
message: "Logger",
|
|
119
142
|
options: [
|
|
120
|
-
{ value:
|
|
121
|
-
{ value:
|
|
122
|
-
{ value:
|
|
143
|
+
{ value: "none", label: "None", hint: "default" },
|
|
144
|
+
{ value: "pino", label: "Pino" },
|
|
145
|
+
{ value: "winston", label: "Winston" },
|
|
123
146
|
],
|
|
124
|
-
initialValue:
|
|
125
|
-
})
|
|
147
|
+
initialValue: "none",
|
|
148
|
+
}));
|
|
126
149
|
|
|
127
150
|
if (p.isCancel(loggerChoice)) {
|
|
128
|
-
p.cancel(
|
|
129
|
-
process.exit(0)
|
|
151
|
+
p.cancel("Scaffold cancelled.");
|
|
152
|
+
process.exit(0);
|
|
130
153
|
}
|
|
131
154
|
|
|
132
|
-
const logger =
|
|
155
|
+
const logger =
|
|
156
|
+
loggerChoice === "none" ? undefined : isLoggerId(loggerChoice) ? loggerChoice : undefined;
|
|
133
157
|
|
|
134
|
-
const validatorChoice =
|
|
135
|
-
??
|
|
136
|
-
|
|
158
|
+
const validatorChoice =
|
|
159
|
+
args.validator ??
|
|
160
|
+
(await p.select({
|
|
161
|
+
message: "Validator",
|
|
137
162
|
options: [
|
|
138
|
-
{ value:
|
|
139
|
-
{ value:
|
|
140
|
-
{ value:
|
|
141
|
-
{ value:
|
|
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:
|
|
144
|
-
})
|
|
168
|
+
initialValue: "none",
|
|
169
|
+
}));
|
|
145
170
|
|
|
146
171
|
if (p.isCancel(validatorChoice)) {
|
|
147
|
-
p.cancel(
|
|
148
|
-
process.exit(0)
|
|
172
|
+
p.cancel("Scaffold cancelled.");
|
|
173
|
+
process.exit(0);
|
|
149
174
|
}
|
|
150
175
|
|
|
151
|
-
const validator =
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
179
|
-
}
|
|
210
|
+
type: args.type ?? "node",
|
|
211
|
+
};
|
|
180
212
|
|
|
181
213
|
if (!resolved.projectName) {
|
|
182
|
-
const message =
|
|
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(
|
|
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(
|
|
217
|
-
const cdPath = path.relative(cwd, targetDir) ||
|
|
218
|
-
p.note(
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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(
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
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
|
-
|
|
263
|
-
|
|
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
|
}
|
package/src/core/json-output.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import type { CapabilitiesCatalog, ScaffoldResult } from
|
|
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
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
2
|
|
|
3
|
-
import type { Agent, ResolvedCommand } from
|
|
4
|
-
import { resolveCommand } from
|
|
5
|
-
import { getUserAgent } from
|
|
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() ||
|
|
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:
|
|
15
|
+
stdio: "inherit",
|
|
16
16
|
shell: false,
|
|
17
17
|
env: process.env,
|
|
18
|
-
})
|
|
19
|
-
child.on(
|
|
20
|
-
child.on(
|
|
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(
|
|
26
|
-
})
|
|
27
|
-
})
|
|
25
|
+
reject(new Error(`${command} ${args.join(" ")} exited with code ${code}`));
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
agent:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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 {
|
|
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
|
-
{
|
|
48
|
-
dependencies
|
|
49
|
-
devDependencies
|
|
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,
|
|
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
|
}
|