create-taserjs 0.0.6 → 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 -1
- 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 +16 -27
- 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 +75 -174
- 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 -2
- 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 +18 -29
- 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 +72 -174
- 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 -2
- 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 +41 -65
- package/src/core/targets.ts +202 -0
- package/src/core/types.ts +38 -24
- package/src/frameworks/index.ts +74 -182
- package/src/scaffold.ts +2 -2
- package/src/templates/base.ts +14 -98
- package/src/types.ts +3 -1
|
@@ -5,25 +5,22 @@ var IMPORT_LINES = {
|
|
|
5
5
|
valibot: `import * as v from 'valibot'`
|
|
6
6
|
};
|
|
7
7
|
var VALIDATION_BLOCK_TEMPLATE = {
|
|
8
|
-
zod:
|
|
9
|
-
query
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
valibot: `, {
|
|
15
|
-
query: v.object({ name: v.optional(v.string(), 'Taser') }),
|
|
16
|
-
}`
|
|
8
|
+
zod: `
|
|
9
|
+
.query(z.object({ name: z.string().default('Taser') }))`,
|
|
10
|
+
arktype: `
|
|
11
|
+
.query(type({ 'name?': 'string = "Taser"' }))`,
|
|
12
|
+
valibot: `
|
|
13
|
+
.query(v.object({ name: v.optional(v.string(), 'Taser') }))`
|
|
17
14
|
};
|
|
18
|
-
var ROUTE_TEMPLATE = (validator) => `import {
|
|
19
|
-
import { t } from '#
|
|
15
|
+
var ROUTE_TEMPLATE = (validator) => `import { json } from '@taserjs/router/reply'
|
|
16
|
+
import { t } from '#taserjs/router'
|
|
20
17
|
${IMPORT_LINES[validator]}
|
|
21
18
|
|
|
22
|
-
const GET = t.get('/'${VALIDATION_BLOCK_TEMPLATE[validator]}
|
|
19
|
+
const GET = t.get('/')${VALIDATION_BLOCK_TEMPLATE[validator]}
|
|
23
20
|
|
|
24
21
|
export type RouteContext = typeof GET.$Infer.Context
|
|
25
22
|
export const Route = GET.handler((ctx) => {
|
|
26
|
-
return
|
|
23
|
+
return json({ message: \`Hello, \${ctx.query.name}!\` })
|
|
27
24
|
})
|
|
28
25
|
`;
|
|
29
26
|
var ValidatorAddon = (validator) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validators.js","names":[],"sources":["../../../src/addons/validators.ts"],"sourcesContent":["import type { ValidatorId } from \"../core/types\";\nimport type { AddonDefinition } from \"./types\";\n\nexport const IMPORT_LINES: Record<ValidatorId, string> = {\n zod: `import { z } from 'zod'`,\n arktype: `import { type } from 'arktype'`,\n valibot: `import * as v from 'valibot'`,\n};\n\nexport const VALIDATION_BLOCK_TEMPLATE: Record<ValidatorId, string> = {\n zod:
|
|
1
|
+
{"version":3,"file":"validators.js","names":[],"sources":["../../../src/addons/validators.ts"],"sourcesContent":["import type { ValidatorId } from \"../core/types\";\nimport type { AddonDefinition } from \"./types\";\n\nexport const IMPORT_LINES: Record<ValidatorId, string> = {\n zod: `import { z } from 'zod'`,\n arktype: `import { type } from 'arktype'`,\n valibot: `import * as v from 'valibot'`,\n};\n\nexport const VALIDATION_BLOCK_TEMPLATE: Record<ValidatorId, string> = {\n zod: `\n .query(z.object({ name: z.string().default('Taser') }))`,\n arktype: `\n .query(type({ 'name?': 'string = \"Taser\"' }))`,\n valibot: `\n .query(v.object({ name: v.optional(v.string(), 'Taser') }))`,\n};\n\nconst ROUTE_TEMPLATE = (validator: ValidatorId) => `import { json } from '@taserjs/router/reply'\nimport { t } from '#taserjs/router'\n${IMPORT_LINES[validator]}\n\nconst GET = t.get('/')${VALIDATION_BLOCK_TEMPLATE[validator]}\n\nexport type RouteContext = typeof GET.$Infer.Context\nexport const Route = GET.handler((ctx) => {\n return json({ message: \\`Hello, \\${ctx.query.name}!\\` })\n})\n`;\n\nexport const ValidatorAddon = (validator: ValidatorId): AddonDefinition => {\n return {\n id: validator,\n category: \"validator\",\n dependencies: () => [validator],\n devDependencies: () => [],\n apply: (ctx, write) => write(\"src/routes/index.get.ts\", ROUTE_TEMPLATE(validator)),\n };\n};\n"],"mappings":";AAGA,IAAa,eAA4C;CACvD,KAAK;CACL,SAAS;CACT,SAAS;AACX;AAEA,IAAa,4BAAyD;CACpE,KAAK;;CAEL,SAAS;;CAET,SAAS;;AAEX;AAEA,IAAM,kBAAkB,cAA2B;;EAEjD,aAAa,WAAW;;wBAEF,0BAA0B,WAAW;;;;;;;AAQ7D,IAAa,kBAAkB,cAA4C;CACzE,OAAO;EACL,IAAI;EACJ,UAAU;EACV,oBAAoB,CAAC,SAAS;EAC9B,uBAAuB,CAAC;EACxB,QAAQ,KAAK,UAAU,MAAM,2BAA2B,eAAe,SAAS,CAAC;CACnF;AACF"}
|
package/dist/esm/cli.js
CHANGED
|
@@ -9,14 +9,15 @@ async function main() {
|
|
|
9
9
|
const { values, positionals } = parseArgs({
|
|
10
10
|
args: process.argv.slice(2),
|
|
11
11
|
options: {
|
|
12
|
-
|
|
12
|
+
preset: {
|
|
13
13
|
type: "string",
|
|
14
|
-
short: "
|
|
14
|
+
short: "p"
|
|
15
15
|
},
|
|
16
|
-
framework: { type: "string" },
|
|
17
16
|
db: { type: "string" },
|
|
18
17
|
logger: { type: "string" },
|
|
19
18
|
validator: { type: "string" },
|
|
19
|
+
framework: { type: "string" },
|
|
20
|
+
runtime: { type: "string" },
|
|
20
21
|
y: {
|
|
21
22
|
type: "boolean",
|
|
22
23
|
short: "y"
|
|
@@ -27,11 +28,12 @@ async function main() {
|
|
|
27
28
|
allowPositionals: true
|
|
28
29
|
});
|
|
29
30
|
const parsed = buildParsedArgsFromCli({
|
|
30
|
-
...values.
|
|
31
|
-
...values.framework !== void 0 ? { framework: values.framework } : {},
|
|
31
|
+
...values.preset !== void 0 ? { preset: values.preset } : {},
|
|
32
32
|
...values.db !== void 0 ? { db: values.db } : {},
|
|
33
33
|
...values.logger !== void 0 ? { logger: values.logger } : {},
|
|
34
34
|
...values.validator !== void 0 ? { validator: values.validator } : {},
|
|
35
|
+
...values.framework !== void 0 ? { framework: values.framework } : {},
|
|
36
|
+
...values.runtime !== void 0 ? { runtime: values.runtime } : {},
|
|
35
37
|
...values.y !== void 0 ? { y: values.y } : {},
|
|
36
38
|
...values.noInstall !== void 0 ? { noInstall: values.noInstall } : {},
|
|
37
39
|
...values.json !== void 0 ? { json: values.json } : {}
|
package/dist/esm/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","names":[],"sources":["../../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { parseArgs } from \"node:util\";\n\nimport * as p from \"@clack/prompts\";\nimport color from \"picocolors\";\n\nimport { buildParsedArgsFromCli, runCreateCommand } from \"./commands/create.js\";\nimport { printJsonError } from \"./core/json-output.js\";\n\nasync function main(): Promise<void> {\n const { values, positionals } = parseArgs({\n args: process.argv.slice(2),\n options: {\n
|
|
1
|
+
{"version":3,"file":"cli.js","names":[],"sources":["../../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { parseArgs } from \"node:util\";\n\nimport * as p from \"@clack/prompts\";\nimport color from \"picocolors\";\n\nimport { buildParsedArgsFromCli, runCreateCommand } from \"./commands/create.js\";\nimport { printJsonError } from \"./core/json-output.js\";\n\nasync function main(): Promise<void> {\n const { values, positionals } = parseArgs({\n args: process.argv.slice(2),\n options: {\n preset: { type: \"string\", short: \"p\" },\n db: { type: \"string\" },\n logger: { type: \"string\" },\n validator: { type: \"string\" },\n framework: { type: \"string\" },\n runtime: { type: \"string\" },\n y: { type: \"boolean\", short: \"y\" },\n noInstall: { type: \"boolean\" },\n json: { type: \"boolean\" },\n },\n allowPositionals: true,\n });\n\n const parsed = buildParsedArgsFromCli(\n {\n ...(values.preset !== undefined ? { preset: values.preset } : {}),\n ...(values.db !== undefined ? { db: values.db } : {}),\n ...(values.logger !== undefined ? { logger: values.logger } : {}),\n ...(values.validator !== undefined ? { validator: values.validator } : {}),\n ...(values.framework !== undefined ? { framework: values.framework } : {}),\n ...(values.runtime !== undefined ? { runtime: values.runtime } : {}),\n ...(values.y !== undefined ? { y: values.y } : {}),\n ...(values.noInstall !== undefined ? { noInstall: values.noInstall } : {}),\n ...(values.json !== undefined ? { json: values.json } : {}),\n },\n positionals,\n );\n\n if (!parsed.json) {\n console.clear();\n p.intro(color.bgCyan(color.black(\" create-taser \")));\n }\n\n try {\n await runCreateCommand(parsed);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (parsed.json) {\n printJsonError(message);\n process.exit(1);\n }\n throw error;\n }\n}\n\nmain().catch((error: unknown) => {\n console.error(error);\n process.exit(1);\n});\n"],"mappings":";;;;;;;AASA,eAAe,OAAsB;CACnC,MAAM,EAAE,QAAQ,gBAAgB,UAAU;EACxC,MAAM,QAAQ,KAAK,MAAM,CAAC;EAC1B,SAAS;GACP,QAAQ;IAAE,MAAM;IAAU,OAAO;GAAI;GACrC,IAAI,EAAE,MAAM,SAAS;GACrB,QAAQ,EAAE,MAAM,SAAS;GACzB,WAAW,EAAE,MAAM,SAAS;GAC5B,WAAW,EAAE,MAAM,SAAS;GAC5B,SAAS,EAAE,MAAM,SAAS;GAC1B,GAAG;IAAE,MAAM;IAAW,OAAO;GAAI;GACjC,WAAW,EAAE,MAAM,UAAU;GAC7B,MAAM,EAAE,MAAM,UAAU;EAC1B;EACA,kBAAkB;CACpB,CAAC;CAED,MAAM,SAAS,uBACb;EACE,GAAI,OAAO,WAAW,KAAA,IAAY,EAAE,QAAQ,OAAO,OAAO,IAAI,CAAC;EAC/D,GAAI,OAAO,OAAO,KAAA,IAAY,EAAE,IAAI,OAAO,GAAG,IAAI,CAAC;EACnD,GAAI,OAAO,WAAW,KAAA,IAAY,EAAE,QAAQ,OAAO,OAAO,IAAI,CAAC;EAC/D,GAAI,OAAO,cAAc,KAAA,IAAY,EAAE,WAAW,OAAO,UAAU,IAAI,CAAC;EACxE,GAAI,OAAO,cAAc,KAAA,IAAY,EAAE,WAAW,OAAO,UAAU,IAAI,CAAC;EACxE,GAAI,OAAO,YAAY,KAAA,IAAY,EAAE,SAAS,OAAO,QAAQ,IAAI,CAAC;EAClE,GAAI,OAAO,MAAM,KAAA,IAAY,EAAE,GAAG,OAAO,EAAE,IAAI,CAAC;EAChD,GAAI,OAAO,cAAc,KAAA,IAAY,EAAE,WAAW,OAAO,UAAU,IAAI,CAAC;EACxE,GAAI,OAAO,SAAS,KAAA,IAAY,EAAE,MAAM,OAAO,KAAK,IAAI,CAAC;CAC3D,GACA,WACF;CAEA,IAAI,CAAC,OAAO,MAAM;EAChB,QAAQ,MAAM;EACd,EAAE,MAAM,MAAM,OAAO,MAAM,MAAM,gBAAgB,CAAC,CAAC;CACrD;CAEA,IAAI;EACF,MAAM,iBAAiB,MAAM;CAC/B,SAAS,OAAO;EACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EACrE,IAAI,OAAO,MAAM;GACf,eAAe,OAAO;GACtB,QAAQ,KAAK,CAAC;EAChB;EACA,MAAM;CACR;AACF;AAEA,KAAK,CAAC,CAAC,OAAO,UAAmB;CAC/B,QAAQ,MAAM,KAAK;CACnB,QAAQ,KAAK,CAAC;AAChB,CAAC"}
|
|
@@ -2,8 +2,9 @@ import { ParsedCreateArgs } from '../core/parse-options.js';
|
|
|
2
2
|
import { ScaffoldResult } from '../core/types.js';
|
|
3
3
|
export declare function runCreateCommand(args: ParsedCreateArgs): Promise<ScaffoldResult | undefined>;
|
|
4
4
|
export declare function buildParsedArgsFromCli(values: {
|
|
5
|
-
|
|
5
|
+
preset?: string;
|
|
6
6
|
framework?: string;
|
|
7
|
+
runtime?: string;
|
|
7
8
|
db?: string;
|
|
8
9
|
logger?: string;
|
|
9
10
|
validator?: string;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { DB_DRIVERS, DB_ODMS,
|
|
1
|
+
import { DB_DRIVERS, DB_ODMS, DEPLOY_TARGETS, LOGGERS, VALIDATORS } from "../core/types.js";
|
|
2
2
|
import { getCapabilitiesCatalog } from "../addons/registry.js";
|
|
3
3
|
import { printCapabilitiesCatalog, printJsonError, printScaffoldResult } from "../core/json-output.js";
|
|
4
|
-
import {
|
|
4
|
+
import { allowedRuntimeOverrides } from "../core/targets.js";
|
|
5
|
+
import { parseDbFlag, parseFrameworkFlag, parseLoggerFlag, parsePresetFlag, parseRuntimeFlag, parseValidatorFlag, resolveScaffoldDefaults } from "../core/parse-options.js";
|
|
5
6
|
import { resolveUserAgent, runScript } from "../core/package-manager.js";
|
|
6
7
|
import { scaffoldProject } from "../core/scaffold-engine.js";
|
|
7
8
|
import { validateProjectName } from "../core/validate-project-name.js";
|
|
@@ -9,8 +10,8 @@ import * as p from "@clack/prompts";
|
|
|
9
10
|
import color from "picocolors";
|
|
10
11
|
import path from "node:path";
|
|
11
12
|
//#region src/commands/create.ts
|
|
12
|
-
function
|
|
13
|
-
return typeof value === "string" &&
|
|
13
|
+
function isDeployTarget(value) {
|
|
14
|
+
return typeof value === "string" && DEPLOY_TARGETS.includes(value);
|
|
14
15
|
}
|
|
15
16
|
function isDbOdm(value) {
|
|
16
17
|
return typeof value === "string" && DB_ODMS.includes(value);
|
|
@@ -37,65 +38,77 @@ async function promptInteractiveOptions(args) {
|
|
|
37
38
|
p.cancel("Scaffold cancelled.");
|
|
38
39
|
process.exit(0);
|
|
39
40
|
}
|
|
40
|
-
const
|
|
41
|
-
message: "
|
|
41
|
+
const framework = args.framework ?? await p.select({
|
|
42
|
+
message: "Host framework",
|
|
42
43
|
options: [
|
|
43
44
|
{
|
|
44
|
-
value: "
|
|
45
|
-
label: "
|
|
45
|
+
value: "none",
|
|
46
|
+
label: "Pure Taser",
|
|
46
47
|
hint: "default"
|
|
47
48
|
},
|
|
48
|
-
{
|
|
49
|
-
value: "express",
|
|
50
|
-
label: "Express"
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
value: "fastify",
|
|
54
|
-
label: "Fastify"
|
|
55
|
-
},
|
|
56
49
|
{
|
|
57
50
|
value: "hono",
|
|
58
51
|
label: "Hono"
|
|
59
52
|
},
|
|
60
53
|
{
|
|
61
|
-
value: "
|
|
62
|
-
label: "
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
value: "deno",
|
|
66
|
-
label: "Deno"
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
value: "aws-lambda",
|
|
70
|
-
label: "AWS Lambda"
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
value: "cloudflare-workers",
|
|
74
|
-
label: "Cloudflare Workers"
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
value: "netlify",
|
|
78
|
-
label: "Netlify"
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
value: "vercel",
|
|
82
|
-
label: "Vercel"
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
value: "azure-functions",
|
|
86
|
-
label: "Azure Functions"
|
|
54
|
+
value: "express",
|
|
55
|
+
label: "Express"
|
|
87
56
|
},
|
|
88
57
|
{
|
|
89
|
-
value: "
|
|
90
|
-
label: "
|
|
58
|
+
value: "fastify",
|
|
59
|
+
label: "Fastify"
|
|
91
60
|
}
|
|
92
61
|
],
|
|
93
|
-
initialValue: "
|
|
62
|
+
initialValue: "none"
|
|
63
|
+
});
|
|
64
|
+
if (p.isCancel(framework)) {
|
|
65
|
+
p.cancel("Scaffold cancelled.");
|
|
66
|
+
process.exit(0);
|
|
67
|
+
}
|
|
68
|
+
const DEPLOY_LABELS = {
|
|
69
|
+
"node-server": "Node.js server",
|
|
70
|
+
"node-cluster": "Node.js cluster",
|
|
71
|
+
bun: "Bun",
|
|
72
|
+
"deno-server": "Deno",
|
|
73
|
+
"deno-deploy": "Deno Deploy",
|
|
74
|
+
"cloudflare-module": "Cloudflare Workers",
|
|
75
|
+
vercel: "Vercel",
|
|
76
|
+
"aws-lambda": "AWS Lambda",
|
|
77
|
+
netlify: "Netlify"
|
|
78
|
+
};
|
|
79
|
+
const preset = args.preset ?? await p.select({
|
|
80
|
+
message: "Deployment target",
|
|
81
|
+
options: DEPLOY_TARGETS.map((id) => ({
|
|
82
|
+
value: id,
|
|
83
|
+
label: DEPLOY_LABELS[id]
|
|
84
|
+
})),
|
|
85
|
+
initialValue: "node-server"
|
|
94
86
|
});
|
|
95
|
-
if (p.isCancel(
|
|
87
|
+
if (p.isCancel(preset) || !isDeployTarget(preset)) {
|
|
96
88
|
p.cancel("Scaffold cancelled.");
|
|
97
89
|
process.exit(0);
|
|
98
90
|
}
|
|
91
|
+
let runtime;
|
|
92
|
+
const runtimeOverrides = allowedRuntimeOverrides(preset);
|
|
93
|
+
if (runtimeOverrides.length > 0) {
|
|
94
|
+
const runtimeChoice = args.runtime ?? await p.select({
|
|
95
|
+
message: "Runtime",
|
|
96
|
+
options: [...runtimeOverrides.map((rt) => ({
|
|
97
|
+
value: rt,
|
|
98
|
+
label: rt
|
|
99
|
+
})), {
|
|
100
|
+
value: "default",
|
|
101
|
+
label: `Preset default`,
|
|
102
|
+
hint: "no override"
|
|
103
|
+
}],
|
|
104
|
+
initialValue: "default"
|
|
105
|
+
});
|
|
106
|
+
if (p.isCancel(runtimeChoice)) {
|
|
107
|
+
p.cancel("Scaffold cancelled.");
|
|
108
|
+
process.exit(0);
|
|
109
|
+
}
|
|
110
|
+
runtime = runtimeChoice === "default" ? void 0 : runtimeChoice;
|
|
111
|
+
}
|
|
99
112
|
const dbChoice = args.db ?? await p.select({
|
|
100
113
|
message: "Database",
|
|
101
114
|
options: [
|
|
@@ -206,7 +219,9 @@ async function promptInteractiveOptions(args) {
|
|
|
206
219
|
const validator = validatorChoice === "none" ? void 0 : isValidatorId(validatorChoice) ? validatorChoice : void 0;
|
|
207
220
|
return {
|
|
208
221
|
projectName: String(projectName).trim(),
|
|
209
|
-
|
|
222
|
+
framework,
|
|
223
|
+
preset,
|
|
224
|
+
...runtime !== void 0 ? { runtime } : {},
|
|
210
225
|
yes: args.yes,
|
|
211
226
|
noInstall: args.noInstall,
|
|
212
227
|
json: args.json,
|
|
@@ -227,7 +242,7 @@ async function runCreateCommand(args) {
|
|
|
227
242
|
const resolved = !args.yes ? await promptInteractiveOptions(args) : {
|
|
228
243
|
...args,
|
|
229
244
|
projectName: args.projectName?.trim(),
|
|
230
|
-
|
|
245
|
+
preset: args.preset ?? "node-server"
|
|
231
246
|
};
|
|
232
247
|
if (!resolved.projectName) {
|
|
233
248
|
const message = "Project name is required";
|
|
@@ -287,8 +302,13 @@ function buildParsedArgsFromCli(values, positionals) {
|
|
|
287
302
|
json: values.json ?? false
|
|
288
303
|
};
|
|
289
304
|
if (positionals[0]) args.projectName = positionals[0];
|
|
290
|
-
|
|
291
|
-
|
|
305
|
+
if (values.preset) {
|
|
306
|
+
const parsed = parsePresetFlag(values.preset);
|
|
307
|
+
args.preset = parsed.preset;
|
|
308
|
+
if (parsed.warning && !args.json) console.warn(`warning: ${parsed.warning}`);
|
|
309
|
+
}
|
|
310
|
+
if (values.framework) args.framework = parseFrameworkFlag(values.framework);
|
|
311
|
+
if (values.runtime) args.runtime = parseRuntimeFlag(values.runtime);
|
|
292
312
|
if (values.db) {
|
|
293
313
|
const parsed = parseDbFlag(values.db);
|
|
294
314
|
args.db = parsed.db;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","names":[],"sources":["../../../src/commands/create.ts"],"sourcesContent":["import path from \"node:path\";\n\nimport * as p from \"@clack/prompts\";\nimport color from \"picocolors\";\n\nimport { getCapabilitiesCatalog } from \"../addons/registry.js\";\nimport {\n printCapabilitiesCatalog,\n printJsonError,\n printScaffoldResult,\n} from \"../core/json-output.js\";\nimport {\n parseDbFlag,\n parseLoggerFlag,\n parseTypeFlag,\n parseValidatorFlag,\n type ParsedCreateArgs,\n resolveScaffoldDefaults,\n} from \"../core/parse-options.js\";\nimport { scaffoldProject } from \"../core/scaffold-engine.js\";\nimport type {\n DbDriver,\n DbOdm,\n LoggerId,\n ProjectType,\n ScaffoldResult,\n ValidatorId,\n} from \"../core/types.js\";\nimport { DB_DRIVERS, DB_ODMS, LOGGERS, PROJECT_TYPES, VALIDATORS } from \"../core/types.js\";\nimport { validateProjectName } from \"../core/validate-project-name.js\";\nimport { resolveUserAgent, runScript } from \"../core/package-manager.js\";\n\nfunction isProjectType(value: unknown): value is ProjectType {\n return typeof value === \"string\" && (PROJECT_TYPES as readonly string[]).includes(value);\n}\n\nfunction isDbOdm(value: unknown): value is DbOdm {\n return typeof value === \"string\" && (DB_ODMS as readonly string[]).includes(value);\n}\n\nfunction isDbDriver(value: unknown): value is DbDriver {\n return typeof value === \"string\" && (DB_DRIVERS as readonly string[]).includes(value);\n}\n\nfunction isLoggerId(value: unknown): value is LoggerId {\n return typeof value === \"string\" && (LOGGERS as readonly string[]).includes(value);\n}\n\nfunction isValidatorId(value: unknown): value is ValidatorId {\n return typeof value === \"string\" && (VALIDATORS as readonly string[]).includes(value);\n}\n\nasync function promptInteractiveOptions(args: ParsedCreateArgs): Promise<ParsedCreateArgs> {\n const projectName =\n args.projectName ??\n (await p.text({\n message: \"Project name\",\n placeholder: \"my-taser-app\",\n defaultValue: \"my-taser-app\",\n validate(value) {\n return validateProjectName(value);\n },\n }));\n\n if (p.isCancel(projectName)) {\n p.cancel(\"Scaffold cancelled.\");\n process.exit(0);\n }\n\n const type =\n args.type ??\n (await p.select({\n message: \"Project type (runtime / framework)\",\n options: [\n { value: \"node\", label: \"Node.js\", hint: \"default\" },\n { value: \"express\", label: \"Express\" },\n { value: \"fastify\", label: \"Fastify\" },\n { value: \"hono\", label: \"Hono\" },\n { value: \"bun\", label: \"Bun\" },\n { value: \"deno\", label: \"Deno\" },\n { value: \"aws-lambda\", label: \"AWS Lambda\" },\n { value: \"cloudflare-workers\", label: \"Cloudflare Workers\" },\n { value: \"netlify\", label: \"Netlify\" },\n { value: \"vercel\", label: \"Vercel\" },\n { value: \"azure-functions\", label: \"Azure Functions\" },\n { value: \"google-cloud-run\", label: \"Google Cloud Run\" },\n ],\n initialValue: \"node\",\n }));\n\n if (p.isCancel(type) || !isProjectType(type)) {\n p.cancel(\"Scaffold cancelled.\");\n process.exit(0);\n }\n\n const dbChoice =\n args.db ??\n (await p.select({\n message: \"Database\",\n options: [\n { value: \"none\", label: \"None\", hint: \"default\" },\n { value: \"drizzle\", label: \"Drizzle\" },\n { value: \"prisma\", label: \"Prisma\" },\n { value: \"kysely\", label: \"Kysely\" },\n ],\n initialValue: \"none\",\n }));\n\n if (p.isCancel(dbChoice)) {\n p.cancel(\"Scaffold cancelled.\");\n process.exit(0);\n }\n\n let db: DbOdm | undefined;\n let driver: DbDriver | undefined;\n\n if (dbChoice !== \"none\" && isDbOdm(dbChoice)) {\n db = dbChoice;\n const driverChoice =\n args.driver ??\n (await p.select({\n message: \"Database driver\",\n options: [\n { value: \"sqlite\", label: \"SQLite\", hint: \"default\" },\n { value: \"postgres\", label: \"PostgreSQL\" },\n { value: \"mysql\", label: \"MySQL\" },\n ],\n initialValue: \"sqlite\",\n }));\n\n if (p.isCancel(driverChoice) || !isDbDriver(driverChoice)) {\n p.cancel(\"Scaffold cancelled.\");\n process.exit(0);\n }\n driver = driverChoice;\n }\n\n const loggerChoice =\n args.logger ??\n (await p.select({\n message: \"Logger\",\n options: [\n { value: \"none\", label: \"None\", hint: \"default\" },\n { value: \"pino\", label: \"Pino\" },\n { value: \"winston\", label: \"Winston\" },\n ],\n initialValue: \"none\",\n }));\n\n if (p.isCancel(loggerChoice)) {\n p.cancel(\"Scaffold cancelled.\");\n process.exit(0);\n }\n\n const logger =\n loggerChoice === \"none\" ? undefined : isLoggerId(loggerChoice) ? loggerChoice : undefined;\n\n const validatorChoice =\n args.validator ??\n (await p.select({\n message: \"Validator\",\n options: [\n { value: \"none\", label: \"None\", hint: \"default\" },\n { value: \"zod\", label: \"Zod\" },\n { value: \"arktype\", label: \"Arktype\" },\n { value: \"valibot\", label: \"Valibot\" },\n ],\n initialValue: \"none\",\n }));\n\n if (p.isCancel(validatorChoice)) {\n p.cancel(\"Scaffold cancelled.\");\n process.exit(0);\n }\n\n const validator =\n validatorChoice === \"none\"\n ? undefined\n : isValidatorId(validatorChoice)\n ? validatorChoice\n : undefined;\n\n return {\n projectName: String(projectName).trim(),\n type,\n yes: args.yes,\n noInstall: args.noInstall,\n json: args.json,\n ...(db ? { db, driver: driver! } : {}),\n ...(logger ? { logger } : {}),\n ...(validator ? { validator } : {}),\n };\n}\n\nexport async function runCreateCommand(\n args: ParsedCreateArgs,\n): Promise<ScaffoldResult | undefined> {\n if (args.json && !args.projectName) {\n printCapabilitiesCatalog(getCapabilitiesCatalog());\n return undefined;\n }\n\n const cwd = process.cwd();\n const interactive = !args.yes;\n const resolved = interactive\n ? await promptInteractiveOptions(args)\n : {\n ...args,\n projectName: args.projectName?.trim(),\n type: args.type ?? \"node\",\n };\n\n if (!resolved.projectName) {\n const message = \"Project name is required\";\n if (args.json) {\n printJsonError(message);\n process.exit(1);\n }\n throw new Error(message);\n }\n\n const nameError = validateProjectName(resolved.projectName, cwd);\n if (nameError) {\n if (args.json) {\n printJsonError(nameError);\n process.exit(1);\n }\n throw new Error(nameError);\n }\n\n const targetDir = path.resolve(cwd, resolved.projectName);\n const scaffoldCtx = resolveScaffoldDefaults({\n ...resolved,\n projectName: resolved.projectName,\n });\n scaffoldCtx.targetDir = targetDir;\n\n if (!args.json) {\n const spinner = p.spinner();\n spinner.start(\"Scaffolding project\");\n try {\n const result = await scaffoldProject({\n ...scaffoldCtx,\n targetDir,\n skipInstall: args.noInstall,\n agent: resolveUserAgent(),\n });\n spinner.stop(\"Project created\");\n const cdPath = path.relative(cwd, targetDir) || \".\";\n p.note([`cd ${cdPath}`, runScript(resolveUserAgent(), \"dev\")].join(\"\\n\"), \"Next steps\");\n p.outro(color.green(\"Done.\"));\n return result;\n } catch (error) {\n spinner.stop(\"Scaffold failed\");\n throw error;\n }\n }\n\n const result = await scaffoldProject({\n ...scaffoldCtx,\n targetDir,\n skipInstall: args.noInstall,\n agent: resolveUserAgent(),\n });\n printScaffoldResult(result);\n return result;\n}\n\nexport function buildParsedArgsFromCli(\n values: {\n type?: string;\n framework?: string;\n db?: string;\n logger?: string;\n validator?: string;\n y?: boolean;\n noInstall?: boolean;\n json?: boolean;\n },\n positionals: string[],\n): ParsedCreateArgs {\n const args: ParsedCreateArgs = {\n yes: values.y ?? false,\n noInstall: values.noInstall ?? false,\n json: values.json ?? false,\n };\n\n if (positionals[0]) {\n args.projectName = positionals[0];\n }\n\n const typeFlag = values.type ?? values.framework;\n if (typeFlag) {\n args.type = parseTypeFlag(typeFlag);\n }\n\n if (values.db) {\n const parsed = parseDbFlag(values.db);\n args.db = parsed.db;\n args.driver = parsed.driver;\n }\n\n if (values.logger) {\n args.logger = parseLoggerFlag(values.logger);\n }\n\n if (values.validator) {\n args.validator = parseValidatorFlag(values.validator);\n }\n\n return args;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"create.js","names":[],"sources":["../../../src/commands/create.ts"],"sourcesContent":["import path from \"node:path\";\n\nimport * as p from \"@clack/prompts\";\nimport color from \"picocolors\";\n\nimport { getCapabilitiesCatalog } from \"../addons/registry.js\";\nimport {\n printCapabilitiesCatalog,\n printJsonError,\n printScaffoldResult,\n} from \"../core/json-output.js\";\nimport {\n parseDbFlag,\n parseFrameworkFlag,\n parseLoggerFlag,\n parsePresetFlag,\n parseRuntimeFlag,\n parseValidatorFlag,\n type ParsedCreateArgs,\n resolveScaffoldDefaults,\n} from \"../core/parse-options.js\";\nimport { scaffoldProject } from \"../core/scaffold-engine.js\";\nimport { allowedRuntimeOverrides } from \"../core/targets.js\";\nimport type {\n DbDriver,\n DbOdm,\n DeployTarget,\n LoggerId,\n ScaffoldResult,\n ValidatorId,\n} from \"../core/types.js\";\nimport { DB_DRIVERS, DB_ODMS, DEPLOY_TARGETS, LOGGERS, VALIDATORS } from \"../core/types.js\";\nimport { validateProjectName } from \"../core/validate-project-name.js\";\nimport { resolveUserAgent, runScript } from \"../core/package-manager.js\";\n\nfunction isDeployTarget(value: unknown): value is DeployTarget {\n return typeof value === \"string\" && (DEPLOY_TARGETS as readonly string[]).includes(value);\n}\n\nfunction isDbOdm(value: unknown): value is DbOdm {\n return typeof value === \"string\" && (DB_ODMS as readonly string[]).includes(value);\n}\n\nfunction isDbDriver(value: unknown): value is DbDriver {\n return typeof value === \"string\" && (DB_DRIVERS as readonly string[]).includes(value);\n}\n\nfunction isLoggerId(value: unknown): value is LoggerId {\n return typeof value === \"string\" && (LOGGERS as readonly string[]).includes(value);\n}\n\nfunction isValidatorId(value: unknown): value is ValidatorId {\n return typeof value === \"string\" && (VALIDATORS as readonly string[]).includes(value);\n}\n\nasync function promptInteractiveOptions(args: ParsedCreateArgs): Promise<ParsedCreateArgs> {\n const projectName =\n args.projectName ??\n (await p.text({\n message: \"Project name\",\n placeholder: \"my-taser-app\",\n defaultValue: \"my-taser-app\",\n validate(value) {\n return validateProjectName(value);\n },\n }));\n\n if (p.isCancel(projectName)) {\n p.cancel(\"Scaffold cancelled.\");\n process.exit(0);\n }\n\n const framework =\n args.framework ??\n (await p.select({\n message: \"Host framework\",\n options: [\n { value: \"none\", label: \"Pure Taser\", hint: \"default\" },\n { value: \"hono\", label: \"Hono\" },\n { value: \"express\", label: \"Express\" },\n { value: \"fastify\", label: \"Fastify\" },\n ],\n initialValue: \"none\",\n }));\n\n if (p.isCancel(framework)) {\n p.cancel(\"Scaffold cancelled.\");\n process.exit(0);\n }\n\n const DEPLOY_LABELS: Record<DeployTarget, string> = {\n \"node-server\": \"Node.js server\",\n \"node-cluster\": \"Node.js cluster\",\n bun: \"Bun\",\n \"deno-server\": \"Deno\",\n \"deno-deploy\": \"Deno Deploy\",\n \"cloudflare-module\": \"Cloudflare Workers\",\n vercel: \"Vercel\",\n \"aws-lambda\": \"AWS Lambda\",\n netlify: \"Netlify\",\n };\n\n const preset =\n args.preset ??\n (await p.select({\n message: \"Deployment target\",\n options: DEPLOY_TARGETS.map((id) => ({ value: id, label: DEPLOY_LABELS[id] })),\n initialValue: \"node-server\",\n }));\n\n if (p.isCancel(preset) || !isDeployTarget(preset)) {\n p.cancel(\"Scaffold cancelled.\");\n process.exit(0);\n }\n\n let runtime: import(\"../core/types.js\").Runtime | undefined;\n const runtimeOverrides = allowedRuntimeOverrides(preset);\n if (runtimeOverrides.length > 0) {\n const runtimeChoice =\n args.runtime ??\n (await p.select({\n message: \"Runtime\",\n options: [\n ...runtimeOverrides.map((rt) => ({ value: rt, label: rt })),\n { value: \"default\", label: `Preset default`, hint: \"no override\" },\n ],\n initialValue: \"default\",\n }));\n\n if (p.isCancel(runtimeChoice)) {\n p.cancel(\"Scaffold cancelled.\");\n process.exit(0);\n }\n\n runtime = runtimeChoice === \"default\" ? undefined : runtimeChoice;\n }\n\n const dbChoice =\n args.db ??\n (await p.select({\n message: \"Database\",\n options: [\n { value: \"none\", label: \"None\", hint: \"default\" },\n { value: \"drizzle\", label: \"Drizzle\" },\n { value: \"prisma\", label: \"Prisma\" },\n { value: \"kysely\", label: \"Kysely\" },\n ],\n initialValue: \"none\",\n }));\n\n if (p.isCancel(dbChoice)) {\n p.cancel(\"Scaffold cancelled.\");\n process.exit(0);\n }\n\n let db: DbOdm | undefined;\n let driver: DbDriver | undefined;\n\n if (dbChoice !== \"none\" && isDbOdm(dbChoice)) {\n db = dbChoice;\n const driverChoice =\n args.driver ??\n (await p.select({\n message: \"Database driver\",\n options: [\n { value: \"sqlite\", label: \"SQLite\", hint: \"default\" },\n { value: \"postgres\", label: \"PostgreSQL\" },\n { value: \"mysql\", label: \"MySQL\" },\n ],\n initialValue: \"sqlite\",\n }));\n\n if (p.isCancel(driverChoice) || !isDbDriver(driverChoice)) {\n p.cancel(\"Scaffold cancelled.\");\n process.exit(0);\n }\n driver = driverChoice;\n }\n\n const loggerChoice =\n args.logger ??\n (await p.select({\n message: \"Logger\",\n options: [\n { value: \"none\", label: \"None\", hint: \"default\" },\n { value: \"pino\", label: \"Pino\" },\n { value: \"winston\", label: \"Winston\" },\n ],\n initialValue: \"none\",\n }));\n\n if (p.isCancel(loggerChoice)) {\n p.cancel(\"Scaffold cancelled.\");\n process.exit(0);\n }\n\n const logger =\n loggerChoice === \"none\" ? undefined : isLoggerId(loggerChoice) ? loggerChoice : undefined;\n\n const validatorChoice =\n args.validator ??\n (await p.select({\n message: \"Validator\",\n options: [\n { value: \"none\", label: \"None\", hint: \"default\" },\n { value: \"zod\", label: \"Zod\" },\n { value: \"arktype\", label: \"Arktype\" },\n { value: \"valibot\", label: \"Valibot\" },\n ],\n initialValue: \"none\",\n }));\n\n if (p.isCancel(validatorChoice)) {\n p.cancel(\"Scaffold cancelled.\");\n process.exit(0);\n }\n\n const validator =\n validatorChoice === \"none\"\n ? undefined\n : isValidatorId(validatorChoice)\n ? validatorChoice\n : undefined;\n\n return {\n projectName: String(projectName).trim(),\n framework,\n preset,\n ...(runtime !== undefined ? { runtime } : {}),\n yes: args.yes,\n noInstall: args.noInstall,\n json: args.json,\n ...(db ? { db, driver: driver! } : {}),\n ...(logger ? { logger } : {}),\n ...(validator ? { validator } : {}),\n };\n}\n\nexport async function runCreateCommand(\n args: ParsedCreateArgs,\n): Promise<ScaffoldResult | undefined> {\n if (args.json && !args.projectName) {\n printCapabilitiesCatalog(getCapabilitiesCatalog());\n return undefined;\n }\n\n const cwd = process.cwd();\n const interactive = !args.yes;\n const resolved = interactive\n ? await promptInteractiveOptions(args)\n : {\n ...args,\n projectName: args.projectName?.trim(),\n preset: args.preset ?? \"node-server\",\n };\n\n if (!resolved.projectName) {\n const message = \"Project name is required\";\n if (args.json) {\n printJsonError(message);\n process.exit(1);\n }\n throw new Error(message);\n }\n\n const nameError = validateProjectName(resolved.projectName, cwd);\n if (nameError) {\n if (args.json) {\n printJsonError(nameError);\n process.exit(1);\n }\n throw new Error(nameError);\n }\n\n const targetDir = path.resolve(cwd, resolved.projectName);\n const scaffoldCtx = resolveScaffoldDefaults({\n ...resolved,\n projectName: resolved.projectName,\n });\n scaffoldCtx.targetDir = targetDir;\n\n if (!args.json) {\n const spinner = p.spinner();\n spinner.start(\"Scaffolding project\");\n try {\n const result = await scaffoldProject({\n ...scaffoldCtx,\n targetDir,\n skipInstall: args.noInstall,\n agent: resolveUserAgent(),\n });\n spinner.stop(\"Project created\");\n const cdPath = path.relative(cwd, targetDir) || \".\";\n p.note([`cd ${cdPath}`, runScript(resolveUserAgent(), \"dev\")].join(\"\\n\"), \"Next steps\");\n p.outro(color.green(\"Done.\"));\n return result;\n } catch (error) {\n spinner.stop(\"Scaffold failed\");\n throw error;\n }\n }\n\n const result = await scaffoldProject({\n ...scaffoldCtx,\n targetDir,\n skipInstall: args.noInstall,\n agent: resolveUserAgent(),\n });\n printScaffoldResult(result);\n return result;\n}\n\nexport function buildParsedArgsFromCli(\n values: {\n preset?: string;\n framework?: string;\n runtime?: string;\n db?: string;\n logger?: string;\n validator?: string;\n y?: boolean;\n noInstall?: boolean;\n json?: boolean;\n },\n positionals: string[],\n): ParsedCreateArgs {\n const args: ParsedCreateArgs = {\n yes: values.y ?? false,\n noInstall: values.noInstall ?? false,\n json: values.json ?? false,\n };\n\n if (positionals[0]) {\n args.projectName = positionals[0];\n }\n\n if (values.preset) {\n const parsed = parsePresetFlag(values.preset);\n args.preset = parsed.preset;\n if (parsed.warning && !args.json) {\n console.warn(`warning: ${parsed.warning}`);\n }\n }\n\n if (values.framework) {\n args.framework = parseFrameworkFlag(values.framework);\n }\n\n if (values.runtime) {\n args.runtime = parseRuntimeFlag(values.runtime);\n }\n\n if (values.db) {\n const parsed = parseDbFlag(values.db);\n args.db = parsed.db;\n args.driver = parsed.driver;\n }\n\n if (values.logger) {\n args.logger = parseLoggerFlag(values.logger);\n }\n\n if (values.validator) {\n args.validator = parseValidatorFlag(values.validator);\n }\n\n return args;\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import { DbDriver, DbOdm, LoggerId,
|
|
1
|
+
import { DbDriver, DbOdm, Framework, LoggerId, Runtime, ScaffoldContext, ValidatorId } from './types.js';
|
|
2
|
+
import { resolveDeployEntry } from './targets.js';
|
|
2
3
|
export type ParsedCreateArgs = {
|
|
3
4
|
projectName?: string;
|
|
4
|
-
|
|
5
|
+
framework?: Framework;
|
|
6
|
+
/** Deployment target — a Nitro preset id. */
|
|
7
|
+
preset?: string;
|
|
8
|
+
runtime?: Runtime;
|
|
5
9
|
db?: DbOdm;
|
|
6
10
|
driver?: DbDriver;
|
|
7
11
|
logger?: LoggerId;
|
|
@@ -14,7 +18,18 @@ export declare function parseDbFlag(value: string): {
|
|
|
14
18
|
db: DbOdm;
|
|
15
19
|
driver: DbDriver;
|
|
16
20
|
};
|
|
17
|
-
export declare function
|
|
18
|
-
|
|
21
|
+
export declare function parseFrameworkFlag(value: string): Framework;
|
|
22
|
+
/**
|
|
23
|
+
* Accepts curated deploy targets verbatim; unknown ids pass through to Nitro.
|
|
24
|
+
* Returns a warning for passthrough ids so callers can surface it.
|
|
25
|
+
*/
|
|
26
|
+
export declare function parsePresetFlag(value: string): {
|
|
27
|
+
preset: string;
|
|
28
|
+
warning?: string;
|
|
29
|
+
};
|
|
30
|
+
export declare function parseRuntimeFlag(value: string): Runtime;
|
|
19
31
|
export declare function parseLoggerFlag(value: string): LoggerId;
|
|
20
32
|
export declare function parseValidatorFlag(value: string): ValidatorId;
|
|
33
|
+
export declare function resolveScaffoldDefaults(args: ParsedCreateArgs): ScaffoldContext;
|
|
34
|
+
/** Re-exported for CLI layers that need to warn about passthrough presets. */
|
|
35
|
+
export { resolveDeployEntry };
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import { DB_DRIVERS, DB_ODMS, DEFAULT_DB_DRIVER, LOGGERS,
|
|
1
|
+
import { DB_DRIVERS, DB_ODMS, DEFAULT_DB_DRIVER, FRAMEWORKS, LOGGERS, RUNTIMES, VALIDATORS } from "./types.js";
|
|
2
|
+
import { isCuratedDeploy, validateCombination } from "./targets.js";
|
|
2
3
|
//#region src/core/parse-options.ts
|
|
3
|
-
function
|
|
4
|
-
return
|
|
4
|
+
function isFramework(value) {
|
|
5
|
+
return FRAMEWORKS.includes(value);
|
|
6
|
+
}
|
|
7
|
+
function isRuntime(value) {
|
|
8
|
+
return RUNTIMES.includes(value);
|
|
5
9
|
}
|
|
6
10
|
function isDbOdm(value) {
|
|
7
11
|
return DB_ODMS.includes(value);
|
|
@@ -28,27 +32,26 @@ function parseDbFlag(value) {
|
|
|
28
32
|
driver
|
|
29
33
|
};
|
|
30
34
|
}
|
|
31
|
-
function
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
35
|
+
function parseFrameworkFlag(value) {
|
|
36
|
+
if (!isFramework(value)) throw new Error(`Invalid --framework "${value}". Use ${FRAMEWORKS.join(", ")}.`);
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Accepts curated deploy targets verbatim; unknown ids pass through to Nitro.
|
|
41
|
+
* Returns a warning for passthrough ids so callers can surface it.
|
|
42
|
+
*/
|
|
43
|
+
function parsePresetFlag(value) {
|
|
44
|
+
if (!isCuratedDeploy(value)) {
|
|
45
|
+
if (!/^[a-z0-9][a-z0-9-_]*$/i.test(value)) throw new Error(`Invalid --preset "${value}".`);
|
|
46
|
+
return {
|
|
47
|
+
preset: value,
|
|
48
|
+
warning: `"${value}" is not a curated Taser deploy target; passing it through to Nitro as-is.`
|
|
49
|
+
};
|
|
45
50
|
}
|
|
46
|
-
|
|
47
|
-
if (validator) result.validator = validator;
|
|
48
|
-
return result;
|
|
51
|
+
return { preset: value };
|
|
49
52
|
}
|
|
50
|
-
function
|
|
51
|
-
if (!
|
|
53
|
+
function parseRuntimeFlag(value) {
|
|
54
|
+
if (!isRuntime(value)) throw new Error(`Invalid --runtime "${value}". Use node, bun, or deno.`);
|
|
52
55
|
return value;
|
|
53
56
|
}
|
|
54
57
|
function parseLoggerFlag(value) {
|
|
@@ -59,7 +62,28 @@ function parseValidatorFlag(value) {
|
|
|
59
62
|
if (!isValidatorId(value)) throw new Error(`Invalid --validator "${value}". Use zod, arktype, or valibot.`);
|
|
60
63
|
return value;
|
|
61
64
|
}
|
|
65
|
+
function resolveScaffoldDefaults(args) {
|
|
66
|
+
const framework = args.framework ?? "none";
|
|
67
|
+
const preset = args.preset ?? "node-server";
|
|
68
|
+
if (!args.projectName) throw new Error("Project name is required");
|
|
69
|
+
const combination = validateCombination(args.runtime, framework, preset);
|
|
70
|
+
if (!combination.ok) throw new Error(combination.reason);
|
|
71
|
+
const result = {
|
|
72
|
+
projectName: args.projectName.trim(),
|
|
73
|
+
targetDir: "",
|
|
74
|
+
framework,
|
|
75
|
+
preset,
|
|
76
|
+
...args.runtime !== void 0 ? { runtime: args.runtime } : {}
|
|
77
|
+
};
|
|
78
|
+
if (args.db) {
|
|
79
|
+
result.db = args.db;
|
|
80
|
+
result.driver = args.driver ?? "sqlite";
|
|
81
|
+
}
|
|
82
|
+
if (args.logger) result.logger = args.logger;
|
|
83
|
+
if (args.validator) result.validator = args.validator;
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
62
86
|
//#endregion
|
|
63
|
-
export { parseDbFlag, parseLoggerFlag,
|
|
87
|
+
export { parseDbFlag, parseFrameworkFlag, parseLoggerFlag, parsePresetFlag, parseRuntimeFlag, parseValidatorFlag, resolveScaffoldDefaults };
|
|
64
88
|
|
|
65
89
|
//# sourceMappingURL=parse-options.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-options.js","names":[],"sources":["../../../src/core/parse-options.ts"],"sourcesContent":["import {\n DB_DRIVERS,\n DB_ODMS,\n DEFAULT_DB_DRIVER,\n LOGGERS,\n
|
|
1
|
+
{"version":3,"file":"parse-options.js","names":[],"sources":["../../../src/core/parse-options.ts"],"sourcesContent":["import {\n DB_DRIVERS,\n DB_ODMS,\n DEFAULT_DB_DRIVER,\n FRAMEWORKS,\n LOGGERS,\n RUNTIMES,\n VALIDATORS,\n type DbDriver,\n type DbOdm,\n type DeployTarget,\n type Framework,\n type LoggerId,\n type Runtime,\n type ScaffoldContext,\n type ValidatorId,\n} from \"./types.js\";\nimport {\n DEFAULT_DEPLOY,\n isCuratedDeploy,\n resolveDeployEntry,\n validateCombination,\n} from \"./targets.js\";\n\nexport type ParsedCreateArgs = {\n projectName?: string;\n framework?: Framework;\n /** Deployment target — a Nitro preset id. */\n preset?: string;\n runtime?: Runtime;\n db?: DbOdm;\n driver?: DbDriver;\n logger?: LoggerId;\n validator?: ValidatorId;\n yes: boolean;\n noInstall: boolean;\n json: boolean;\n};\n\nfunction isFramework(value: string): value is Framework {\n return (FRAMEWORKS as readonly string[]).includes(value);\n}\n\nfunction isRuntime(value: string): value is Runtime {\n return (RUNTIMES as readonly string[]).includes(value);\n}\n\nfunction isDbOdm(value: string): value is DbOdm {\n return (DB_ODMS as readonly string[]).includes(value);\n}\n\nfunction isDbDriver(value: string): value is DbDriver {\n return (DB_DRIVERS as readonly string[]).includes(value);\n}\n\nfunction isLoggerId(value: string): value is LoggerId {\n return (LOGGERS as readonly string[]).includes(value);\n}\n\nfunction isValidatorId(value: string): value is ValidatorId {\n return (VALIDATORS as readonly string[]).includes(value);\n}\n\nexport function parseDbFlag(value: string): { db: DbOdm; driver: DbDriver } {\n const [odm, driver] = value.split(\":\");\n if (!odm || !isDbOdm(odm)) {\n throw new Error(\n `Invalid --db value \"${value}\". Use drizzle, prisma, or kysely (optionally with :postgres, :sqlite, or :mysql).`,\n );\n }\n\n if (driver === undefined || driver === \"\") {\n return { db: odm, driver: DEFAULT_DB_DRIVER };\n }\n\n if (!isDbDriver(driver)) {\n throw new Error(`Invalid database driver \"${driver}\". Use postgres, sqlite, or mysql.`);\n }\n\n return { db: odm, driver };\n}\n\nexport function parseFrameworkFlag(value: string): Framework {\n if (!isFramework(value)) {\n throw new Error(`Invalid --framework \"${value}\". Use ${FRAMEWORKS.join(\", \")}.`);\n }\n return value;\n}\n\n/**\n * Accepts curated deploy targets verbatim; unknown ids pass through to Nitro.\n * Returns a warning for passthrough ids so callers can surface it.\n */\nexport function parsePresetFlag(value: string): { preset: string; warning?: string } {\n if (!isCuratedDeploy(value)) {\n if (!/^[a-z0-9][a-z0-9-_]*$/i.test(value)) {\n throw new Error(`Invalid --preset \"${value}\".`);\n }\n return {\n preset: value,\n warning: `\"${value}\" is not a curated Taser deploy target; passing it through to Nitro as-is.`,\n };\n }\n return { preset: value };\n}\n\nexport function parseRuntimeFlag(value: string): Runtime {\n if (!isRuntime(value)) {\n throw new Error(`Invalid --runtime \"${value}\". Use node, bun, or deno.`);\n }\n return value;\n}\n\nexport function parseLoggerFlag(value: string): LoggerId {\n if (!isLoggerId(value)) {\n throw new Error(`Invalid --logger \"${value}\". Use pino or winston.`);\n }\n return value;\n}\n\nexport function parseValidatorFlag(value: string): ValidatorId {\n if (!isValidatorId(value)) {\n throw new Error(`Invalid --validator \"${value}\". Use zod, arktype, or valibot.`);\n }\n return value;\n}\n\nexport function resolveScaffoldDefaults(args: ParsedCreateArgs): ScaffoldContext {\n const framework: Framework = args.framework ?? \"none\";\n const preset = args.preset ?? DEFAULT_DEPLOY;\n\n if (!args.projectName) {\n throw new Error(\"Project name is required\");\n }\n\n // Throws with a precise reason when runtime × framework × deploy clash.\n const combination = validateCombination(args.runtime, framework, preset);\n if (!combination.ok) {\n throw new Error(combination.reason);\n }\n\n const result: ScaffoldContext = {\n projectName: args.projectName.trim(),\n targetDir: \"\",\n framework,\n preset: preset as DeployTarget,\n ...(args.runtime !== undefined ? { runtime: args.runtime } : {}),\n };\n\n if (args.db) {\n result.db = args.db;\n result.driver = args.driver ?? DEFAULT_DB_DRIVER;\n }\n\n if (args.logger) {\n result.logger = args.logger;\n }\n\n if (args.validator) {\n result.validator = args.validator;\n }\n\n return result;\n}\n\n/** Re-exported for CLI layers that need to warn about passthrough presets. */\nexport { resolveDeployEntry };\n"],"mappings":";;;AAuCA,SAAS,YAAY,OAAmC;CACtD,OAAQ,WAAiC,SAAS,KAAK;AACzD;AAEA,SAAS,UAAU,OAAiC;CAClD,OAAQ,SAA+B,SAAS,KAAK;AACvD;AAEA,SAAS,QAAQ,OAA+B;CAC9C,OAAQ,QAA8B,SAAS,KAAK;AACtD;AAEA,SAAS,WAAW,OAAkC;CACpD,OAAQ,WAAiC,SAAS,KAAK;AACzD;AAEA,SAAS,WAAW,OAAkC;CACpD,OAAQ,QAA8B,SAAS,KAAK;AACtD;AAEA,SAAS,cAAc,OAAqC;CAC1D,OAAQ,WAAiC,SAAS,KAAK;AACzD;AAEA,SAAgB,YAAY,OAAgD;CAC1E,MAAM,CAAC,KAAK,UAAU,MAAM,MAAM,GAAG;CACrC,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,GACtB,MAAM,IAAI,MACR,uBAAuB,MAAM,mFAC/B;CAGF,IAAI,WAAW,KAAA,KAAa,WAAW,IACrC,OAAO;EAAE,IAAI;EAAK,QAAQ;CAAkB;CAG9C,IAAI,CAAC,WAAW,MAAM,GACpB,MAAM,IAAI,MAAM,4BAA4B,OAAO,mCAAmC;CAGxF,OAAO;EAAE,IAAI;EAAK;CAAO;AAC3B;AAEA,SAAgB,mBAAmB,OAA0B;CAC3D,IAAI,CAAC,YAAY,KAAK,GACpB,MAAM,IAAI,MAAM,wBAAwB,MAAM,SAAS,WAAW,KAAK,IAAI,EAAE,EAAE;CAEjF,OAAO;AACT;;;;;AAMA,SAAgB,gBAAgB,OAAqD;CACnF,IAAI,CAAC,gBAAgB,KAAK,GAAG;EAC3B,IAAI,CAAC,yBAAyB,KAAK,KAAK,GACtC,MAAM,IAAI,MAAM,qBAAqB,MAAM,GAAG;EAEhD,OAAO;GACL,QAAQ;GACR,SAAS,IAAI,MAAM;EACrB;CACF;CACA,OAAO,EAAE,QAAQ,MAAM;AACzB;AAEA,SAAgB,iBAAiB,OAAwB;CACvD,IAAI,CAAC,UAAU,KAAK,GAClB,MAAM,IAAI,MAAM,sBAAsB,MAAM,2BAA2B;CAEzE,OAAO;AACT;AAEA,SAAgB,gBAAgB,OAAyB;CACvD,IAAI,CAAC,WAAW,KAAK,GACnB,MAAM,IAAI,MAAM,qBAAqB,MAAM,wBAAwB;CAErE,OAAO;AACT;AAEA,SAAgB,mBAAmB,OAA4B;CAC7D,IAAI,CAAC,cAAc,KAAK,GACtB,MAAM,IAAI,MAAM,wBAAwB,MAAM,iCAAiC;CAEjF,OAAO;AACT;AAEA,SAAgB,wBAAwB,MAAyC;CAC/E,MAAM,YAAuB,KAAK,aAAa;CAC/C,MAAM,SAAS,KAAK,UAAA;CAEpB,IAAI,CAAC,KAAK,aACR,MAAM,IAAI,MAAM,0BAA0B;CAI5C,MAAM,cAAc,oBAAoB,KAAK,SAAS,WAAW,MAAM;CACvE,IAAI,CAAC,YAAY,IACf,MAAM,IAAI,MAAM,YAAY,MAAM;CAGpC,MAAM,SAA0B;EAC9B,aAAa,KAAK,YAAY,KAAK;EACnC,WAAW;EACX;EACQ;EACR,GAAI,KAAK,YAAY,KAAA,IAAY,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;CAChE;CAEA,IAAI,KAAK,IAAI;EACX,OAAO,KAAK,KAAK;EACjB,OAAO,SAAS,KAAK,UAAA;CACvB;CAEA,IAAI,KAAK,QACP,OAAO,SAAS,KAAK;CAGvB,IAAI,KAAK,WACP,OAAO,YAAY,KAAK;CAG1B,OAAO;AACT"}
|
|
@@ -2,7 +2,11 @@ import path from "node:path";
|
|
|
2
2
|
import { writeFile } from "node:fs/promises";
|
|
3
3
|
//#region src/core/project-config.ts
|
|
4
4
|
async function writeProjectConfig(root, ctx) {
|
|
5
|
-
const config = {
|
|
5
|
+
const config = {
|
|
6
|
+
framework: ctx.framework ?? "none",
|
|
7
|
+
preset: ctx.preset ?? "node-server"
|
|
8
|
+
};
|
|
9
|
+
if (ctx.runtime) config.runtime = ctx.runtime;
|
|
6
10
|
if (ctx.db) {
|
|
7
11
|
config.db = ctx.db;
|
|
8
12
|
if (ctx.driver) config.driver = ctx.driver;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-config.js","names":[],"sources":["../../../src/core/project-config.ts"],"sourcesContent":["import { writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { ScaffoldContext } from \"./types.js\";\n\nexport async function writeProjectConfig(root: string, ctx: ScaffoldContext): Promise<void> {\n const config: Record<string, string> = {\n
|
|
1
|
+
{"version":3,"file":"project-config.js","names":[],"sources":["../../../src/core/project-config.ts"],"sourcesContent":["import { writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { ScaffoldContext } from \"./types.js\";\n\nexport async function writeProjectConfig(root: string, ctx: ScaffoldContext): Promise<void> {\n const config: Record<string, string> = {\n framework: ctx.framework ?? \"none\",\n preset: ctx.preset ?? \"node-server\",\n };\n\n if (ctx.runtime) {\n config.runtime = ctx.runtime;\n }\n\n if (ctx.db) {\n config.db = ctx.db;\n if (ctx.driver) {\n config.driver = ctx.driver;\n }\n }\n\n if (ctx.logger) {\n config.logger = ctx.logger;\n }\n\n if (ctx.validator) {\n config.validator = ctx.validator;\n }\n\n await writeFile(path.join(root, \".taser.json\"), `${JSON.stringify(config, null, 2)}\\n`, \"utf8\");\n}\n"],"mappings":";;;AAKA,eAAsB,mBAAmB,MAAc,KAAqC;CAC1F,MAAM,SAAiC;EACrC,WAAW,IAAI,aAAa;EAC5B,QAAQ,IAAI,UAAU;CACxB;CAEA,IAAI,IAAI,SACN,OAAO,UAAU,IAAI;CAGvB,IAAI,IAAI,IAAI;EACV,OAAO,KAAK,IAAI;EAChB,IAAI,IAAI,QACN,OAAO,SAAS,IAAI;CAExB;CAEA,IAAI,IAAI,QACN,OAAO,SAAS,IAAI;CAGtB,IAAI,IAAI,WACN,OAAO,YAAY,IAAI;CAGzB,MAAM,UAAU,KAAK,KAAK,MAAM,aAAa,GAAG,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,KAAK,MAAM;AAChG"}
|
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
import { PackageGroups,
|
|
1
|
+
import { PackageGroups, ScaffoldContext } from '../core/types.js';
|
|
2
2
|
export declare function resolvePackages(ctx: ScaffoldContext): PackageGroups;
|
|
3
|
-
export declare function getPackageGroups(type: ProjectType): Omit<PackageGroups, "scripts"> & {
|
|
4
|
-
scripts?: Record<string, string>;
|
|
5
|
-
};
|