create-taserjs 0.0.5 → 0.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/README.md +1 -1
- package/dist/cjs/addons/registry.cjs +3 -4
- package/dist/cjs/addons/registry.cjs.map +1 -1
- package/dist/cjs/addons/validators.cjs +10 -13
- package/dist/cjs/addons/validators.cjs.map +1 -1
- package/dist/cjs/cli.cjs +7 -5
- package/dist/cjs/cli.cjs.map +1 -1
- package/dist/cjs/commands/create.cjs +68 -48
- package/dist/cjs/commands/create.cjs.map +1 -1
- package/dist/cjs/commands/create.d.cts +2 -1
- package/dist/cjs/core/parse-options.cjs +48 -22
- package/dist/cjs/core/parse-options.cjs.map +1 -1
- package/dist/cjs/core/parse-options.d.cts +19 -4
- package/dist/cjs/core/project-config.cjs +5 -1
- package/dist/cjs/core/project-config.cjs.map +1 -1
- package/dist/cjs/core/resolve-packages.cjs +28 -66
- package/dist/cjs/core/resolve-packages.cjs.map +1 -1
- package/dist/cjs/core/resolve-packages.d.cts +1 -4
- package/dist/cjs/core/scaffold-engine.cjs +18 -49
- package/dist/cjs/core/scaffold-engine.cjs.map +1 -1
- package/dist/cjs/core/targets.cjs +162 -0
- package/dist/cjs/core/targets.cjs.map +1 -0
- package/dist/cjs/core/targets.d.cts +49 -0
- package/dist/cjs/core/types.cjs +21 -11
- package/dist/cjs/core/types.cjs.map +1 -1
- package/dist/cjs/core/types.d.cts +20 -4
- package/dist/cjs/frameworks/index.cjs +76 -194
- package/dist/cjs/frameworks/index.cjs.map +1 -1
- package/dist/cjs/frameworks/index.d.cts +18 -3
- package/dist/cjs/scaffold.d.cts +2 -2
- package/dist/cjs/templates/base.cjs +15 -99
- package/dist/cjs/templates/base.cjs.map +1 -1
- package/dist/cjs/templates/base.d.cts +0 -3
- package/dist/cjs/types.d.cts +1 -1
- package/dist/esm/addons/registry.js +4 -5
- package/dist/esm/addons/registry.js.map +1 -1
- package/dist/esm/addons/validators.js +10 -13
- package/dist/esm/addons/validators.js.map +1 -1
- package/dist/esm/cli.js +7 -5
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/commands/create.d.ts +2 -1
- package/dist/esm/commands/create.js +70 -50
- package/dist/esm/commands/create.js.map +1 -1
- package/dist/esm/core/parse-options.d.ts +19 -4
- package/dist/esm/core/parse-options.js +47 -23
- package/dist/esm/core/parse-options.js.map +1 -1
- package/dist/esm/core/project-config.js +5 -1
- package/dist/esm/core/project-config.js.map +1 -1
- package/dist/esm/core/resolve-packages.d.ts +1 -4
- package/dist/esm/core/resolve-packages.js +28 -66
- package/dist/esm/core/resolve-packages.js.map +1 -1
- package/dist/esm/core/scaffold-engine.js +20 -51
- package/dist/esm/core/scaffold-engine.js.map +1 -1
- package/dist/esm/core/targets.d.ts +49 -0
- package/dist/esm/core/targets.js +157 -0
- package/dist/esm/core/targets.js.map +1 -0
- package/dist/esm/core/types.d.ts +20 -4
- package/dist/esm/core/types.js +19 -11
- package/dist/esm/core/types.js.map +1 -1
- package/dist/esm/frameworks/index.d.ts +18 -3
- package/dist/esm/frameworks/index.js +73 -194
- package/dist/esm/frameworks/index.js.map +1 -1
- package/dist/esm/scaffold.d.ts +2 -2
- package/dist/esm/templates/base.d.ts +0 -3
- package/dist/esm/templates/base.js +16 -98
- package/dist/esm/templates/base.js.map +1 -1
- package/dist/esm/types.d.ts +1 -1
- package/package.json +3 -2
- package/src/addons/registry.ts +6 -17
- package/src/addons/validators.ts +10 -13
- package/src/cli.ts +6 -4
- package/src/commands/create.ts +82 -26
- package/src/core/parse-options.ts +84 -35
- package/src/core/project-config.ts +6 -1
- package/src/core/resolve-packages.ts +38 -76
- package/src/core/scaffold-engine.ts +43 -81
- package/src/core/targets.ts +202 -0
- package/src/core/types.ts +38 -24
- package/src/frameworks/index.ts +75 -211
- package/src/scaffold.ts +2 -2
- package/src/templates/base.ts +14 -98
- package/src/types.ts +3 -1
package/src/addons/validators.ts
CHANGED
|
@@ -8,26 +8,23 @@ export const IMPORT_LINES: Record<ValidatorId, string> = {
|
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
export const VALIDATION_BLOCK_TEMPLATE: Record<ValidatorId, string> = {
|
|
11
|
-
zod:
|
|
12
|
-
query
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}`,
|
|
17
|
-
valibot: `, {
|
|
18
|
-
query: v.object({ name: v.string() }),
|
|
19
|
-
}`,
|
|
11
|
+
zod: `
|
|
12
|
+
.query(z.object({ name: z.string().default('Taser') }))`,
|
|
13
|
+
arktype: `
|
|
14
|
+
.query(type({ 'name?': 'string = "Taser"' }))`,
|
|
15
|
+
valibot: `
|
|
16
|
+
.query(v.object({ name: v.optional(v.string(), 'Taser') }))`,
|
|
20
17
|
};
|
|
21
18
|
|
|
22
|
-
const ROUTE_TEMPLATE = (validator: ValidatorId) => `import {
|
|
23
|
-
import { t } from '#
|
|
19
|
+
const ROUTE_TEMPLATE = (validator: ValidatorId) => `import { json } from '@taserjs/router/reply'
|
|
20
|
+
import { t } from '#taserjs/router'
|
|
24
21
|
${IMPORT_LINES[validator]}
|
|
25
22
|
|
|
26
|
-
const GET = t.get('/'${VALIDATION_BLOCK_TEMPLATE[validator]}
|
|
23
|
+
const GET = t.get('/')${VALIDATION_BLOCK_TEMPLATE[validator]}
|
|
27
24
|
|
|
28
25
|
export type RouteContext = typeof GET.$Infer.Context
|
|
29
26
|
export const Route = GET.handler((ctx) => {
|
|
30
|
-
return
|
|
27
|
+
return json({ message: \`Hello, \${ctx.query.name}!\` })
|
|
31
28
|
})
|
|
32
29
|
`;
|
|
33
30
|
|
package/src/cli.ts
CHANGED
|
@@ -11,11 +11,12 @@ async function main(): Promise<void> {
|
|
|
11
11
|
const { values, positionals } = parseArgs({
|
|
12
12
|
args: process.argv.slice(2),
|
|
13
13
|
options: {
|
|
14
|
-
|
|
15
|
-
framework: { type: "string" },
|
|
14
|
+
preset: { type: "string", short: "p" },
|
|
16
15
|
db: { type: "string" },
|
|
17
16
|
logger: { type: "string" },
|
|
18
17
|
validator: { type: "string" },
|
|
18
|
+
framework: { type: "string" },
|
|
19
|
+
runtime: { type: "string" },
|
|
19
20
|
y: { type: "boolean", short: "y" },
|
|
20
21
|
noInstall: { type: "boolean" },
|
|
21
22
|
json: { type: "boolean" },
|
|
@@ -25,11 +26,12 @@ async function main(): Promise<void> {
|
|
|
25
26
|
|
|
26
27
|
const parsed = buildParsedArgsFromCli(
|
|
27
28
|
{
|
|
28
|
-
...(values.
|
|
29
|
-
...(values.framework !== undefined ? { framework: values.framework } : {}),
|
|
29
|
+
...(values.preset !== undefined ? { preset: values.preset } : {}),
|
|
30
30
|
...(values.db !== undefined ? { db: values.db } : {}),
|
|
31
31
|
...(values.logger !== undefined ? { logger: values.logger } : {}),
|
|
32
32
|
...(values.validator !== undefined ? { validator: values.validator } : {}),
|
|
33
|
+
...(values.framework !== undefined ? { framework: values.framework } : {}),
|
|
34
|
+
...(values.runtime !== undefined ? { runtime: values.runtime } : {}),
|
|
33
35
|
...(values.y !== undefined ? { y: values.y } : {}),
|
|
34
36
|
...(values.noInstall !== undefined ? { noInstall: values.noInstall } : {}),
|
|
35
37
|
...(values.json !== undefined ? { json: values.json } : {}),
|
package/src/commands/create.ts
CHANGED
|
@@ -11,27 +11,30 @@ import {
|
|
|
11
11
|
} from "../core/json-output.js";
|
|
12
12
|
import {
|
|
13
13
|
parseDbFlag,
|
|
14
|
+
parseFrameworkFlag,
|
|
14
15
|
parseLoggerFlag,
|
|
15
|
-
|
|
16
|
+
parsePresetFlag,
|
|
17
|
+
parseRuntimeFlag,
|
|
16
18
|
parseValidatorFlag,
|
|
17
19
|
type ParsedCreateArgs,
|
|
18
20
|
resolveScaffoldDefaults,
|
|
19
21
|
} from "../core/parse-options.js";
|
|
20
22
|
import { scaffoldProject } from "../core/scaffold-engine.js";
|
|
23
|
+
import { allowedRuntimeOverrides } from "../core/targets.js";
|
|
21
24
|
import type {
|
|
22
25
|
DbDriver,
|
|
23
26
|
DbOdm,
|
|
27
|
+
DeployTarget,
|
|
24
28
|
LoggerId,
|
|
25
|
-
ProjectType,
|
|
26
29
|
ScaffoldResult,
|
|
27
30
|
ValidatorId,
|
|
28
31
|
} from "../core/types.js";
|
|
29
|
-
import { DB_DRIVERS, DB_ODMS,
|
|
32
|
+
import { DB_DRIVERS, DB_ODMS, DEPLOY_TARGETS, LOGGERS, VALIDATORS } from "../core/types.js";
|
|
30
33
|
import { validateProjectName } from "../core/validate-project-name.js";
|
|
31
34
|
import { resolveUserAgent, runScript } from "../core/package-manager.js";
|
|
32
35
|
|
|
33
|
-
function
|
|
34
|
-
return typeof value === "string" && (
|
|
36
|
+
function isDeployTarget(value: unknown): value is DeployTarget {
|
|
37
|
+
return typeof value === "string" && (DEPLOY_TARGETS as readonly string[]).includes(value);
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
function isDbOdm(value: unknown): value is DbOdm {
|
|
@@ -67,32 +70,71 @@ async function promptInteractiveOptions(args: ParsedCreateArgs): Promise<ParsedC
|
|
|
67
70
|
process.exit(0);
|
|
68
71
|
}
|
|
69
72
|
|
|
70
|
-
const
|
|
71
|
-
args.
|
|
73
|
+
const framework =
|
|
74
|
+
args.framework ??
|
|
72
75
|
(await p.select({
|
|
73
|
-
message: "
|
|
76
|
+
message: "Host framework",
|
|
74
77
|
options: [
|
|
75
|
-
{ value: "
|
|
78
|
+
{ value: "none", label: "Pure Taser", hint: "default" },
|
|
79
|
+
{ value: "hono", label: "Hono" },
|
|
76
80
|
{ value: "express", label: "Express" },
|
|
77
81
|
{ 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" },
|
|
87
82
|
],
|
|
88
|
-
initialValue: "
|
|
83
|
+
initialValue: "none",
|
|
84
|
+
}));
|
|
85
|
+
|
|
86
|
+
if (p.isCancel(framework)) {
|
|
87
|
+
p.cancel("Scaffold cancelled.");
|
|
88
|
+
process.exit(0);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const DEPLOY_LABELS: Record<DeployTarget, string> = {
|
|
92
|
+
"node-server": "Node.js server",
|
|
93
|
+
"node-cluster": "Node.js cluster",
|
|
94
|
+
bun: "Bun",
|
|
95
|
+
"deno-server": "Deno",
|
|
96
|
+
"deno-deploy": "Deno Deploy",
|
|
97
|
+
"cloudflare-module": "Cloudflare Workers",
|
|
98
|
+
vercel: "Vercel",
|
|
99
|
+
"aws-lambda": "AWS Lambda",
|
|
100
|
+
netlify: "Netlify",
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const preset =
|
|
104
|
+
args.preset ??
|
|
105
|
+
(await p.select({
|
|
106
|
+
message: "Deployment target",
|
|
107
|
+
options: DEPLOY_TARGETS.map((id) => ({ value: id, label: DEPLOY_LABELS[id] })),
|
|
108
|
+
initialValue: "node-server",
|
|
89
109
|
}));
|
|
90
110
|
|
|
91
|
-
if (p.isCancel(
|
|
111
|
+
if (p.isCancel(preset) || !isDeployTarget(preset)) {
|
|
92
112
|
p.cancel("Scaffold cancelled.");
|
|
93
113
|
process.exit(0);
|
|
94
114
|
}
|
|
95
115
|
|
|
116
|
+
let runtime: import("../core/types.js").Runtime | undefined;
|
|
117
|
+
const runtimeOverrides = allowedRuntimeOverrides(preset);
|
|
118
|
+
if (runtimeOverrides.length > 0) {
|
|
119
|
+
const runtimeChoice =
|
|
120
|
+
args.runtime ??
|
|
121
|
+
(await p.select({
|
|
122
|
+
message: "Runtime",
|
|
123
|
+
options: [
|
|
124
|
+
...runtimeOverrides.map((rt) => ({ value: rt, label: rt })),
|
|
125
|
+
{ value: "default", label: `Preset default`, hint: "no override" },
|
|
126
|
+
],
|
|
127
|
+
initialValue: "default",
|
|
128
|
+
}));
|
|
129
|
+
|
|
130
|
+
if (p.isCancel(runtimeChoice)) {
|
|
131
|
+
p.cancel("Scaffold cancelled.");
|
|
132
|
+
process.exit(0);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
runtime = runtimeChoice === "default" ? undefined : runtimeChoice;
|
|
136
|
+
}
|
|
137
|
+
|
|
96
138
|
const dbChoice =
|
|
97
139
|
args.db ??
|
|
98
140
|
(await p.select({
|
|
@@ -182,7 +224,9 @@ async function promptInteractiveOptions(args: ParsedCreateArgs): Promise<ParsedC
|
|
|
182
224
|
|
|
183
225
|
return {
|
|
184
226
|
projectName: String(projectName).trim(),
|
|
185
|
-
|
|
227
|
+
framework,
|
|
228
|
+
preset,
|
|
229
|
+
...(runtime !== undefined ? { runtime } : {}),
|
|
186
230
|
yes: args.yes,
|
|
187
231
|
noInstall: args.noInstall,
|
|
188
232
|
json: args.json,
|
|
@@ -207,7 +251,7 @@ export async function runCreateCommand(
|
|
|
207
251
|
: {
|
|
208
252
|
...args,
|
|
209
253
|
projectName: args.projectName?.trim(),
|
|
210
|
-
|
|
254
|
+
preset: args.preset ?? "node-server",
|
|
211
255
|
};
|
|
212
256
|
|
|
213
257
|
if (!resolved.projectName) {
|
|
@@ -268,8 +312,9 @@ export async function runCreateCommand(
|
|
|
268
312
|
|
|
269
313
|
export function buildParsedArgsFromCli(
|
|
270
314
|
values: {
|
|
271
|
-
|
|
315
|
+
preset?: string;
|
|
272
316
|
framework?: string;
|
|
317
|
+
runtime?: string;
|
|
273
318
|
db?: string;
|
|
274
319
|
logger?: string;
|
|
275
320
|
validator?: string;
|
|
@@ -289,9 +334,20 @@ export function buildParsedArgsFromCli(
|
|
|
289
334
|
args.projectName = positionals[0];
|
|
290
335
|
}
|
|
291
336
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
args.
|
|
337
|
+
if (values.preset) {
|
|
338
|
+
const parsed = parsePresetFlag(values.preset);
|
|
339
|
+
args.preset = parsed.preset;
|
|
340
|
+
if (parsed.warning && !args.json) {
|
|
341
|
+
console.warn(`warning: ${parsed.warning}`);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (values.framework) {
|
|
346
|
+
args.framework = parseFrameworkFlag(values.framework);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if (values.runtime) {
|
|
350
|
+
args.runtime = parseRuntimeFlag(values.runtime);
|
|
295
351
|
}
|
|
296
352
|
|
|
297
353
|
if (values.db) {
|
|
@@ -2,20 +2,32 @@ import {
|
|
|
2
2
|
DB_DRIVERS,
|
|
3
3
|
DB_ODMS,
|
|
4
4
|
DEFAULT_DB_DRIVER,
|
|
5
|
+
FRAMEWORKS,
|
|
5
6
|
LOGGERS,
|
|
6
|
-
|
|
7
|
+
RUNTIMES,
|
|
7
8
|
VALIDATORS,
|
|
8
9
|
type DbDriver,
|
|
9
10
|
type DbOdm,
|
|
11
|
+
type DeployTarget,
|
|
12
|
+
type Framework,
|
|
10
13
|
type LoggerId,
|
|
11
|
-
type
|
|
14
|
+
type Runtime,
|
|
12
15
|
type ScaffoldContext,
|
|
13
16
|
type ValidatorId,
|
|
14
17
|
} from "./types.js";
|
|
18
|
+
import {
|
|
19
|
+
DEFAULT_DEPLOY,
|
|
20
|
+
isCuratedDeploy,
|
|
21
|
+
resolveDeployEntry,
|
|
22
|
+
validateCombination,
|
|
23
|
+
} from "./targets.js";
|
|
15
24
|
|
|
16
25
|
export type ParsedCreateArgs = {
|
|
17
26
|
projectName?: string;
|
|
18
|
-
|
|
27
|
+
framework?: Framework;
|
|
28
|
+
/** Deployment target — a Nitro preset id. */
|
|
29
|
+
preset?: string;
|
|
30
|
+
runtime?: Runtime;
|
|
19
31
|
db?: DbOdm;
|
|
20
32
|
driver?: DbDriver;
|
|
21
33
|
logger?: LoggerId;
|
|
@@ -25,8 +37,12 @@ export type ParsedCreateArgs = {
|
|
|
25
37
|
json: boolean;
|
|
26
38
|
};
|
|
27
39
|
|
|
28
|
-
function
|
|
29
|
-
return (
|
|
40
|
+
function isFramework(value: string): value is Framework {
|
|
41
|
+
return (FRAMEWORKS as readonly string[]).includes(value);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function isRuntime(value: string): value is Runtime {
|
|
45
|
+
return (RUNTIMES as readonly string[]).includes(value);
|
|
30
46
|
}
|
|
31
47
|
|
|
32
48
|
function isDbOdm(value: string): value is DbOdm {
|
|
@@ -64,41 +80,33 @@ export function parseDbFlag(value: string): { db: DbOdm; driver: DbDriver } {
|
|
|
64
80
|
return { db: odm, driver };
|
|
65
81
|
}
|
|
66
82
|
|
|
67
|
-
export function
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const logger = args.logger;
|
|
71
|
-
const validator = args.validator;
|
|
72
|
-
|
|
73
|
-
if (!args.projectName) {
|
|
74
|
-
throw new Error("Project name is required");
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const result: ScaffoldContext = {
|
|
78
|
-
projectName: args.projectName.trim(),
|
|
79
|
-
targetDir: "",
|
|
80
|
-
type,
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
if (db) {
|
|
84
|
-
result.db = db;
|
|
85
|
-
result.driver = args.driver ?? DEFAULT_DB_DRIVER;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (logger) {
|
|
89
|
-
result.logger = logger;
|
|
83
|
+
export function parseFrameworkFlag(value: string): Framework {
|
|
84
|
+
if (!isFramework(value)) {
|
|
85
|
+
throw new Error(`Invalid --framework "${value}". Use ${FRAMEWORKS.join(", ")}.`);
|
|
90
86
|
}
|
|
87
|
+
return value;
|
|
88
|
+
}
|
|
91
89
|
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
/**
|
|
91
|
+
* Accepts curated deploy targets verbatim; unknown ids pass through to Nitro.
|
|
92
|
+
* Returns a warning for passthrough ids so callers can surface it.
|
|
93
|
+
*/
|
|
94
|
+
export function parsePresetFlag(value: string): { preset: string; warning?: string } {
|
|
95
|
+
if (!isCuratedDeploy(value)) {
|
|
96
|
+
if (!/^[a-z0-9][a-z0-9-_]*$/i.test(value)) {
|
|
97
|
+
throw new Error(`Invalid --preset "${value}".`);
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
preset: value,
|
|
101
|
+
warning: `"${value}" is not a curated Taser deploy target; passing it through to Nitro as-is.`,
|
|
102
|
+
};
|
|
94
103
|
}
|
|
95
|
-
|
|
96
|
-
return result;
|
|
104
|
+
return { preset: value };
|
|
97
105
|
}
|
|
98
106
|
|
|
99
|
-
export function
|
|
100
|
-
if (!
|
|
101
|
-
throw new Error(`Invalid --
|
|
107
|
+
export function parseRuntimeFlag(value: string): Runtime {
|
|
108
|
+
if (!isRuntime(value)) {
|
|
109
|
+
throw new Error(`Invalid --runtime "${value}". Use node, bun, or deno.`);
|
|
102
110
|
}
|
|
103
111
|
return value;
|
|
104
112
|
}
|
|
@@ -116,3 +124,44 @@ export function parseValidatorFlag(value: string): ValidatorId {
|
|
|
116
124
|
}
|
|
117
125
|
return value;
|
|
118
126
|
}
|
|
127
|
+
|
|
128
|
+
export function resolveScaffoldDefaults(args: ParsedCreateArgs): ScaffoldContext {
|
|
129
|
+
const framework: Framework = args.framework ?? "none";
|
|
130
|
+
const preset = args.preset ?? DEFAULT_DEPLOY;
|
|
131
|
+
|
|
132
|
+
if (!args.projectName) {
|
|
133
|
+
throw new Error("Project name is required");
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Throws with a precise reason when runtime × framework × deploy clash.
|
|
137
|
+
const combination = validateCombination(args.runtime, framework, preset);
|
|
138
|
+
if (!combination.ok) {
|
|
139
|
+
throw new Error(combination.reason);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const result: ScaffoldContext = {
|
|
143
|
+
projectName: args.projectName.trim(),
|
|
144
|
+
targetDir: "",
|
|
145
|
+
framework,
|
|
146
|
+
preset: preset as DeployTarget,
|
|
147
|
+
...(args.runtime !== undefined ? { runtime: args.runtime } : {}),
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
if (args.db) {
|
|
151
|
+
result.db = args.db;
|
|
152
|
+
result.driver = args.driver ?? DEFAULT_DB_DRIVER;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (args.logger) {
|
|
156
|
+
result.logger = args.logger;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (args.validator) {
|
|
160
|
+
result.validator = args.validator;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Re-exported for CLI layers that need to warn about passthrough presets. */
|
|
167
|
+
export { resolveDeployEntry };
|
|
@@ -5,9 +5,14 @@ import type { ScaffoldContext } from "./types.js";
|
|
|
5
5
|
|
|
6
6
|
export async function writeProjectConfig(root: string, ctx: ScaffoldContext): Promise<void> {
|
|
7
7
|
const config: Record<string, string> = {
|
|
8
|
-
|
|
8
|
+
framework: ctx.framework ?? "none",
|
|
9
|
+
preset: ctx.preset ?? "node-server",
|
|
9
10
|
};
|
|
10
11
|
|
|
12
|
+
if (ctx.runtime) {
|
|
13
|
+
config.runtime = ctx.runtime;
|
|
14
|
+
}
|
|
15
|
+
|
|
11
16
|
if (ctx.db) {
|
|
12
17
|
config.db = ctx.db;
|
|
13
18
|
if (ctx.driver) {
|
|
@@ -1,83 +1,52 @@
|
|
|
1
1
|
import { resolveAddons } from "../addons/registry.js";
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
break;
|
|
21
|
-
case "fastify":
|
|
22
|
-
dependencies.push("@taserjs/adapter-fastify", "fastify");
|
|
23
|
-
break;
|
|
24
|
-
case "hono":
|
|
25
|
-
dependencies.push("@hono/node-server", "hono");
|
|
26
|
-
break;
|
|
2
|
+
import { FRAMEWORK_ENTRIES } from "../frameworks/index.js";
|
|
3
|
+
import type { PackageGroups, ScaffoldContext } from "../core/types.js";
|
|
4
|
+
import { resolveDeployEntry } from "./targets.js";
|
|
5
|
+
|
|
6
|
+
const BASE_DEPENDENCIES = ["@taserjs/router", "dotenv"];
|
|
7
|
+
|
|
8
|
+
/** Runtime-agnostic build/dev tooling every scaffolded project needs. */
|
|
9
|
+
const BASE_DEV_DEPENDENCIES = [
|
|
10
|
+
"@taserjs/router-plugin",
|
|
11
|
+
"nitro",
|
|
12
|
+
"typescript@^5.9.3",
|
|
13
|
+
"vite@^8.1.5",
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
function runtimeDevDeps(ctx: ScaffoldContext): string[] {
|
|
17
|
+
const { entry } = resolveDeployEntry(ctx.preset ?? "node-server");
|
|
18
|
+
const effective = ctx.runtime ?? entry.impliedRuntime;
|
|
19
|
+
switch (effective) {
|
|
27
20
|
case "bun":
|
|
28
|
-
|
|
29
|
-
devDependencies.push("@types/bun");
|
|
30
|
-
scripts["dev:server"] = "bun --watch src/index.ts";
|
|
31
|
-
scripts.start = "bun src/index.ts";
|
|
32
|
-
scripts.serve = "bun dist/index.mjs";
|
|
33
|
-
break;
|
|
21
|
+
return ["@types/bun"];
|
|
34
22
|
case "deno":
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
break;
|
|
39
|
-
case "aws-lambda":
|
|
40
|
-
dependencies.push("hono");
|
|
41
|
-
devDependencies.push("@types/aws-lambda");
|
|
42
|
-
break;
|
|
43
|
-
case "cloudflare-workers": {
|
|
44
|
-
// Cloudflare workers uses wrangler
|
|
45
|
-
const cfDevDeps = devDependencies.filter((d) => d !== "tsx");
|
|
46
|
-
cfDevDeps.push("wrangler", "@cloudflare/workers-types");
|
|
47
|
-
devDependencies.length = 0;
|
|
48
|
-
devDependencies.push(...cfDevDeps);
|
|
49
|
-
scripts["dev:server"] = "wrangler dev";
|
|
50
|
-
scripts.deploy = "wrangler deploy";
|
|
51
|
-
break;
|
|
52
|
-
}
|
|
53
|
-
case "netlify":
|
|
54
|
-
dependencies.push("hono", "@netlify/functions");
|
|
55
|
-
break;
|
|
56
|
-
case "vercel":
|
|
57
|
-
dependencies.push("hono");
|
|
58
|
-
devDependencies.push("@vercel/node");
|
|
59
|
-
break;
|
|
60
|
-
case "azure-functions":
|
|
61
|
-
dependencies.push("hono", "@azure/functions", "@marplex/hono-azurefunc-adapter");
|
|
62
|
-
break;
|
|
63
|
-
case "google-cloud-run":
|
|
23
|
+
return []; // Deno ships its own tooling and types.
|
|
24
|
+
case "workerd":
|
|
25
|
+
return ["@cloudflare/workers-types"];
|
|
64
26
|
case "node":
|
|
65
27
|
default:
|
|
66
|
-
|
|
67
|
-
break;
|
|
28
|
+
return ["@types/node"];
|
|
68
29
|
}
|
|
69
|
-
|
|
70
|
-
return { dependencies, devDependencies, scripts };
|
|
71
30
|
}
|
|
72
31
|
|
|
73
32
|
export function resolvePackages(ctx: ScaffoldContext): PackageGroups {
|
|
74
|
-
const
|
|
75
|
-
const
|
|
33
|
+
const frameworkEntry = FRAMEWORK_ENTRIES[ctx.framework ?? "none"];
|
|
34
|
+
const { entry: deployEntry } = resolveDeployEntry(ctx.preset ?? "node-server");
|
|
76
35
|
|
|
77
|
-
const dependencies = [...
|
|
78
|
-
const devDependencies = [
|
|
79
|
-
|
|
36
|
+
const dependencies = [...BASE_DEPENDENCIES, ...frameworkEntry.deps];
|
|
37
|
+
const devDependencies = [
|
|
38
|
+
...BASE_DEV_DEPENDENCIES,
|
|
39
|
+
...runtimeDevDeps(ctx),
|
|
40
|
+
...deployEntry.devDeps,
|
|
41
|
+
...frameworkEntry.devDeps,
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
const scripts: Record<string, string> = {};
|
|
45
|
+
if (deployEntry.startScript) {
|
|
46
|
+
scripts.start = deployEntry.startScript;
|
|
47
|
+
}
|
|
80
48
|
|
|
49
|
+
const addons = resolveAddons(ctx);
|
|
81
50
|
for (const addon of addons) {
|
|
82
51
|
dependencies.push(...addon.dependencies(ctx));
|
|
83
52
|
devDependencies.push(...addon.devDependencies(ctx));
|
|
@@ -92,10 +61,3 @@ export function resolvePackages(ctx: ScaffoldContext): PackageGroups {
|
|
|
92
61
|
scripts,
|
|
93
62
|
};
|
|
94
63
|
}
|
|
95
|
-
|
|
96
|
-
export function getPackageGroups(
|
|
97
|
-
type: ProjectType,
|
|
98
|
-
): Omit<PackageGroups, "scripts"> & { scripts?: Record<string, string> } {
|
|
99
|
-
const groups = typePackages(type);
|
|
100
|
-
return groups;
|
|
101
|
-
}
|