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,7 +1,6 @@
1
1
  import type { AddonDefinition } from "../types.js";
2
2
  import type { DbDriver } from "../../core/types.js";
3
3
 
4
- /** Latest Prisma ORM v7 release line — keep all @prisma/* packages on this range. */
5
4
  const PRISMA_VERSION = "^7.10.0";
6
5
 
7
6
  function prismaPackage(name: string): string {
@@ -59,53 +58,50 @@ function driverDevPackages(driver: DbDriver): string[] {
59
58
  function dbIndexSource(driver: DbDriver): string {
60
59
  switch (driver) {
61
60
  case "postgres":
62
- return `import { PrismaPg } from '@prisma/adapter-pg'
63
-
64
- import { PrismaClient } from './prisma/client.js'
61
+ return `import { PrismaPg } from "@prisma/adapter-pg";
62
+ import { PrismaClient } from "./prisma/client.js";
65
63
 
66
64
  export function createDb() {
67
65
  const adapter = new PrismaPg({
68
66
  connectionString: process.env.DATABASE_URL,
69
- })
70
- return new PrismaClient({ adapter })
67
+ });
68
+ return new PrismaClient({ adapter });
71
69
  }
72
70
  `;
73
71
  case "mysql":
74
- return `import { PrismaMariaDb } from '@prisma/adapter-mariadb'
75
-
76
- import { PrismaClient } from './prisma/client.js'
72
+ return `import { PrismaMariaDb } from "@prisma/adapter-mariadb";
73
+ import { PrismaClient } from "./prisma/client.js";
77
74
 
78
75
  export function createDb() {
79
- const adapter = new PrismaMariaDb(process.env.DATABASE_URL ?? 'mariadb://root:@localhost:3306/mydb')
80
- return new PrismaClient({ adapter })
76
+ const adapter = new PrismaMariaDb(process.env.DATABASE_URL ?? "mariadb://root:@localhost:3306/mydb");
77
+ return new PrismaClient({ adapter });
81
78
  }
82
79
  `;
83
80
  case "sqlite":
84
81
  default:
85
- return `import { PrismaBetterSqlite3 } from '@prisma/adapter-better-sqlite3'
86
-
87
- import { PrismaClient } from './prisma/client.js'
82
+ return `import { PrismaBetterSqlite3 } from "@prisma/adapter-better-sqlite3";
83
+ import { PrismaClient } from "./prisma/client.js";
88
84
 
89
85
  export function createDb() {
90
86
  const adapter = new PrismaBetterSqlite3({
91
- url: process.env.DATABASE_URL ?? 'file:./local.db',
92
- })
93
- return new PrismaClient({ adapter })
87
+ url: process.env.DATABASE_URL ?? "file:./local.db",
88
+ });
89
+ return new PrismaClient({ adapter });
94
90
  }
95
91
  `;
96
92
  }
97
93
  }
98
94
 
99
95
  function prismaConfigSource(): string {
100
- return `import 'dotenv/config'
101
- import { defineConfig, env } from 'prisma/config'
96
+ return `import "dotenv/config";
97
+ import { defineConfig, env } from "prisma/config";
102
98
 
103
99
  export default defineConfig({
104
- schema: 'prisma/schema.prisma',
100
+ schema: "prisma/schema.prisma",
105
101
  datasource: {
106
- url: env('DATABASE_URL'),
102
+ url: env("DATABASE_URL"),
107
103
  },
108
- })
104
+ });
109
105
  `;
110
106
  }
111
107
 
@@ -1,86 +1,50 @@
1
- import { arktypeAddon } from "./arktype/index.js";
2
1
  import { drizzleAddon } from "./drizzle/index.js";
3
2
  import { kyselyAddon } from "./kysely/index.js";
4
3
  import { pinoAddon } from "./pino/index.js";
5
4
  import { prismaAddon } from "./prisma/index.js";
6
- import { valibotAddon } from "./valibot/index.js";
5
+ import type { AddonDefinition, BootBinding } from "./types.js";
6
+ import { ValidatorAddon } from "./validators.js";
7
7
  import { winstonAddon } from "./winston/index.js";
8
- import { zodAddon } from "./zod/index.js";
9
- import type { AddonDefinition } from "./types.js";
10
- import type { CapabilitiesCatalog, ScaffoldContext } from "../core/types.js";
11
- import {
12
- DB_DRIVERS,
13
- DB_ODMS,
14
- DEFAULT_DB_DRIVER,
15
- DEPLOY_TARGETS,
16
- FRAMEWORKS,
17
- LOGGERS,
18
- RUNTIMES,
19
- VALIDATORS,
20
- } from "../core/types.js";
21
-
22
- const ALL_ADDONS: AddonDefinition[] = [
23
- drizzleAddon,
24
- prismaAddon,
25
- kyselyAddon,
26
- pinoAddon,
27
- winstonAddon,
28
- zodAddon,
29
- arktypeAddon,
30
- valibotAddon,
31
- ];
32
-
33
- const DB_ADDONS = ALL_ADDONS.filter((addon) => addon.category === "database");
34
- const LOGGER_ADDONS = ALL_ADDONS.filter((addon) => addon.category === "logger");
35
- const VALIDATOR_ADDONS = ALL_ADDONS.filter((addon) => addon.category === "validator");
36
-
37
- export function getCapabilitiesCatalog(): CapabilitiesCatalog {
38
- return {
39
- frameworks: [...FRAMEWORKS],
40
- deployTargets: [...DEPLOY_TARGETS],
41
- runtimes: [...RUNTIMES],
42
- db: {
43
- odms: [...DB_ODMS],
44
- drivers: [...DB_DRIVERS],
45
- defaultDriver: DEFAULT_DB_DRIVER,
46
- },
47
- loggers: [...LOGGERS],
48
- validators: [...VALIDATORS],
49
- };
50
- }
8
+ import type { ScaffoldContext } from "../core/types.js";
9
+
10
+ export const ADDONS: Record<string, AddonDefinition> = {
11
+ drizzle: drizzleAddon,
12
+ prisma: prismaAddon,
13
+ kysely: kyselyAddon,
14
+ pino: pinoAddon,
15
+ winston: winstonAddon,
16
+ zod: ValidatorAddon("zod"),
17
+ arktype: ValidatorAddon("arktype"),
18
+ valibot: ValidatorAddon("valibot"),
19
+ };
51
20
 
52
21
  export function resolveAddons(ctx: ScaffoldContext): AddonDefinition[] {
53
- const selected: AddonDefinition[] = [];
54
-
55
- if (ctx.db) {
56
- const dbAddon = DB_ADDONS.find((addon) => addon.id === ctx.db);
57
- if (!dbAddon) {
58
- throw new Error(`Unknown database addon "${ctx.db}"`);
59
- }
60
- selected.push(dbAddon);
22
+ const result: AddonDefinition[] = [];
23
+ if (ctx.db && ADDONS[ctx.db]) {
24
+ const addon = ADDONS[ctx.db];
25
+ if (addon) result.push(addon);
61
26
  }
62
-
63
- if (ctx.logger) {
64
- const loggerAddon = LOGGER_ADDONS.find((addon) => addon.id === ctx.logger);
65
- if (!loggerAddon) {
66
- throw new Error(`Unknown logger addon "${ctx.logger}"`);
67
- }
68
- selected.push(loggerAddon);
27
+ if (ctx.logger && ADDONS[ctx.logger]) {
28
+ const addon = ADDONS[ctx.logger];
29
+ if (addon) result.push(addon);
69
30
  }
70
-
71
- if (ctx.validator) {
72
- const validatorAddon = VALIDATOR_ADDONS.find((addon) => addon.id === ctx.validator);
73
- if (!validatorAddon) {
74
- throw new Error(`Unknown validator addon "${ctx.validator}"`);
75
- }
76
- selected.push(validatorAddon);
31
+ if (ctx.validator && ADDONS[ctx.validator]) {
32
+ const addon = ADDONS[ctx.validator];
33
+ if (addon) result.push(addon);
77
34
  }
78
-
79
- return selected;
35
+ return result;
80
36
  }
81
37
 
82
- export function collectBootBindings(ctx: ScaffoldContext) {
83
- return resolveAddons(ctx)
84
- .map((addon) => addon.bootBinding?.(ctx))
85
- .filter((v): v is NonNullable<typeof v> => Boolean(v));
38
+ export function collectBootBindings(ctx: ScaffoldContext): BootBinding[] {
39
+ const addons = resolveAddons(ctx);
40
+ const bindings: BootBinding[] = [];
41
+ for (const addon of addons) {
42
+ if (addon.bootBinding) {
43
+ const binding = addon.bootBinding(ctx);
44
+ if (binding) {
45
+ bindings.push(binding);
46
+ }
47
+ }
48
+ }
49
+ return bindings;
86
50
  }
@@ -1,19 +1,18 @@
1
- import type { ScaffoldContext } from "../core/types.js";
2
-
3
- export type BootBinding = {
1
+ export interface BootBinding {
4
2
  key: string;
5
3
  importPath: string;
6
4
  factoryName: string;
7
- };
8
-
9
- export type FileWriter = (filePath: string, contents: string) => Promise<void>;
5
+ }
10
6
 
11
- export type AddonDefinition = {
7
+ export interface AddonDefinition {
12
8
  id: string;
13
9
  category: "database" | "logger" | "validator";
14
- dependencies: (ctx: ScaffoldContext) => string[];
15
- devDependencies: (ctx: ScaffoldContext) => string[];
16
- scripts?: (ctx: ScaffoldContext) => Record<string, string>;
17
- bootBinding?: (ctx: ScaffoldContext) => BootBinding;
18
- apply: (ctx: ScaffoldContext, write: FileWriter) => Promise<void>;
19
- };
10
+ dependencies(ctx: import("../core/types.js").ScaffoldContext): string[];
11
+ devDependencies(ctx: import("../core/types.js").ScaffoldContext): string[];
12
+ scripts?(ctx: import("../core/types.js").ScaffoldContext): Record<string, string>;
13
+ bootBinding?(ctx: import("../core/types.js").ScaffoldContext): BootBinding | undefined;
14
+ apply(
15
+ ctx: import("../core/types.js").ScaffoldContext,
16
+ write: (path: string, content: string) => Promise<void> | void,
17
+ ): Promise<void>;
18
+ }
@@ -1,37 +1,36 @@
1
- import type { ValidatorId } from "../core/types";
2
- import type { AddonDefinition } from "./types";
1
+ import type { ValidatorId } from "../core/types.js";
2
+ import type { AddonDefinition } from "./types.js";
3
3
 
4
4
  export const IMPORT_LINES: Record<ValidatorId, string> = {
5
- zod: `import { z } from 'zod'`,
6
- arktype: `import { type } from 'arktype'`,
7
- valibot: `import * as v from 'valibot'`,
5
+ zod: `import { z } from "zod";`,
6
+ arktype: `import { type } from "arktype";`,
7
+ valibot: `import * as v from "valibot";`,
8
8
  };
9
9
 
10
- export const VALIDATION_BLOCK_TEMPLATE: Record<ValidatorId, string> = {
11
- zod: `
12
- .query(z.object({ name: z.string().default('Taser.js') }))`,
13
- arktype: `
14
- .query(type({ 'name?': 'string = "Taser.js"' }))`,
15
- valibot: `
16
- .query(v.object({ name: v.optional(v.string(), 'Taser.js') }))`,
10
+ export const QUERY_SCHEMA_EXPR: Record<ValidatorId, string> = {
11
+ zod: `z.object({ name: z.string().default("Taser.js") })`,
12
+ arktype: `type({ "name?": 'string = "Taser.js"' })`,
13
+ valibot: `v.object({ name: v.optional(v.string(), "Taser.js") })`,
17
14
  };
18
15
 
19
- const ROUTE_TEMPLATE = (validator: ValidatorId) => `import { t } from '@taserjs/router'
20
- import { json } from '@taserjs/router/reply'
21
- ${IMPORT_LINES[validator]}
22
-
23
- export default t.get('/')${VALIDATION_BLOCK_TEMPLATE[validator]}
24
- .handler((ctx) => {
25
- return json({ message: \`Hello, \${ctx.query.name}!\` })
26
- })
27
- `;
28
-
29
16
  export const ValidatorAddon = (validator: ValidatorId): AddonDefinition => {
30
17
  return {
31
18
  id: validator,
32
19
  category: "validator",
33
20
  dependencies: () => [validator],
34
21
  devDependencies: () => [],
35
- apply: (ctx, write) => write("src/routes/index.get.ts", ROUTE_TEMPLATE(validator)),
22
+ apply: async (_ctx, write) => {
23
+ const content = `import { t } from "@taserjs/router";
24
+ ${IMPORT_LINES[validator]}
25
+
26
+ export default t
27
+ .get("/")
28
+ .query(${QUERY_SCHEMA_EXPR[validator]})
29
+ .handler(({ req }) => {
30
+ return Response.json({ message: \`Hello, \${req.query.name}!\` });
31
+ });
32
+ `;
33
+ await write("src/routes/index.get.ts", content);
34
+ },
36
35
  };
37
36
  };
@@ -19,14 +19,14 @@ export const winstonAddon: AddonDefinition = {
19
19
  async apply(_ctx, write) {
20
20
  await write(
21
21
  "src/logger.ts",
22
- `import winston from 'winston'
22
+ `import winston from "winston";
23
23
 
24
24
  export function createLogger() {
25
25
  return winston.createLogger({
26
- level: process.env.LOG_LEVEL ?? 'info',
26
+ level: process.env.LOG_LEVEL ?? "info",
27
27
  format: winston.format.json(),
28
28
  transports: [new winston.transports.Console()],
29
- })
29
+ });
30
30
  }
31
31
  `,
32
32
  );
package/src/cli.ts CHANGED
@@ -1,62 +1,102 @@
1
1
  #!/usr/bin/env node
2
- import { parseArgs } from "node:util";
2
+ import yargs from "yargs";
3
+ import { hideBin } from "yargs/helpers";
4
+ import { runCreateCommand, type RunCreateCommandOptions } from "./commands/create.js";
5
+ import type {
6
+ DbDriver,
7
+ DbOdm,
8
+ DeployTarget,
9
+ LoggerId,
10
+ Runtime,
11
+ ValidatorId,
12
+ } from "./core/types.js";
3
13
 
4
- import * as p from "@clack/prompts";
5
- import color from "picocolors";
14
+ export async function run(argv: string[] = hideBin(process.argv)): Promise<void> {
15
+ const parser = yargs(argv)
16
+ .scriptName("create-taserjs")
17
+ .usage("$0 [dir] [options]")
18
+ .command(
19
+ "$0 [dir]",
20
+ "Scaffold a new Taser.js application",
21
+ (y: any) =>
22
+ y
23
+ .positional("dir", {
24
+ type: "string",
25
+ description: "Directory or project name",
26
+ })
27
+ .option("preset", {
28
+ alias: "p",
29
+ type: "string",
30
+ description: "Deployment preset",
31
+ })
32
+ .option("runtime", {
33
+ type: "string",
34
+ description: "Runtime override (node, bun, deno)",
35
+ })
36
+ .option("validator", {
37
+ alias: "v",
38
+ type: "string",
39
+ choices: ["zod", "valibot", "arktype", "none"],
40
+ description: "Standard Schema validator",
41
+ })
42
+ .option("db", {
43
+ type: "string",
44
+ choices: ["drizzle", "prisma", "kysely", "none"],
45
+ description: "Database ORM / Query builder",
46
+ })
47
+ .option("driver", {
48
+ type: "string",
49
+ choices: ["sqlite", "postgres", "mysql"],
50
+ description: "Database driver",
51
+ })
52
+ .option("logger", {
53
+ alias: "l",
54
+ type: "string",
55
+ choices: ["pino", "winston", "none"],
56
+ description: "Logger addon",
57
+ })
58
+ .option("skip-install", {
59
+ type: "boolean",
60
+ description: "Skip dependency installation",
61
+ default: false,
62
+ })
63
+ .option("yes", {
64
+ alias: "y",
65
+ type: "boolean",
66
+ description: "Skip prompts and use defaults",
67
+ default: false,
68
+ }),
69
+ async (args: any) => {
70
+ const createOpts: RunCreateCommandOptions = {
71
+ targetDir: args.dir as string | undefined,
72
+ projectName: args.dir as string | undefined,
73
+ preset: args.preset as DeployTarget | undefined,
74
+ runtime: args.runtime as Runtime | undefined,
75
+ validator: (args.validator === "none" ? undefined : args.validator) as
76
+ | ValidatorId
77
+ | undefined,
78
+ db: (args.db === "none" ? undefined : args.db) as DbOdm | undefined,
79
+ driver: args.driver as DbDriver | undefined,
80
+ logger: (args.logger === "none" ? undefined : args.logger) as LoggerId | undefined,
81
+ skipInstall: Boolean(args.skipInstall),
82
+ interactive: !args.yes,
83
+ };
84
+ await runCreateCommand(createOpts);
85
+ },
86
+ )
87
+ .help()
88
+ .alias("help", "h")
89
+ .version()
90
+ .alias("version", "V")
91
+ .strict()
92
+ .exitProcess(false);
6
93
 
7
- import { buildParsedArgsFromCli, runCreateCommand } from "./commands/create.js";
8
- import { printJsonError } from "./core/json-output.js";
94
+ await parser.parse();
95
+ }
9
96
 
10
- async function main(): Promise<void> {
11
- const { values, positionals } = parseArgs({
12
- args: process.argv.slice(2),
13
- options: {
14
- preset: { type: "string", short: "p" },
15
- db: { type: "string" },
16
- logger: { type: "string" },
17
- validator: { type: "string" },
18
- framework: { type: "string" },
19
- runtime: { type: "string" },
20
- y: { type: "boolean", short: "y" },
21
- noInstall: { type: "boolean" },
22
- json: { type: "boolean" },
23
- },
24
- allowPositionals: true,
97
+ if (process.argv[1] && process.argv[1].endsWith("cli.js")) {
98
+ run().catch((err: unknown) => {
99
+ console.error(err instanceof Error ? err.message : String(err));
100
+ process.exit(1);
25
101
  });
26
-
27
- const parsed = buildParsedArgsFromCli(
28
- {
29
- ...(values.preset !== undefined ? { preset: values.preset } : {}),
30
- ...(values.db !== undefined ? { db: values.db } : {}),
31
- ...(values.logger !== undefined ? { logger: values.logger } : {}),
32
- ...(values.validator !== undefined ? { validator: values.validator } : {}),
33
- ...(values.framework !== undefined ? { framework: values.framework } : {}),
34
- ...(values.runtime !== undefined ? { runtime: values.runtime } : {}),
35
- ...(values.y !== undefined ? { y: values.y } : {}),
36
- ...(values.noInstall !== undefined ? { noInstall: values.noInstall } : {}),
37
- ...(values.json !== undefined ? { json: values.json } : {}),
38
- },
39
- positionals,
40
- );
41
-
42
- if (!parsed.json) {
43
- console.clear();
44
- p.intro(color.bgCyan(color.black(" create-taserjs ")));
45
- }
46
-
47
- try {
48
- await runCreateCommand(parsed);
49
- } catch (error) {
50
- const message = error instanceof Error ? error.message : String(error);
51
- if (parsed.json) {
52
- printJsonError(message);
53
- process.exit(1);
54
- }
55
- throw error;
56
- }
57
102
  }
58
-
59
- main().catch((error: unknown) => {
60
- console.error(error);
61
- process.exit(1);
62
- });