create-taserjs 0.1.11 → 0.2.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.
Files changed (189) hide show
  1. package/README.md +8 -44
  2. package/dist/cli-9fkoNOJg.js +1237 -0
  3. package/dist/cli-9fkoNOJg.js.map +1 -0
  4. package/dist/cli-DkZddFtU.cjs +1398 -0
  5. package/dist/cli.cjs +4 -0
  6. package/dist/cli.d.cts +4 -0
  7. package/dist/cli.d.cts.map +1 -0
  8. package/dist/cli.d.ts +4 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/cli.js +3 -0
  11. package/dist/index.cjs +25 -0
  12. package/dist/index.d.cts +119 -0
  13. package/dist/index.d.cts.map +1 -0
  14. package/dist/index.d.ts +119 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +2 -0
  17. package/package.json +39 -9
  18. package/src/addons/drizzle/index.ts +37 -40
  19. package/src/addons/kysely/index.ts +19 -22
  20. package/src/addons/pino/index.ts +2 -2
  21. package/src/addons/prisma/index.ts +18 -22
  22. package/src/addons/registry.ts +37 -73
  23. package/src/addons/types.ts +12 -13
  24. package/src/addons/validators.ts +22 -23
  25. package/src/addons/winston/index.ts +3 -3
  26. package/src/cli.ts +96 -56
  27. package/src/commands/create.ts +118 -249
  28. package/src/core/package-manager.ts +36 -55
  29. package/src/core/scaffold-engine.ts +100 -75
  30. package/src/core/targets.ts +20 -56
  31. package/src/core/types.ts +18 -53
  32. package/src/index.ts +8 -0
  33. package/src/templates/base.ts +139 -51
  34. package/dist/cjs/_virtual/_rolldown/runtime.cjs +0 -23
  35. package/dist/cjs/addons/arktype/index.cjs +0 -6
  36. package/dist/cjs/addons/arktype/index.cjs.map +0 -1
  37. package/dist/cjs/addons/arktype/index.d.cts +0 -1
  38. package/dist/cjs/addons/drizzle/index.cjs +0 -131
  39. package/dist/cjs/addons/drizzle/index.cjs.map +0 -1
  40. package/dist/cjs/addons/drizzle/index.d.cts +0 -2
  41. package/dist/cjs/addons/kysely/index.cjs +0 -103
  42. package/dist/cjs/addons/kysely/index.cjs.map +0 -1
  43. package/dist/cjs/addons/kysely/index.d.cts +0 -2
  44. package/dist/cjs/addons/pino/index.cjs +0 -30
  45. package/dist/cjs/addons/pino/index.cjs.map +0 -1
  46. package/dist/cjs/addons/pino/index.d.cts +0 -2
  47. package/dist/cjs/addons/prisma/index.cjs +0 -133
  48. package/dist/cjs/addons/prisma/index.cjs.map +0 -1
  49. package/dist/cjs/addons/prisma/index.d.cts +0 -2
  50. package/dist/cjs/addons/registry.cjs +0 -65
  51. package/dist/cjs/addons/registry.cjs.map +0 -1
  52. package/dist/cjs/addons/registry.d.cts +0 -5
  53. package/dist/cjs/addons/types.d.cts +0 -16
  54. package/dist/cjs/addons/valibot/index.cjs +0 -6
  55. package/dist/cjs/addons/valibot/index.cjs.map +0 -1
  56. package/dist/cjs/addons/valibot/index.d.cts +0 -1
  57. package/dist/cjs/addons/validators.cjs +0 -38
  58. package/dist/cjs/addons/validators.cjs.map +0 -1
  59. package/dist/cjs/addons/validators.d.cts +0 -5
  60. package/dist/cjs/addons/winston/index.cjs +0 -34
  61. package/dist/cjs/addons/winston/index.cjs.map +0 -1
  62. package/dist/cjs/addons/winston/index.d.cts +0 -2
  63. package/dist/cjs/addons/zod/index.cjs +0 -6
  64. package/dist/cjs/addons/zod/index.cjs.map +0 -1
  65. package/dist/cjs/addons/zod/index.d.cts +0 -1
  66. package/dist/cjs/cli.cjs +0 -65
  67. package/dist/cjs/cli.cjs.map +0 -1
  68. package/dist/cjs/cli.d.cts +0 -2
  69. package/dist/cjs/commands/create.cjs +0 -332
  70. package/dist/cjs/commands/create.cjs.map +0 -1
  71. package/dist/cjs/commands/create.d.cts +0 -14
  72. package/dist/cjs/core/json-output.cjs +0 -16
  73. package/dist/cjs/core/json-output.cjs.map +0 -1
  74. package/dist/cjs/core/json-output.d.cts +0 -4
  75. package/dist/cjs/core/package-manager.cjs +0 -56
  76. package/dist/cjs/core/package-manager.cjs.map +0 -1
  77. package/dist/cjs/core/package-manager.d.cts +0 -8
  78. package/dist/cjs/core/parse-options.cjs +0 -95
  79. package/dist/cjs/core/parse-options.cjs.map +0 -1
  80. package/dist/cjs/core/parse-options.d.cts +0 -35
  81. package/dist/cjs/core/project-config.cjs +0 -23
  82. package/dist/cjs/core/project-config.cjs.map +0 -1
  83. package/dist/cjs/core/project-config.d.cts +0 -2
  84. package/dist/cjs/core/resolve-packages.cjs +0 -58
  85. package/dist/cjs/core/resolve-packages.cjs.map +0 -1
  86. package/dist/cjs/core/resolve-packages.d.cts +0 -2
  87. package/dist/cjs/core/scaffold-engine.cjs +0 -72
  88. package/dist/cjs/core/scaffold-engine.cjs.map +0 -1
  89. package/dist/cjs/core/scaffold-engine.d.cts +0 -2
  90. package/dist/cjs/core/targets.cjs +0 -171
  91. package/dist/cjs/core/targets.cjs.map +0 -1
  92. package/dist/cjs/core/targets.d.cts +0 -49
  93. package/dist/cjs/core/types.cjs +0 -52
  94. package/dist/cjs/core/types.cjs.map +0 -1
  95. package/dist/cjs/core/types.d.cts +0 -57
  96. package/dist/cjs/core/validate-project-name.cjs +0 -44
  97. package/dist/cjs/core/validate-project-name.cjs.map +0 -1
  98. package/dist/cjs/core/validate-project-name.d.cts +0 -1
  99. package/dist/cjs/frameworks/index.cjs +0 -116
  100. package/dist/cjs/frameworks/index.cjs.map +0 -1
  101. package/dist/cjs/frameworks/index.d.cts +0 -18
  102. package/dist/cjs/scaffold.d.cts +0 -3
  103. package/dist/cjs/templates/base.cjs +0 -97
  104. package/dist/cjs/templates/base.cjs.map +0 -1
  105. package/dist/cjs/templates/base.d.cts +0 -9
  106. package/dist/cjs/types.d.cts +0 -1
  107. package/dist/esm/addons/arktype/index.d.ts +0 -1
  108. package/dist/esm/addons/arktype/index.js +0 -7
  109. package/dist/esm/addons/arktype/index.js.map +0 -1
  110. package/dist/esm/addons/drizzle/index.d.ts +0 -2
  111. package/dist/esm/addons/drizzle/index.js +0 -131
  112. package/dist/esm/addons/drizzle/index.js.map +0 -1
  113. package/dist/esm/addons/kysely/index.d.ts +0 -2
  114. package/dist/esm/addons/kysely/index.js +0 -103
  115. package/dist/esm/addons/kysely/index.js.map +0 -1
  116. package/dist/esm/addons/pino/index.d.ts +0 -2
  117. package/dist/esm/addons/pino/index.js +0 -30
  118. package/dist/esm/addons/pino/index.js.map +0 -1
  119. package/dist/esm/addons/prisma/index.d.ts +0 -2
  120. package/dist/esm/addons/prisma/index.js +0 -133
  121. package/dist/esm/addons/prisma/index.js.map +0 -1
  122. package/dist/esm/addons/registry.d.ts +0 -5
  123. package/dist/esm/addons/registry.js +0 -63
  124. package/dist/esm/addons/registry.js.map +0 -1
  125. package/dist/esm/addons/types.d.ts +0 -16
  126. package/dist/esm/addons/valibot/index.d.ts +0 -1
  127. package/dist/esm/addons/valibot/index.js +0 -7
  128. package/dist/esm/addons/valibot/index.js.map +0 -1
  129. package/dist/esm/addons/validators.d.ts +0 -5
  130. package/dist/esm/addons/validators.js +0 -36
  131. package/dist/esm/addons/validators.js.map +0 -1
  132. package/dist/esm/addons/winston/index.d.ts +0 -2
  133. package/dist/esm/addons/winston/index.js +0 -34
  134. package/dist/esm/addons/winston/index.js.map +0 -1
  135. package/dist/esm/addons/zod/index.d.ts +0 -1
  136. package/dist/esm/addons/zod/index.js +0 -7
  137. package/dist/esm/addons/zod/index.js.map +0 -1
  138. package/dist/esm/cli.d.ts +0 -2
  139. package/dist/esm/cli.js +0 -62
  140. package/dist/esm/cli.js.map +0 -1
  141. package/dist/esm/commands/create.d.ts +0 -14
  142. package/dist/esm/commands/create.js +0 -327
  143. package/dist/esm/commands/create.js.map +0 -1
  144. package/dist/esm/core/json-output.d.ts +0 -4
  145. package/dist/esm/core/json-output.js +0 -14
  146. package/dist/esm/core/json-output.js.map +0 -1
  147. package/dist/esm/core/package-manager.d.ts +0 -8
  148. package/dist/esm/core/package-manager.js +0 -53
  149. package/dist/esm/core/package-manager.js.map +0 -1
  150. package/dist/esm/core/parse-options.d.ts +0 -35
  151. package/dist/esm/core/parse-options.js +0 -89
  152. package/dist/esm/core/parse-options.js.map +0 -1
  153. package/dist/esm/core/project-config.d.ts +0 -2
  154. package/dist/esm/core/project-config.js +0 -21
  155. package/dist/esm/core/project-config.js.map +0 -1
  156. package/dist/esm/core/resolve-packages.d.ts +0 -2
  157. package/dist/esm/core/resolve-packages.js +0 -58
  158. package/dist/esm/core/resolve-packages.js.map +0 -1
  159. package/dist/esm/core/scaffold-engine.d.ts +0 -2
  160. package/dist/esm/core/scaffold-engine.js +0 -70
  161. package/dist/esm/core/scaffold-engine.js.map +0 -1
  162. package/dist/esm/core/targets.d.ts +0 -49
  163. package/dist/esm/core/targets.js +0 -166
  164. package/dist/esm/core/targets.js.map +0 -1
  165. package/dist/esm/core/types.d.ts +0 -57
  166. package/dist/esm/core/types.js +0 -45
  167. package/dist/esm/core/types.js.map +0 -1
  168. package/dist/esm/core/validate-project-name.d.ts +0 -1
  169. package/dist/esm/core/validate-project-name.js +0 -42
  170. package/dist/esm/core/validate-project-name.js.map +0 -1
  171. package/dist/esm/frameworks/index.d.ts +0 -18
  172. package/dist/esm/frameworks/index.js +0 -112
  173. package/dist/esm/frameworks/index.js.map +0 -1
  174. package/dist/esm/scaffold.d.ts +0 -3
  175. package/dist/esm/templates/base.d.ts +0 -9
  176. package/dist/esm/templates/base.js +0 -91
  177. package/dist/esm/templates/base.js.map +0 -1
  178. package/dist/esm/types.d.ts +0 -1
  179. package/src/addons/arktype/index.ts +0 -3
  180. package/src/addons/valibot/index.ts +0 -3
  181. package/src/addons/zod/index.ts +0 -3
  182. package/src/core/json-output.ts +0 -13
  183. package/src/core/parse-options.ts +0 -167
  184. package/src/core/project-config.ts +0 -32
  185. package/src/core/resolve-packages.ts +0 -69
  186. package/src/core/validate-project-name.ts +0 -55
  187. package/src/frameworks/index.ts +0 -120
  188. package/src/scaffold.ts +0 -3
  189. package/src/types.ts +0 -12
@@ -1,117 +1,142 @@
1
- import { copyFile, mkdir, writeFile } from "node:fs/promises";
2
- import path from "node:path";
3
-
1
+ import { mkdir, writeFile } from "node:fs/promises";
2
+ import { dirname, join } from "node:path";
4
3
  import { collectBootBindings, resolveAddons } from "../addons/registry.js";
5
- import { nitroConfigTemplate, taserTsTemplate, viteConfigTemplate } from "../frameworks/index.js";
6
4
  import { installPackages, resolveUserAgent } from "./package-manager.js";
7
- import { writeProjectConfig } from "./project-config.js";
8
- import { resolvePackages } from "./resolve-packages.js";
9
5
  import { resolveDeployEntry, validateCombination } from "./targets.js";
10
- import { FRAMEWORK_ENTRIES } from "../frameworks/index.js";
11
- import type { ScaffoldContext, ScaffoldOptions, ScaffoldResult } from "./types.js";
6
+ import type { ScaffoldOptions, ScaffoldResult } from "./types.js";
12
7
  import {
13
8
  contextTemplate,
14
9
  gitignoreTemplate,
15
- healthRouteTemplate,
16
10
  indexRouteTemplate,
11
+ nitroConfigTemplate,
17
12
  packageJsonTemplate,
18
13
  rootLayoutTemplate,
14
+ staticRoutesGenTemplate,
15
+ taserConfigTemplate,
16
+ taserTsTemplate,
19
17
  tsconfigTemplate,
18
+ viteConfigTemplate,
20
19
  } from "../templates/base.js";
21
20
 
22
21
  async function write(filePath: string, contents: string): Promise<void> {
23
- await mkdir(path.dirname(filePath), { recursive: true });
24
- await writeFile(filePath, contents, "utf8");
22
+ await mkdir(dirname(filePath), { recursive: true });
23
+ await writeFile(filePath, contents.trimStart(), "utf-8");
25
24
  }
26
25
 
27
26
  export async function scaffoldProject(options: ScaffoldOptions): Promise<ScaffoldResult> {
28
27
  const root = options.targetDir;
29
- const preset = options.preset ?? "node-server";
30
- const framework = options.framework ?? "none";
28
+ const preset = options.preset ?? "none";
31
29
 
32
- // Guards direct/library callers; the CLI path is validated earlier in
33
- // resolveScaffoldDefaults. Throws with a precise reason on impossible
34
- // runtime × framework × deploy combinations.
35
- const combination = validateCombination(options.runtime, framework, preset);
30
+ const combination = validateCombination(options.runtime, preset);
36
31
  if (!combination.ok) {
37
32
  throw new Error(combination.reason);
38
33
  }
39
34
 
40
- const ctx: ScaffoldContext = {
41
- projectName: options.projectName,
42
- targetDir: root,
43
- framework,
44
- preset,
45
- ...(options.runtime !== undefined ? { runtime: options.runtime } : {}),
46
- ...(options.db ? { db: options.db, driver: options.driver } : {}),
47
- ...(options.logger ? { logger: options.logger } : {}),
48
- ...(options.validator ? { validator: options.validator } : {}),
35
+ const writtenFiles: string[] = [];
36
+ const trackedWrite = async (relPath: string, contents: string) => {
37
+ const fullPath = join(root, relPath);
38
+ await write(fullPath, contents);
39
+ writtenFiles.push(relPath);
49
40
  };
50
41
 
51
- const addons = resolveAddons(ctx);
52
- const packages = resolvePackages(ctx);
53
- const bootBindings = collectBootBindings(ctx);
54
- const frameworkEntry = FRAMEWORK_ENTRIES[framework];
55
- const { entry: deployEntry } = resolveDeployEntry(ctx.preset ?? "node-server");
42
+ const addons = resolveAddons(options);
43
+ const bootBindings = collectBootBindings(options);
44
+ const { entry: deployEntry } = resolveDeployEntry(preset);
56
45
 
57
- await write(
58
- path.join(root, "package.json"),
59
- packageJsonTemplate(options.projectName, packages.scripts),
60
- );
61
- await write(path.join(root, "tsconfig.json"), tsconfigTemplate());
62
- await write(path.join(root, "vite.config.ts"), viteConfigTemplate(ctx.preset));
63
- await write(path.join(root, ".gitignore"), gitignoreTemplate());
64
- await write(path.join(root, "src/context.ts"), contextTemplate(bootBindings));
65
- await write(path.join(root, "src/taser.ts"), taserTsTemplate());
66
- await write(path.join(root, "src/routes/$.ts"), rootLayoutTemplate());
67
- await write(path.join(root, "src/routes/index.get.ts"), indexRouteTemplate());
68
- await write(path.join(root, "src/routes/health.get.ts"), healthRouteTemplate(ctx));
69
-
70
- // Nitro's default preset is node-server — only emit an explicit config when
71
- // the deployment target differs. Do not emit for preset "none".
72
- if (ctx.preset !== "node-server" && ctx.preset !== "none") {
73
- await write(path.join(root, "nitro.config.ts"), nitroConfigTemplate(deployEntry.id));
46
+ // Collect scripts & dependencies
47
+ const scripts: Record<string, string> = {};
48
+ if (deployEntry.startScript) {
49
+ scripts.start = deployEntry.startScript;
50
+ }
51
+
52
+ const dependencies: string[] = ["@taserjs/router", "@taserjs/runtime"];
53
+ const devDependencies: string[] = ["@taserjs/cli", "@taserjs/plugin", "typescript", "vite"];
54
+
55
+ for (const dep of deployEntry.devDeps) {
56
+ devDependencies.push(dep);
57
+ }
58
+
59
+ for (const addon of addons) {
60
+ dependencies.push(...addon.dependencies(options));
61
+ devDependencies.push(...addon.devDependencies(options));
62
+ if (addon.scripts) {
63
+ Object.assign(scripts, addon.scripts(options));
64
+ }
74
65
  }
75
66
 
67
+ // Override versions from packageVersions if provided
68
+ const formatDep = (pkg: string): string => {
69
+ const ver = options.packageVersions?.[pkg];
70
+ return ver ? `${pkg}@${ver}` : pkg;
71
+ };
72
+
73
+ const resolvedDeps = [...new Set(dependencies)].map(formatDep);
74
+ const resolvedDevDeps = [...new Set(devDependencies)].map(formatDep);
75
+
76
+ // 1. package.json
77
+ await trackedWrite("package.json", packageJsonTemplate(options.projectName, scripts));
78
+
79
+ // 2. tsconfig.json
80
+ await trackedWrite("tsconfig.json", tsconfigTemplate());
81
+
82
+ // 3. .gitignore
83
+ await trackedWrite(".gitignore", gitignoreTemplate());
84
+
85
+ // 4. taserjs.config.ts
86
+ await trackedWrite("taserjs.config.ts", taserConfigTemplate());
87
+
88
+ // 5. vite.config.ts
89
+ await trackedWrite("vite.config.ts", viteConfigTemplate(preset));
90
+
91
+ // 6. nitro.config.ts (if preset is selected)
92
+ if (preset !== "none") {
93
+ await trackedWrite("nitro.config.ts", nitroConfigTemplate(preset));
94
+ }
95
+
96
+ // 7. Platform files (e.g. wrangler.jsonc)
76
97
  await Promise.all(
77
- deployEntry.files.map((file) =>
78
- write(
79
- path.join(root, file.name),
98
+ deployEntry.files.map(async (file) => {
99
+ const content =
80
100
  typeof file.content === "function"
81
101
  ? file.content({ projectName: options.projectName })
82
- : file.content,
83
- ),
84
- ),
102
+ : file.content;
103
+ await trackedWrite(file.name, content);
104
+ }),
85
105
  );
86
106
 
87
- const serverEntry = frameworkEntry.serverEntry;
88
- if (serverEntry) {
89
- await write(path.join(root, serverEntry.fileName), serverEntry.content);
90
- }
107
+ // 8. src/context.ts
108
+ await trackedWrite("src/context.ts", contextTemplate(bootBindings));
91
109
 
110
+ // 9. src/taser.ts
111
+ await trackedWrite("src/taser.ts", taserTsTemplate());
112
+
113
+ // 10. Routes: src/routes/index.get.ts & src/routes/$.ts
114
+ await trackedWrite("src/routes/index.get.ts", indexRouteTemplate());
115
+ await trackedWrite("src/routes/$.ts", rootLayoutTemplate());
116
+
117
+ // 12. Apply Addons (custom routes, db schemas, configs)
92
118
  await Promise.all(
93
119
  addons.map(async (addon) => {
94
- await addon.apply(ctx, (filePath, contents) => write(path.join(root, filePath), contents));
120
+ await addon.apply(options, async (relPath, contents) => {
121
+ await trackedWrite(relPath, contents);
122
+ });
95
123
  }),
96
124
  );
97
125
 
98
- try {
99
- await copyFile(path.join(root, ".env.example"), path.join(root, ".env"));
100
- } catch {
101
- // .env.example was not created
102
- }
103
-
104
- await writeProjectConfig(root, ctx);
126
+ // 13. Static routes.gen.ts starter manifest
127
+ await trackedWrite("src/.taserjs/routes.gen.ts", staticRoutesGenTemplate());
105
128
 
106
- if (options.skipInstall) {
107
- return ctx as ScaffoldResult;
129
+ // Install dependencies if not skipped
130
+ if (!options.skipInstall) {
131
+ const agent = options.agent ?? resolveUserAgent();
132
+ await installPackages(agent, root, {
133
+ dependencies: resolvedDeps,
134
+ devDependencies: resolvedDevDeps,
135
+ });
108
136
  }
109
137
 
110
- const agent = options.agent ?? resolveUserAgent();
111
- await installPackages(agent, root, {
112
- dependencies: packages.dependencies,
113
- devDependencies: packages.devDependencies,
114
- });
115
-
116
- return ctx as ScaffoldResult;
138
+ return {
139
+ ...options,
140
+ files: writtenFiles,
141
+ };
117
142
  }
@@ -1,32 +1,20 @@
1
- /**
2
- * Registry for the three scaffold dimensions — runtime, framework, deploy —
3
- * plus the compatibility rules between them.
4
- *
5
- * Dependency direction: deploy implies the runtime family; the effective
6
- * runtime constrains which frameworks can run. `--runtime` is an override
7
- * available only where it is meaningful (self-hosted node-family targets).
8
- */
9
- import { DEPLOY_TARGETS, type DeployTarget, type Framework, type Runtime } from "./types.js";
1
+ import { DEPLOY_TARGETS, type DeployTarget, type Runtime } from "./types.js";
10
2
 
11
- export type PlatformFile = {
3
+ export interface PlatformFile {
12
4
  name: string;
13
5
  content: string | ((ctx: { projectName: string }) => string);
14
- };
6
+ }
15
7
 
16
- export type DeployEntry = {
8
+ export interface DeployEntry {
17
9
  id: DeployTarget;
18
- /** Runtime this target builds for ("workerd" = Cloudflare's V8 runtime). */
19
10
  impliedRuntime: Runtime | "workerd";
20
- /** Whether the built output is a long-running server you start locally. */
21
11
  selfHosted: boolean;
22
- /** `start` script value; null for platform-deployed targets. */
23
12
  startScript: string | null;
24
- /** Runtime/platform tooling devDependencies beyond the base set. */
25
13
  devDeps: string[];
26
14
  files: PlatformFile[];
27
- };
15
+ }
28
16
 
29
- const NODE_START = "node .output/server/index.mjs";
17
+ const NITRO_NODE_START = "node .output/server/index.mjs";
30
18
 
31
19
  export const DEPLOY_ENTRIES: Record<DeployTarget, DeployEntry> = {
32
20
  none: {
@@ -34,23 +22,23 @@ export const DEPLOY_ENTRIES: Record<DeployTarget, DeployEntry> = {
34
22
  impliedRuntime: "node",
35
23
  selfHosted: true,
36
24
  startScript: "node dist/serve.mjs",
37
- devDeps: [],
25
+ devDeps: ["srvx"],
38
26
  files: [],
39
27
  },
40
28
  "node-server": {
41
29
  id: "node-server",
42
30
  impliedRuntime: "node",
43
31
  selfHosted: true,
44
- startScript: NODE_START,
45
- devDeps: [],
32
+ startScript: NITRO_NODE_START,
33
+ devDeps: ["nitro"],
46
34
  files: [],
47
35
  },
48
36
  "node-cluster": {
49
37
  id: "node-cluster",
50
38
  impliedRuntime: "node",
51
39
  selfHosted: true,
52
- startScript: NODE_START,
53
- devDeps: [],
40
+ startScript: NITRO_NODE_START,
41
+ devDeps: ["nitro"],
54
42
  files: [],
55
43
  },
56
44
  bun: {
@@ -58,7 +46,7 @@ export const DEPLOY_ENTRIES: Record<DeployTarget, DeployEntry> = {
58
46
  impliedRuntime: "bun",
59
47
  selfHosted: true,
60
48
  startScript: "bun .output/server/index.mjs",
61
- devDeps: ["@types/bun"],
49
+ devDeps: ["nitro", "@types/bun"],
62
50
  files: [],
63
51
  },
64
52
  "deno-server": {
@@ -66,7 +54,7 @@ export const DEPLOY_ENTRIES: Record<DeployTarget, DeployEntry> = {
66
54
  impliedRuntime: "deno",
67
55
  selfHosted: true,
68
56
  startScript: "deno run -A .output/server/index.mjs",
69
- devDeps: [],
57
+ devDeps: ["nitro"],
70
58
  files: [],
71
59
  },
72
60
  "deno-deploy": {
@@ -74,7 +62,7 @@ export const DEPLOY_ENTRIES: Record<DeployTarget, DeployEntry> = {
74
62
  impliedRuntime: "deno",
75
63
  selfHosted: false,
76
64
  startScript: null,
77
- devDeps: [],
65
+ devDeps: ["nitro"],
78
66
  files: [],
79
67
  },
80
68
  "cloudflare-module": {
@@ -82,7 +70,7 @@ export const DEPLOY_ENTRIES: Record<DeployTarget, DeployEntry> = {
82
70
  impliedRuntime: "workerd",
83
71
  selfHosted: false,
84
72
  startScript: null,
85
- devDeps: ["wrangler", "@cloudflare/workers-types"],
73
+ devDeps: ["nitro", "wrangler", "@cloudflare/workers-types"],
86
74
  files: [
87
75
  {
88
76
  name: "wrangler.jsonc",
@@ -105,7 +93,7 @@ export const DEPLOY_ENTRIES: Record<DeployTarget, DeployEntry> = {
105
93
  impliedRuntime: "node",
106
94
  selfHosted: false,
107
95
  startScript: null,
108
- devDeps: ["@vercel/node"],
96
+ devDeps: ["nitro", "@vercel/node"],
109
97
  files: [],
110
98
  },
111
99
  "aws-lambda": {
@@ -113,7 +101,7 @@ export const DEPLOY_ENTRIES: Record<DeployTarget, DeployEntry> = {
113
101
  impliedRuntime: "node",
114
102
  selfHosted: false,
115
103
  startScript: null,
116
- devDeps: ["@types/aws-lambda"],
104
+ devDeps: ["nitro", "@types/aws-lambda"],
117
105
  files: [],
118
106
  },
119
107
  netlify: {
@@ -121,49 +109,40 @@ export const DEPLOY_ENTRIES: Record<DeployTarget, DeployEntry> = {
121
109
  impliedRuntime: "node",
122
110
  selfHosted: false,
123
111
  startScript: null,
124
- devDeps: [],
112
+ devDeps: ["nitro"],
125
113
  files: [],
126
114
  },
127
115
  };
128
116
 
129
- /** Runtimes a `--runtime` override may select per self-hosted deploy target. */
130
117
  const RUNTIME_OVERRIDES: Partial<Record<DeployTarget, readonly Runtime[]>> = {
131
118
  none: ["node", "bun"],
132
119
  "node-server": ["node", "bun"],
133
120
  "node-cluster": ["node", "bun"],
134
121
  };
135
122
 
136
- export const DEFAULT_DEPLOY: DeployTarget = "node-server";
137
- export const DEFAULT_FRAMEWORK: Framework = "none";
123
+ export const DEFAULT_DEPLOY: DeployTarget = "none";
138
124
 
139
125
  export function isCuratedDeploy(value: string): value is DeployTarget {
140
126
  return (DEPLOY_TARGETS as readonly string[]).includes(value);
141
127
  }
142
128
 
143
- /**
144
- * Resolves any preset id to its emission entry. Curated ids come from the
145
- * registry; unknown strings pass through to Nitro verbatim as non-self-hosted
146
- * node-family targets.
147
- */
148
129
  export function resolveDeployEntry(id: string): { entry: DeployEntry; curated: boolean } {
149
130
  if (isCuratedDeploy(id)) {
150
131
  return { entry: DEPLOY_ENTRIES[id], curated: true };
151
132
  }
152
133
  return {
153
134
  entry: {
154
- // Cast: passthrough ids are valid Nitro PresetNameInputs by contract.
155
135
  id: id as DeployTarget,
156
136
  impliedRuntime: "node",
157
137
  selfHosted: false,
158
138
  startScript: null,
159
- devDeps: [],
139
+ devDeps: ["nitro"],
160
140
  files: [],
161
141
  },
162
142
  curated: false,
163
143
  };
164
144
  }
165
145
 
166
- /** Runtime overrides permitted for a deploy target; empty = no override. */
167
146
  export function allowedRuntimeOverrides(id: DeployTarget): readonly Runtime[] {
168
147
  return RUNTIME_OVERRIDES[id] ?? [];
169
148
  }
@@ -171,15 +150,8 @@ export function allowedRuntimeOverrides(id: DeployTarget): readonly Runtime[] {
171
150
  export type CombinationError = { ok: false; reason: string };
172
151
  export type CombinationOk = { ok: true; runtime: Runtime | "workerd" };
173
152
 
174
- /**
175
- * Validates a runtime × framework × deploy combination.
176
- *
177
- * @param runtimeOverride explicit `--runtime` selection, if any
178
- * @param deploy preset id (curated or passthrough)
179
- */
180
153
  export function validateCombination(
181
154
  runtimeOverride: Runtime | undefined,
182
- framework: Framework,
183
155
  deploy: string,
184
156
  ): CombinationOk | CombinationError {
185
157
  const { entry } = resolveDeployEntry(deploy);
@@ -199,13 +171,5 @@ export function validateCombination(
199
171
  }
200
172
 
201
173
  const effective = runtimeOverride ?? entry.impliedRuntime;
202
-
203
- if ((framework === "express" || framework === "fastify") && effective !== "node") {
204
- return {
205
- ok: false,
206
- reason: `Framework "${framework}" requires the Node runtime, but deploy target "${entry.id}" implies "${String(effective)}".`,
207
- };
208
- }
209
-
210
174
  return { ok: true, runtime: effective };
211
175
  }
package/src/core/types.ts CHANGED
@@ -1,18 +1,8 @@
1
1
  import type { Agent } from "package-manager-detector";
2
2
 
3
- /** Host framework layered on top of pure Taser.js pass-through dispatch. */
4
- export type Framework = "none" | "hono" | "express" | "fastify";
5
-
6
- export const FRAMEWORKS: readonly Framework[] = ["none", "hono", "express", "fastify"];
7
-
8
3
  export type Runtime = "node" | "bun" | "deno";
9
-
10
4
  export const RUNTIMES: readonly Runtime[] = ["node", "bun", "deno"];
11
5
 
12
- /**
13
- * Deployment target. Values are Nitro preset ids (see `nitro/config`
14
- * PresetNameInput) so `--preset` passes straight through to Nitro.
15
- */
16
6
  export type DeployTarget =
17
7
  | "none"
18
8
  | "node-server"
@@ -39,60 +29,35 @@ export const DEPLOY_TARGETS: readonly DeployTarget[] = [
39
29
  ];
40
30
 
41
31
  export type DbOdm = "drizzle" | "prisma" | "kysely";
42
-
43
32
  export const DB_ODMS: readonly DbOdm[] = ["drizzle", "prisma", "kysely"];
44
33
 
45
34
  export type DbDriver = "postgres" | "sqlite" | "mysql";
46
-
47
35
  export const DB_DRIVERS: readonly DbDriver[] = ["postgres", "sqlite", "mysql"];
48
-
49
36
  export const DEFAULT_DB_DRIVER: DbDriver = "sqlite";
50
37
 
51
38
  export type LoggerId = "pino" | "winston";
52
-
53
39
  export const LOGGERS: readonly LoggerId[] = ["pino", "winston"];
54
40
 
55
41
  export type ValidatorId = "zod" | "arktype" | "valibot";
56
-
57
42
  export const VALIDATORS: readonly ValidatorId[] = ["zod", "arktype", "valibot"];
58
43
 
59
- export type PackageGroups = {
60
- dependencies: string[];
61
- devDependencies: string[];
62
- scripts: Record<string, string>;
63
- };
64
-
65
- export type ScaffoldContext = {
44
+ export interface ScaffoldContext {
66
45
  projectName: string;
67
46
  targetDir: string;
68
- /** Host framework; "none" is pure Taser.js pass-through dispatch. Defaults to "none". */
69
- framework?: Framework;
70
- /** Deployment target — a Nitro preset id. Defaults to "node-server". */
71
- preset?: DeployTarget;
72
- /** Set only when explicitly overriding the runtime implied by the preset. */
73
- runtime?: Runtime;
74
- db?: DbOdm;
75
- driver?: DbDriver;
76
- logger?: LoggerId;
77
- validator?: ValidatorId;
78
- };
79
-
80
- export type ScaffoldOptions = ScaffoldContext & {
81
- skipInstall?: boolean;
82
- agent?: Agent;
83
- };
84
-
85
- export type ScaffoldResult = ScaffoldContext;
86
-
87
- export type CapabilitiesCatalog = {
88
- frameworks: Framework[];
89
- deployTargets: DeployTarget[];
90
- runtimes: Runtime[];
91
- db: {
92
- odms: DbOdm[];
93
- drivers: DbDriver[];
94
- defaultDriver: DbDriver;
95
- };
96
- loggers: LoggerId[];
97
- validators: ValidatorId[];
98
- };
47
+ preset?: DeployTarget | undefined;
48
+ runtime?: Runtime | undefined;
49
+ db?: DbOdm | undefined;
50
+ driver?: DbDriver | undefined;
51
+ logger?: LoggerId | undefined;
52
+ validator?: ValidatorId | undefined;
53
+ packageVersions?: Record<string, string> | undefined;
54
+ }
55
+
56
+ export interface ScaffoldOptions extends ScaffoldContext {
57
+ skipInstall?: boolean | undefined;
58
+ agent?: Agent | undefined;
59
+ }
60
+
61
+ export interface ScaffoldResult extends ScaffoldContext {
62
+ files: string[];
63
+ }
package/src/index.ts ADDED
@@ -0,0 +1,8 @@
1
+ export * from "./core/types.js";
2
+ export * from "./core/scaffold-engine.js";
3
+ export * from "./core/package-manager.js";
4
+ export * from "./core/targets.js";
5
+ export * from "./addons/types.js";
6
+ export * from "./addons/registry.js";
7
+ export * from "./commands/create.js";
8
+ export * from "./cli.js";