create-taserjs 0.0.0 → 0.0.1

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 (61) hide show
  1. package/dist/cjs/addons/arktype/index.d.cts +1 -0
  2. package/dist/cjs/addons/registry.cjs +14 -4
  3. package/dist/cjs/addons/registry.cjs.map +1 -1
  4. package/dist/cjs/addons/types.d.cts +2 -2
  5. package/dist/cjs/addons/valibot/index.d.cts +1 -0
  6. package/dist/cjs/addons/validators.cjs +40 -0
  7. package/dist/cjs/addons/validators.cjs.map +1 -0
  8. package/dist/cjs/addons/validators.d.cts +5 -0
  9. package/dist/cjs/addons/zod/index.cjs +6 -0
  10. package/dist/cjs/addons/zod/index.cjs.map +1 -0
  11. package/dist/cjs/addons/zod/index.d.cts +1 -0
  12. package/dist/cjs/commands/create.cjs +33 -1
  13. package/dist/cjs/commands/create.cjs.map +1 -1
  14. package/dist/cjs/core/parse-options.cjs.map +1 -1
  15. package/dist/cjs/core/parse-options.d.cts +2 -1
  16. package/dist/cjs/core/resolve-packages.cjs +2 -1
  17. package/dist/cjs/core/resolve-packages.cjs.map +1 -1
  18. package/dist/cjs/core/scaffold-engine.cjs +2 -1
  19. package/dist/cjs/core/scaffold-engine.cjs.map +1 -1
  20. package/dist/cjs/core/types.cjs +6 -0
  21. package/dist/cjs/core/types.cjs.map +1 -1
  22. package/dist/cjs/core/types.d.cts +4 -0
  23. package/dist/cjs/templates/base.cjs +3 -7
  24. package/dist/cjs/templates/base.cjs.map +1 -1
  25. package/dist/esm/addons/arktype/index.d.ts +1 -0
  26. package/dist/esm/addons/registry.js +14 -4
  27. package/dist/esm/addons/registry.js.map +1 -1
  28. package/dist/esm/addons/types.d.ts +2 -2
  29. package/dist/esm/addons/valibot/index.d.ts +1 -0
  30. package/dist/esm/addons/validators.d.ts +5 -0
  31. package/dist/esm/addons/validators.js +38 -0
  32. package/dist/esm/addons/validators.js.map +1 -0
  33. package/dist/esm/addons/zod/index.d.ts +1 -0
  34. package/dist/esm/addons/zod/index.js +7 -0
  35. package/dist/esm/addons/zod/index.js.map +1 -0
  36. package/dist/esm/commands/create.js +34 -2
  37. package/dist/esm/commands/create.js.map +1 -1
  38. package/dist/esm/core/parse-options.d.ts +2 -1
  39. package/dist/esm/core/parse-options.js.map +1 -1
  40. package/dist/esm/core/resolve-packages.js +2 -1
  41. package/dist/esm/core/resolve-packages.js.map +1 -1
  42. package/dist/esm/core/scaffold-engine.js +2 -1
  43. package/dist/esm/core/scaffold-engine.js.map +1 -1
  44. package/dist/esm/core/types.d.ts +4 -0
  45. package/dist/esm/core/types.js +6 -1
  46. package/dist/esm/core/types.js.map +1 -1
  47. package/dist/esm/templates/base.js +3 -7
  48. package/dist/esm/templates/base.js.map +1 -1
  49. package/package.json +1 -1
  50. package/src/addons/arktype/index.ts +3 -0
  51. package/src/addons/registry.ts +21 -1
  52. package/src/addons/types.ts +2 -2
  53. package/src/addons/valibot/index.ts +3 -0
  54. package/src/addons/validators.ts +39 -0
  55. package/src/addons/zod/index.ts +3 -0
  56. package/src/commands/create.ts +26 -2
  57. package/src/core/parse-options.ts +2 -0
  58. package/src/core/resolve-packages.ts +1 -0
  59. package/src/core/scaffold-engine.ts +1 -0
  60. package/src/core/types.ts +6 -0
  61. package/src/templates/base.ts +3 -7
@@ -0,0 +1 @@
1
+ export declare const arktypeAddon: import('../types.js').AddonDefinition;
@@ -2,7 +2,8 @@ const require_index = require("./drizzle/index.cjs");
2
2
  const require_index$1 = require("./kysely/index.cjs");
3
3
  const require_index$2 = require("./pino/index.cjs");
4
4
  const require_index$3 = require("./prisma/index.cjs");
5
- const require_index$4 = require("./winston/index.cjs");
5
+ const require_index$4 = require("./zod/index.cjs");
6
+ const require_index$5 = require("./winston/index.cjs");
6
7
  const require_types = require("../core/types.cjs");
7
8
  //#region src/addons/registry.ts
8
9
  var ALL_ADDONS = [
@@ -10,10 +11,12 @@ var ALL_ADDONS = [
10
11
  require_index$3.prismaAddon,
11
12
  require_index$1.kyselyAddon,
12
13
  require_index$2.pinoAddon,
13
- require_index$4.winstonAddon
14
+ require_index$5.winstonAddon,
15
+ require_index$4.zodAddon
14
16
  ];
15
17
  var DB_ADDONS = ALL_ADDONS.filter((addon) => addon.category === "database");
16
18
  var LOGGER_ADDONS = ALL_ADDONS.filter((addon) => addon.category === "logger");
19
+ var VALIDATOR_ADDONS = ALL_ADDONS.filter((addon) => addon.category === "validator");
17
20
  function getCapabilitiesCatalog() {
18
21
  return {
19
22
  frameworks: [...require_types.FRAMEWORKS],
@@ -22,7 +25,8 @@ function getCapabilitiesCatalog() {
22
25
  drivers: [...require_types.DB_DRIVERS],
23
26
  defaultDriver: require_types.DEFAULT_DB_DRIVER
24
27
  },
25
- loggers: [...require_types.LOGGERS]
28
+ loggers: [...require_types.LOGGERS],
29
+ validators: [...require_types.VALIDATORS]
26
30
  };
27
31
  }
28
32
  function resolveAddons(ctx) {
@@ -39,10 +43,16 @@ function resolveAddons(ctx) {
39
43
  }
40
44
  if (selected.filter((addon) => addon.category === "database").length > 1) throw new Error("Only one database addon can be selected");
41
45
  if (selected.filter((addon) => addon.category === "logger").length > 1) throw new Error("Only one logger addon can be selected");
46
+ if (ctx.validator) {
47
+ const validatorAddon = VALIDATOR_ADDONS.find((addon) => addon.id === ctx.validator);
48
+ if (!validatorAddon) throw new Error(`Unknown validator addon "${ctx.validator}"`);
49
+ selected.push(validatorAddon);
50
+ }
51
+ if (selected.filter((addon) => addon.category === "validator").length > 1) throw new Error("Only one validator addon can be selected");
42
52
  return selected;
43
53
  }
44
54
  function collectBootBindings(ctx) {
45
- return resolveAddons(ctx).map((addon) => addon.bootBinding(ctx));
55
+ return resolveAddons(ctx).map((addon) => addon.bootBinding?.(ctx)).filter((v) => Boolean(v));
46
56
  }
47
57
  //#endregion
48
58
  exports.collectBootBindings = collectBootBindings;
@@ -1 +1 @@
1
- {"version":3,"file":"registry.cjs","names":[],"sources":["../../../src/addons/registry.ts"],"sourcesContent":["import { drizzleAddon } from './drizzle/index.js'\nimport { kyselyAddon } from './kysely/index.js'\nimport { pinoAddon } from './pino/index.js'\nimport { prismaAddon } from './prisma/index.js'\nimport type { AddonDefinition } from './types.js'\nimport { winstonAddon } from './winston/index.js'\nimport type { CapabilitiesCatalog, ScaffoldContext } from '../core/types.js'\nimport {\n DB_DRIVERS,\n DB_ODMS,\n DEFAULT_DB_DRIVER,\n FRAMEWORKS,\n LOGGERS,\n} from '../core/types.js'\n\nconst ALL_ADDONS: AddonDefinition[] = [\n drizzleAddon,\n prismaAddon,\n kyselyAddon,\n pinoAddon,\n winstonAddon,\n]\n\nconst DB_ADDONS = ALL_ADDONS.filter(addon => addon.category === 'database')\nconst LOGGER_ADDONS = ALL_ADDONS.filter(addon => addon.category === 'logger')\n\nexport function getCapabilitiesCatalog(): CapabilitiesCatalog {\n return {\n frameworks: [...FRAMEWORKS],\n db: {\n odms: [...DB_ODMS],\n drivers: [...DB_DRIVERS],\n defaultDriver: DEFAULT_DB_DRIVER,\n },\n loggers: [...LOGGERS],\n }\n}\n\nexport function resolveAddons(ctx: ScaffoldContext): AddonDefinition[] {\n const selected: AddonDefinition[] = []\n\n if (ctx.db) {\n const dbAddon = DB_ADDONS.find(addon => addon.id === ctx.db)\n if (!dbAddon) {\n throw new Error(`Unknown database addon \"${ctx.db}\"`)\n }\n selected.push(dbAddon)\n }\n\n if (ctx.logger) {\n const loggerAddon = LOGGER_ADDONS.find(addon => addon.id === ctx.logger)\n if (!loggerAddon) {\n throw new Error(`Unknown logger addon \"${ctx.logger}\"`)\n }\n selected.push(loggerAddon)\n }\n\n const dbCount = selected.filter(addon => addon.category === 'database').length\n if (dbCount > 1) {\n throw new Error('Only one database addon can be selected')\n }\n\n const loggerCount = selected.filter(addon => addon.category === 'logger').length\n if (loggerCount > 1) {\n throw new Error('Only one logger addon can be selected')\n }\n\n return selected\n}\n\nexport function collectBootBindings(ctx: ScaffoldContext) {\n return resolveAddons(ctx).map(addon => addon.bootBinding(ctx))\n}\n"],"mappings":";;;;;;;AAeA,IAAM,aAAgC;CACpC,cAAA;CACA,gBAAA;CACA,gBAAA;CACA,gBAAA;CACA,gBAAA;AACF;AAEA,IAAM,YAAY,WAAW,QAAO,UAAS,MAAM,aAAa,UAAU;AAC1E,IAAM,gBAAgB,WAAW,QAAO,UAAS,MAAM,aAAa,QAAQ;AAE5E,SAAgB,yBAA8C;CAC5D,OAAO;EACL,YAAY,CAAC,GAAG,cAAA,UAAU;EAC1B,IAAI;GACF,MAAM,CAAC,GAAG,cAAA,OAAO;GACjB,SAAS,CAAC,GAAG,cAAA,UAAU;GACvB,eAAe,cAAA;EACjB;EACA,SAAS,CAAC,GAAG,cAAA,OAAO;CACtB;AACF;AAEA,SAAgB,cAAc,KAAyC;CACrE,MAAM,WAA8B,CAAC;CAErC,IAAI,IAAI,IAAI;EACV,MAAM,UAAU,UAAU,MAAK,UAAS,MAAM,OAAO,IAAI,EAAE;EAC3D,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,2BAA2B,IAAI,GAAG,EAAE;EAEtD,SAAS,KAAK,OAAO;CACvB;CAEA,IAAI,IAAI,QAAQ;EACd,MAAM,cAAc,cAAc,MAAK,UAAS,MAAM,OAAO,IAAI,MAAM;EACvE,IAAI,CAAC,aACH,MAAM,IAAI,MAAM,yBAAyB,IAAI,OAAO,EAAE;EAExD,SAAS,KAAK,WAAW;CAC3B;CAGA,IADgB,SAAS,QAAO,UAAS,MAAM,aAAa,UAAU,CAAC,CAAC,SAC1D,GACZ,MAAM,IAAI,MAAM,yCAAyC;CAI3D,IADoB,SAAS,QAAO,UAAS,MAAM,aAAa,QAAQ,CAAC,CAAC,SACxD,GAChB,MAAM,IAAI,MAAM,uCAAuC;CAGzD,OAAO;AACT;AAEA,SAAgB,oBAAoB,KAAsB;CACxD,OAAO,cAAc,GAAG,CAAC,CAAC,KAAI,UAAS,MAAM,YAAY,GAAG,CAAC;AAC/D"}
1
+ {"version":3,"file":"registry.cjs","names":[],"sources":["../../../src/addons/registry.ts"],"sourcesContent":["import { drizzleAddon } from './drizzle/index.js'\nimport { kyselyAddon } from './kysely/index.js'\nimport { pinoAddon } from './pino/index.js'\nimport { prismaAddon } from './prisma/index.js'\nimport { zodAddon } from './zod/index.js'\nimport type { AddonDefinition } from './types.js'\nimport { winstonAddon } from './winston/index.js'\nimport type { CapabilitiesCatalog, ScaffoldContext } from '../core/types.js'\nimport {\n DB_DRIVERS,\n DB_ODMS,\n DEFAULT_DB_DRIVER,\n FRAMEWORKS,\n LOGGERS,\n VALIDATORS,\n} from '../core/types.js'\n\nconst ALL_ADDONS: AddonDefinition[] = [\n drizzleAddon,\n prismaAddon,\n kyselyAddon,\n pinoAddon,\n winstonAddon,\n zodAddon,\n]\n\nconst DB_ADDONS = ALL_ADDONS.filter(addon => addon.category === 'database')\nconst LOGGER_ADDONS = ALL_ADDONS.filter(addon => addon.category === 'logger')\nconst VALIDATOR_ADDONS = ALL_ADDONS.filter(addon => addon.category === 'validator')\n\nexport function getCapabilitiesCatalog(): CapabilitiesCatalog {\n return {\n frameworks: [...FRAMEWORKS],\n db: {\n odms: [...DB_ODMS],\n drivers: [...DB_DRIVERS],\n defaultDriver: DEFAULT_DB_DRIVER,\n },\n loggers: [...LOGGERS],\n validators: [...VALIDATORS],\n }\n}\n\nexport function resolveAddons(ctx: ScaffoldContext): AddonDefinition[] {\n const selected: AddonDefinition[] = []\n\n if (ctx.db) {\n const dbAddon = DB_ADDONS.find(addon => addon.id === ctx.db)\n if (!dbAddon) {\n throw new Error(`Unknown database addon \"${ctx.db}\"`)\n }\n selected.push(dbAddon)\n }\n\n if (ctx.logger) {\n const loggerAddon = LOGGER_ADDONS.find(addon => addon.id === ctx.logger)\n if (!loggerAddon) {\n throw new Error(`Unknown logger addon \"${ctx.logger}\"`)\n }\n selected.push(loggerAddon)\n }\n\n const dbCount = selected.filter(addon => addon.category === 'database').length\n if (dbCount > 1) {\n throw new Error('Only one database addon can be selected')\n }\n\n const loggerCount = selected.filter(addon => addon.category === 'logger').length\n if (loggerCount > 1) {\n throw new Error('Only one logger addon can be selected')\n }\n\n if (ctx.validator) {\n const validatorAddon = VALIDATOR_ADDONS.find(addon => addon.id === ctx.validator)\n if (!validatorAddon) {\n throw new Error(`Unknown validator addon \"${ctx.validator}\"`)\n }\n selected.push(validatorAddon)\n }\n\n const validatorCount = selected.filter(addon => addon.category === 'validator').length\n if (validatorCount > 1) {\n throw new Error('Only one validator addon can be selected')\n }\n\n return selected\n}\n\nexport function collectBootBindings(ctx: ScaffoldContext) {\n return resolveAddons(ctx)\n .map(addon => addon.bootBinding?.(ctx))\n .filter((v): v is NonNullable<typeof v> => Boolean(v))\n}\n"],"mappings":";;;;;;;;AAiBA,IAAM,aAAgC;CACpC,cAAA;CACA,gBAAA;CACA,gBAAA;CACA,gBAAA;CACA,gBAAA;CACA,gBAAA;AACF;AAEA,IAAM,YAAY,WAAW,QAAO,UAAS,MAAM,aAAa,UAAU;AAC1E,IAAM,gBAAgB,WAAW,QAAO,UAAS,MAAM,aAAa,QAAQ;AAC5E,IAAM,mBAAmB,WAAW,QAAO,UAAS,MAAM,aAAa,WAAW;AAElF,SAAgB,yBAA8C;CAC5D,OAAO;EACL,YAAY,CAAC,GAAG,cAAA,UAAU;EAC1B,IAAI;GACF,MAAM,CAAC,GAAG,cAAA,OAAO;GACjB,SAAS,CAAC,GAAG,cAAA,UAAU;GACvB,eAAe,cAAA;EACjB;EACA,SAAS,CAAC,GAAG,cAAA,OAAO;EACpB,YAAY,CAAC,GAAG,cAAA,UAAU;CAC5B;AACF;AAEA,SAAgB,cAAc,KAAyC;CACrE,MAAM,WAA8B,CAAC;CAErC,IAAI,IAAI,IAAI;EACV,MAAM,UAAU,UAAU,MAAK,UAAS,MAAM,OAAO,IAAI,EAAE;EAC3D,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,2BAA2B,IAAI,GAAG,EAAE;EAEtD,SAAS,KAAK,OAAO;CACvB;CAEA,IAAI,IAAI,QAAQ;EACd,MAAM,cAAc,cAAc,MAAK,UAAS,MAAM,OAAO,IAAI,MAAM;EACvE,IAAI,CAAC,aACH,MAAM,IAAI,MAAM,yBAAyB,IAAI,OAAO,EAAE;EAExD,SAAS,KAAK,WAAW;CAC3B;CAGA,IADgB,SAAS,QAAO,UAAS,MAAM,aAAa,UAAU,CAAC,CAAC,SAC1D,GACZ,MAAM,IAAI,MAAM,yCAAyC;CAI3D,IADoB,SAAS,QAAO,UAAS,MAAM,aAAa,QAAQ,CAAC,CAAC,SACxD,GAChB,MAAM,IAAI,MAAM,uCAAuC;CAGzD,IAAI,IAAI,WAAW;EACjB,MAAM,iBAAiB,iBAAiB,MAAK,UAAS,MAAM,OAAO,IAAI,SAAS;EAChF,IAAI,CAAC,gBACH,MAAM,IAAI,MAAM,4BAA4B,IAAI,UAAU,EAAE;EAE9D,SAAS,KAAK,cAAc;CAC9B;CAGA,IADuB,SAAS,QAAO,UAAS,MAAM,aAAa,WAAW,CAAC,CAAC,SAC3D,GACnB,MAAM,IAAI,MAAM,0CAA0C;CAG5D,OAAO;AACT;AAEA,SAAgB,oBAAoB,KAAsB;CACxD,OAAO,cAAc,GAAG,CAAC,CACtB,KAAI,UAAS,MAAM,cAAc,GAAG,CAAC,CAAC,CACtC,QAAQ,MAAkC,QAAQ,CAAC,CAAC;AACzD"}
@@ -7,10 +7,10 @@ export type BootBinding = {
7
7
  export type FileWriter = (filePath: string, contents: string) => Promise<void>;
8
8
  export type AddonDefinition = {
9
9
  id: string;
10
- category: 'database' | 'logger';
10
+ category: 'database' | 'logger' | 'validator';
11
11
  dependencies: (ctx: ScaffoldContext) => string[];
12
12
  devDependencies: (ctx: ScaffoldContext) => string[];
13
13
  scripts?: (ctx: ScaffoldContext) => Record<string, string>;
14
- bootBinding: (ctx: ScaffoldContext) => BootBinding;
14
+ bootBinding?: (ctx: ScaffoldContext) => BootBinding;
15
15
  apply: (ctx: ScaffoldContext, write: FileWriter) => Promise<void>;
16
16
  };
@@ -0,0 +1 @@
1
+ export declare const valibotAddon: import('../types.js').AddonDefinition;
@@ -0,0 +1,40 @@
1
+ //#region src/addons/validators.ts
2
+ var IMPORT_LINES = {
3
+ zod: `import { z } from 'zod'`,
4
+ arktype: `import { type } from 'arktype'`,
5
+ valibot: `import * as v from 'valibot'`
6
+ };
7
+ var VALIDATION_BLOCK_TEMPLATE = {
8
+ zod: `, {
9
+ query: z.object({ name: z.string() }),
10
+ }`,
11
+ arktype: `, {
12
+ query: type({ name: 'string' }),
13
+ }`,
14
+ valibot: `, {
15
+ query: v.object({ name: v.string() }),
16
+ }`
17
+ };
18
+ var ROUTE_TEMPLATE = (validator) => `
19
+ import { t } from '#src/taser.js'
20
+ ${IMPORT_LINES[validator]}
21
+
22
+ export const Route = t.get('/'${VALIDATION_BLOCK_TEMPLATE[validator]}).handler((ctx) => {
23
+ return ctx.reply.json({ message: \`Hello, \${ctx.query.name}!\` })
24
+ })
25
+ `;
26
+ var ValidatorAddon = (validator) => {
27
+ return {
28
+ id: validator,
29
+ category: "validator",
30
+ dependencies: () => [validator],
31
+ devDependencies: () => [],
32
+ apply: (ctx, write) => write("src/routes/index.get.ts", ROUTE_TEMPLATE(validator))
33
+ };
34
+ };
35
+ //#endregion
36
+ exports.IMPORT_LINES = IMPORT_LINES;
37
+ exports.VALIDATION_BLOCK_TEMPLATE = VALIDATION_BLOCK_TEMPLATE;
38
+ exports.ValidatorAddon = ValidatorAddon;
39
+
40
+ //# sourceMappingURL=validators.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.cjs","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() }),\n}`,\n arktype: `, {\n query: type({ name: 'string' }),\n}`,\n valibot: `, {\n query: v.object({ name: v.string() }),\n}`,\n}\n\nconst ROUTE_TEMPLATE = (validator: ValidatorId) => `\nimport { t } from '#src/taser.js'\n${IMPORT_LINES[validator]}\n\nexport const Route = t.get('/'${VALIDATION_BLOCK_TEMPLATE[validator]}).handler((ctx) => {\n return ctx.reply.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;;;CAGL,SAAS;;;CAGT,SAAS;;;AAGX;AAEA,IAAM,kBAAkB,cAA2B;;EAEjD,aAAa,WAAW;;gCAEM,0BAA0B,WAAW;;;;AAKrE,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"}
@@ -0,0 +1,5 @@
1
+ import { ValidatorId } from '../core/types.cjs';
2
+ import { AddonDefinition } from './types.cjs';
3
+ export declare const IMPORT_LINES: Record<ValidatorId, string>;
4
+ export declare const VALIDATION_BLOCK_TEMPLATE: Record<ValidatorId, string>;
5
+ export declare const ValidatorAddon: (validator: ValidatorId) => AddonDefinition;
@@ -0,0 +1,6 @@
1
+ //#region src/addons/zod/index.ts
2
+ var zodAddon = require("../validators.cjs").ValidatorAddon("zod");
3
+ //#endregion
4
+ exports.zodAddon = zodAddon;
5
+
6
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../../../../src/addons/zod/index.ts"],"sourcesContent":["import { ValidatorAddon } from '../validators.js'\n\nexport const zodAddon = ValidatorAddon('zod')\n"],"mappings":";AAEA,IAAa,sCAAW,CAAA,CAAA,eAAe,KAAK"}
@@ -0,0 +1 @@
1
+ export declare const zodAddon: import('../types.js').AddonDefinition;
@@ -25,6 +25,9 @@ function isDbDriver(value) {
25
25
  function isLoggerId(value) {
26
26
  return typeof value === "string" && require_types.LOGGERS.includes(value);
27
27
  }
28
+ function isValidatorId(value) {
29
+ return typeof value === "string" && require_types.VALIDATORS.includes(value);
30
+ }
28
31
  async function promptInteractiveOptions(args) {
29
32
  const projectName = args.projectName ?? await _clack_prompts.text({
30
33
  message: "Project name",
@@ -145,6 +148,34 @@ async function promptInteractiveOptions(args) {
145
148
  process.exit(0);
146
149
  }
147
150
  const logger = loggerChoice === "none" ? void 0 : isLoggerId(loggerChoice) ? loggerChoice : void 0;
151
+ const validatorChoice = args.validator ?? await _clack_prompts.select({
152
+ message: "Validator",
153
+ options: [
154
+ {
155
+ value: "none",
156
+ label: "None",
157
+ hint: "default"
158
+ },
159
+ {
160
+ value: "zod",
161
+ label: "Zod"
162
+ },
163
+ {
164
+ value: "arktype",
165
+ label: "Arktype"
166
+ },
167
+ {
168
+ value: "valibot",
169
+ label: "Valibot"
170
+ }
171
+ ],
172
+ initialValue: "none"
173
+ });
174
+ if (_clack_prompts.isCancel(validatorChoice)) {
175
+ _clack_prompts.cancel("Scaffold cancelled.");
176
+ process.exit(0);
177
+ }
178
+ const validator = validatorChoice === "none" ? void 0 : isValidatorId(validatorChoice) ? validatorChoice : void 0;
148
179
  return {
149
180
  projectName: String(projectName).trim(),
150
181
  framework,
@@ -155,7 +186,8 @@ async function promptInteractiveOptions(args) {
155
186
  db,
156
187
  driver
157
188
  } : {},
158
- ...logger ? { logger } : {}
189
+ ...logger ? { logger } : {},
190
+ ...validator ? { validator } : {}
159
191
  };
160
192
  }
161
193
  async function runCreateCommand(args) {
@@ -1 +1 @@
1
- {"version":3,"file":"create.cjs","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 { printCapabilitiesCatalog, printJsonError, printScaffoldResult } from '../core/json-output.js'\nimport {\n parseDbFlag,\n parseFrameworkFlag,\n parseLoggerFlag,\n type ParsedCreateArgs,\n resolveScaffoldDefaults,\n} from '../core/parse-options.js'\nimport { scaffoldProject } from '../core/scaffold-engine.js'\nimport type { DbDriver, DbOdm, Framework, LoggerId, ScaffoldResult } from '../core/types.js'\nimport { DB_DRIVERS, DB_ODMS, FRAMEWORKS, LOGGERS } from '../core/types.js'\nimport { validateProjectName } from '../core/validate-project-name.js'\nimport { resolveUserAgent, runScript } from '../core/package-manager.js'\n\nfunction isFramework(value: unknown): value is Framework {\n return typeof value === 'string' && (FRAMEWORKS 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\nasync function promptInteractiveOptions(\n args: ParsedCreateArgs,\n): Promise<ParsedCreateArgs> {\n const projectName = 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 = args.framework\n ?? await p.select({\n message: 'Framework adapter',\n options: [\n { value: 'node', label: 'Plain Node.js', hint: 'default' },\n { value: 'express', label: 'Express' },\n { value: 'hono', label: 'Hono' },\n { value: 'fastify', label: 'Fastify' },\n ],\n initialValue: 'node',\n })\n\n if (p.isCancel(framework) || !isFramework(framework)) {\n p.cancel('Scaffold cancelled.')\n process.exit(0)\n }\n\n const dbChoice = 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 = 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 = 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 = loggerChoice === 'none' ? undefined : isLoggerId(loggerChoice) ? loggerChoice : undefined\n\n return {\n projectName: String(projectName).trim(),\n framework,\n yes: args.yes,\n noInstall: args.noInstall,\n json: args.json,\n ...(db ? { db, driver: driver! } : {}),\n ...(logger ? { logger } : {}),\n }\n}\n\nexport async function runCreateCommand(args: ParsedCreateArgs): 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 framework: args.framework ?? '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(\n [\n `cd ${cdPath}`,\n runScript(resolveUserAgent(), 'dev'),\n ].join('\\n'),\n 'Next steps',\n )\n p.outro(color.green('Done.'))\n return result\n }\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(values: {\n framework?: string\n db?: string\n logger?: string\n y?: boolean\n noInstall?: boolean\n json?: boolean\n}, positionals: string[]): 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.framework) {\n args.framework = parseFrameworkFlag(values.framework)\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 return args\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"create.cjs","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 { printCapabilitiesCatalog, printJsonError, printScaffoldResult } from '../core/json-output.js'\nimport {\n parseDbFlag,\n parseFrameworkFlag,\n parseLoggerFlag,\n type ParsedCreateArgs,\n resolveScaffoldDefaults,\n} from '../core/parse-options.js'\nimport { scaffoldProject } from '../core/scaffold-engine.js'\nimport type { DbDriver, DbOdm, Framework, LoggerId, ScaffoldResult, ValidatorId } from '../core/types.js'\nimport { DB_DRIVERS, DB_ODMS, FRAMEWORKS, LOGGERS, VALIDATORS } from '../core/types.js'\nimport { validateProjectName } from '../core/validate-project-name.js'\nimport { resolveUserAgent, runScript } from '../core/package-manager.js'\n\nfunction isFramework(value: unknown): value is Framework {\n return typeof value === 'string' && (FRAMEWORKS 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(\n args: ParsedCreateArgs,\n): Promise<ParsedCreateArgs> {\n const projectName = 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 = args.framework\n ?? await p.select({\n message: 'Framework adapter',\n options: [\n { value: 'node', label: 'Plain Node.js', hint: 'default' },\n { value: 'express', label: 'Express' },\n { value: 'hono', label: 'Hono' },\n { value: 'fastify', label: 'Fastify' },\n ],\n initialValue: 'node',\n })\n\n if (p.isCancel(framework) || !isFramework(framework)) {\n p.cancel('Scaffold cancelled.')\n process.exit(0)\n }\n\n const dbChoice = 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 = 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 = 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 = loggerChoice === 'none' ? undefined : isLoggerId(loggerChoice) ? loggerChoice : undefined\n\n const validatorChoice = 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 = validatorChoice === 'none' ? undefined : isValidatorId(validatorChoice) ? validatorChoice : undefined\n\n return {\n projectName: String(projectName).trim(),\n framework,\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(args: ParsedCreateArgs): 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 framework: args.framework ?? '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(\n [\n `cd ${cdPath}`,\n runScript(resolveUserAgent(), 'dev'),\n ].join('\\n'),\n 'Next steps',\n )\n p.outro(color.green('Done.'))\n return result\n }\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(values: {\n framework?: string\n db?: string\n logger?: string\n y?: boolean\n noInstall?: boolean\n json?: boolean\n}, positionals: string[]): 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.framework) {\n args.framework = parseFrameworkFlag(values.framework)\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 return args\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"parse-options.cjs","names":[],"sources":["../../../src/core/parse-options.ts"],"sourcesContent":["import {\n DB_DRIVERS,\n DB_ODMS,\n DEFAULT_DB_DRIVER,\n FRAMEWORKS,\n LOGGERS,\n type DbDriver,\n type DbOdm,\n type Framework,\n type LoggerId,\n type ScaffoldContext,\n} from './types.js'\n\nexport type ParsedCreateArgs = {\n projectName?: string\n framework?: Framework\n db?: DbOdm\n driver?: DbDriver\n logger?: LoggerId\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 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\nexport function parseDbFlag(value: string): { db: DbOdm, driver: DbDriver } {\n const [odm, driver] = value.split(':')\n if (!odm || !isDbOdm(odm)) {\n throw new Error(`Invalid --db value \"${value}\". Use drizzle, prisma, or kysely (optionally with :postgres, :sqlite, or :mysql).`)\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 resolveScaffoldDefaults(args: ParsedCreateArgs): ScaffoldContext {\n const framework = args.framework ?? 'node'\n const db = args.db\n const logger = args.logger\n\n if (!args.projectName) {\n throw new Error('Project name is required')\n }\n\n const result: ScaffoldContext = {\n projectName: args.projectName.trim(),\n targetDir: '',\n framework,\n }\n\n if (db) {\n result.db = db\n result.driver = args.driver ?? DEFAULT_DB_DRIVER\n }\n\n if (logger) {\n result.logger = logger\n }\n\n return result\n}\n\nexport function parseFrameworkFlag(value: string): Framework {\n if (!isFramework(value)) {\n throw new Error(`Invalid --framework \"${value}\". Use node, express, hono, or fastify.`)\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"],"mappings":";;AAwBA,SAAS,YAAY,OAAmC;CACtD,OAAQ,cAAA,WAAiC,SAAS,KAAK;AACzD;AAEA,SAAS,QAAQ,OAA+B;CAC9C,OAAQ,cAAA,QAA8B,SAAS,KAAK;AACtD;AAEA,SAAS,WAAW,OAAkC;CACpD,OAAQ,cAAA,WAAiC,SAAS,KAAK;AACzD;AAEA,SAAS,WAAW,OAAkC;CACpD,OAAQ,cAAA,QAA8B,SAAS,KAAK;AACtD;AAEA,SAAgB,YAAY,OAAgD;CAC1E,MAAM,CAAC,KAAK,UAAU,MAAM,MAAM,GAAG;CACrC,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,GACtB,MAAM,IAAI,MAAM,uBAAuB,MAAM,mFAAmF;CAGlI,IAAI,WAAW,KAAA,KAAa,WAAW,IACrC,OAAO;EAAE,IAAI;EAAK,QAAQ,cAAA;CAAkB;CAG9C,IAAI,CAAC,WAAW,MAAM,GACpB,MAAM,IAAI,MAAM,4BAA4B,OAAO,mCAAmC;CAGxF,OAAO;EAAE,IAAI;EAAK;CAAO;AAC3B;AAEA,SAAgB,wBAAwB,MAAyC;CAC/E,MAAM,YAAY,KAAK,aAAa;CACpC,MAAM,KAAK,KAAK;CAChB,MAAM,SAAS,KAAK;CAEpB,IAAI,CAAC,KAAK,aACR,MAAM,IAAI,MAAM,0BAA0B;CAG5C,MAAM,SAA0B;EAC9B,aAAa,KAAK,YAAY,KAAK;EACnC,WAAW;EACX;CACF;CAEA,IAAI,IAAI;EACN,OAAO,KAAK;EACZ,OAAO,SAAS,KAAK,UAAA;CACvB;CAEA,IAAI,QACF,OAAO,SAAS;CAGlB,OAAO;AACT;AAEA,SAAgB,mBAAmB,OAA0B;CAC3D,IAAI,CAAC,YAAY,KAAK,GACpB,MAAM,IAAI,MAAM,wBAAwB,MAAM,wCAAwC;CAExF,OAAO;AACT;AAEA,SAAgB,gBAAgB,OAAyB;CACvD,IAAI,CAAC,WAAW,KAAK,GACnB,MAAM,IAAI,MAAM,qBAAqB,MAAM,wBAAwB;CAErE,OAAO;AACT"}
1
+ {"version":3,"file":"parse-options.cjs","names":[],"sources":["../../../src/core/parse-options.ts"],"sourcesContent":["import {\n DB_DRIVERS,\n DB_ODMS,\n DEFAULT_DB_DRIVER,\n FRAMEWORKS,\n LOGGERS,\n type DbDriver,\n type DbOdm,\n type Framework,\n type LoggerId,\n type ScaffoldContext,\n type ValidatorId,\n} from './types.js'\n\nexport type ParsedCreateArgs = {\n projectName?: string\n framework?: Framework\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 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\nexport function parseDbFlag(value: string): { db: DbOdm, driver: DbDriver } {\n const [odm, driver] = value.split(':')\n if (!odm || !isDbOdm(odm)) {\n throw new Error(`Invalid --db value \"${value}\". Use drizzle, prisma, or kysely (optionally with :postgres, :sqlite, or :mysql).`)\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 resolveScaffoldDefaults(args: ParsedCreateArgs): ScaffoldContext {\n const framework = args.framework ?? 'node'\n const db = args.db\n const logger = args.logger\n\n if (!args.projectName) {\n throw new Error('Project name is required')\n }\n\n const result: ScaffoldContext = {\n projectName: args.projectName.trim(),\n targetDir: '',\n framework,\n }\n\n if (db) {\n result.db = db\n result.driver = args.driver ?? DEFAULT_DB_DRIVER\n }\n\n if (logger) {\n result.logger = logger\n }\n\n return result\n}\n\nexport function parseFrameworkFlag(value: string): Framework {\n if (!isFramework(value)) {\n throw new Error(`Invalid --framework \"${value}\". Use node, express, hono, or fastify.`)\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"],"mappings":";;AA0BA,SAAS,YAAY,OAAmC;CACtD,OAAQ,cAAA,WAAiC,SAAS,KAAK;AACzD;AAEA,SAAS,QAAQ,OAA+B;CAC9C,OAAQ,cAAA,QAA8B,SAAS,KAAK;AACtD;AAEA,SAAS,WAAW,OAAkC;CACpD,OAAQ,cAAA,WAAiC,SAAS,KAAK;AACzD;AAEA,SAAS,WAAW,OAAkC;CACpD,OAAQ,cAAA,QAA8B,SAAS,KAAK;AACtD;AAEA,SAAgB,YAAY,OAAgD;CAC1E,MAAM,CAAC,KAAK,UAAU,MAAM,MAAM,GAAG;CACrC,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,GACtB,MAAM,IAAI,MAAM,uBAAuB,MAAM,mFAAmF;CAGlI,IAAI,WAAW,KAAA,KAAa,WAAW,IACrC,OAAO;EAAE,IAAI;EAAK,QAAQ,cAAA;CAAkB;CAG9C,IAAI,CAAC,WAAW,MAAM,GACpB,MAAM,IAAI,MAAM,4BAA4B,OAAO,mCAAmC;CAGxF,OAAO;EAAE,IAAI;EAAK;CAAO;AAC3B;AAEA,SAAgB,wBAAwB,MAAyC;CAC/E,MAAM,YAAY,KAAK,aAAa;CACpC,MAAM,KAAK,KAAK;CAChB,MAAM,SAAS,KAAK;CAEpB,IAAI,CAAC,KAAK,aACR,MAAM,IAAI,MAAM,0BAA0B;CAG5C,MAAM,SAA0B;EAC9B,aAAa,KAAK,YAAY,KAAK;EACnC,WAAW;EACX;CACF;CAEA,IAAI,IAAI;EACN,OAAO,KAAK;EACZ,OAAO,SAAS,KAAK,UAAA;CACvB;CAEA,IAAI,QACF,OAAO,SAAS;CAGlB,OAAO;AACT;AAEA,SAAgB,mBAAmB,OAA0B;CAC3D,IAAI,CAAC,YAAY,KAAK,GACpB,MAAM,IAAI,MAAM,wBAAwB,MAAM,wCAAwC;CAExF,OAAO;AACT;AAEA,SAAgB,gBAAgB,OAAyB;CACvD,IAAI,CAAC,WAAW,KAAK,GACnB,MAAM,IAAI,MAAM,qBAAqB,MAAM,wBAAwB;CAErE,OAAO;AACT"}
@@ -1,10 +1,11 @@
1
- import { DbDriver, DbOdm, Framework, LoggerId, ScaffoldContext } from './types.js';
1
+ import { DbDriver, DbOdm, Framework, LoggerId, ScaffoldContext, ValidatorId } from './types.js';
2
2
  export type ParsedCreateArgs = {
3
3
  projectName?: string;
4
4
  framework?: Framework;
5
5
  db?: DbOdm;
6
6
  driver?: DbDriver;
7
7
  logger?: LoggerId;
8
+ validator?: ValidatorId;
8
9
  yes: boolean;
9
10
  noInstall: boolean;
10
11
  json: boolean;
@@ -7,7 +7,8 @@ function frameworkPackages(framework) {
7
7
  "npm-run-all2",
8
8
  "tsdown",
9
9
  "tsx",
10
- "typescript"
10
+ "typescript",
11
+ "@types/node"
11
12
  ];
12
13
  const scripts = {};
13
14
  switch (framework) {
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-packages.cjs","names":[],"sources":["../../../src/core/resolve-packages.ts"],"sourcesContent":["import { resolveAddons } from '../addons/registry.js'\nimport type { PackageGroups, ScaffoldContext, Framework } from '../core/types.js'\n\nfunction frameworkPackages(framework: Framework): PackageGroups {\n const dependencies = ['@taserjs/router']\n const devDependencies = [\n '@taserjs/router-cli',\n 'npm-run-all2',\n 'tsdown',\n 'tsx',\n 'typescript',\n ]\n const scripts: Record<string, string> = {}\n\n switch (framework) {\n case 'express':\n dependencies.push('@taserjs/adapter-express', 'express')\n devDependencies.push('@types/express')\n break\n case 'hono':\n dependencies.push('@hono/node-server', 'hono')\n break\n case 'fastify':\n dependencies.push('@taserjs/adapter-fastify', 'fastify')\n break\n case 'node':\n default:\n dependencies.push('@taserjs/adapter-node')\n break\n }\n\n return { dependencies, devDependencies, scripts }\n}\n\nexport function resolvePackages(ctx: ScaffoldContext): PackageGroups {\n const base = frameworkPackages(ctx.framework)\n const addons = resolveAddons(ctx)\n\n const dependencies = [...base.dependencies]\n const devDependencies = [...base.devDependencies]\n const scripts = { ...base.scripts }\n\n for (const addon of addons) {\n dependencies.push(...addon.dependencies(ctx))\n devDependencies.push(...addon.devDependencies(ctx))\n if (addon.scripts) {\n Object.assign(scripts, addon.scripts(ctx))\n }\n }\n\n return {\n dependencies: [...new Set(dependencies)],\n devDependencies: [...new Set(devDependencies)],\n scripts,\n }\n}\n\n// Backward-compatible export for tests during migration\nexport function getPackageGroups(framework: Framework): Omit<PackageGroups, 'scripts'> & { scripts?: Record<string, string> } {\n const groups = frameworkPackages(framework)\n return groups\n}\n"],"mappings":";;AAGA,SAAS,kBAAkB,WAAqC;CAC9D,MAAM,eAAe,CAAC,iBAAiB;CACvC,MAAM,kBAAkB;EACtB;EACA;EACA;EACA;EACA;CACF;CACA,MAAM,UAAkC,CAAC;CAEzC,QAAQ,WAAR;EACE,KAAK;GACH,aAAa,KAAK,4BAA4B,SAAS;GACvD,gBAAgB,KAAK,gBAAgB;GACrC;EACF,KAAK;GACH,aAAa,KAAK,qBAAqB,MAAM;GAC7C;EACF,KAAK;GACH,aAAa,KAAK,4BAA4B,SAAS;GACvD;EAEF,SACE,aAAa,KAAK,uBAAuB;CAE7C;CAEA,OAAO;EAAE;EAAc;EAAiB;CAAQ;AAClD;AAEA,SAAgB,gBAAgB,KAAqC;CACnE,MAAM,OAAO,kBAAkB,IAAI,SAAS;CAC5C,MAAM,SAAS,iBAAA,cAAc,GAAG;CAEhC,MAAM,eAAe,CAAC,GAAG,KAAK,YAAY;CAC1C,MAAM,kBAAkB,CAAC,GAAG,KAAK,eAAe;CAChD,MAAM,UAAU,EAAE,GAAG,KAAK,QAAQ;CAElC,KAAK,MAAM,SAAS,QAAQ;EAC1B,aAAa,KAAK,GAAG,MAAM,aAAa,GAAG,CAAC;EAC5C,gBAAgB,KAAK,GAAG,MAAM,gBAAgB,GAAG,CAAC;EAClD,IAAI,MAAM,SACR,OAAO,OAAO,SAAS,MAAM,QAAQ,GAAG,CAAC;CAE7C;CAEA,OAAO;EACL,cAAc,CAAC,GAAG,IAAI,IAAI,YAAY,CAAC;EACvC,iBAAiB,CAAC,GAAG,IAAI,IAAI,eAAe,CAAC;EAC7C;CACF;AACF"}
1
+ {"version":3,"file":"resolve-packages.cjs","names":[],"sources":["../../../src/core/resolve-packages.ts"],"sourcesContent":["import { resolveAddons } from '../addons/registry.js'\nimport type { PackageGroups, ScaffoldContext, Framework } from '../core/types.js'\n\nfunction frameworkPackages(framework: Framework): PackageGroups {\n const dependencies = ['@taserjs/router']\n const devDependencies = [\n '@taserjs/router-cli',\n 'npm-run-all2',\n 'tsdown',\n 'tsx',\n 'typescript',\n '@types/node',\n ]\n const scripts: Record<string, string> = {}\n\n switch (framework) {\n case 'express':\n dependencies.push('@taserjs/adapter-express', 'express')\n devDependencies.push('@types/express')\n break\n case 'hono':\n dependencies.push('@hono/node-server', 'hono')\n break\n case 'fastify':\n dependencies.push('@taserjs/adapter-fastify', 'fastify')\n break\n case 'node':\n default:\n dependencies.push('@taserjs/adapter-node')\n break\n }\n\n return { dependencies, devDependencies, scripts }\n}\n\nexport function resolvePackages(ctx: ScaffoldContext): PackageGroups {\n const base = frameworkPackages(ctx.framework)\n const addons = resolveAddons(ctx)\n\n const dependencies = [...base.dependencies]\n const devDependencies = [...base.devDependencies]\n const scripts = { ...base.scripts }\n\n for (const addon of addons) {\n dependencies.push(...addon.dependencies(ctx))\n devDependencies.push(...addon.devDependencies(ctx))\n if (addon.scripts) {\n Object.assign(scripts, addon.scripts(ctx))\n }\n }\n\n return {\n dependencies: [...new Set(dependencies)],\n devDependencies: [...new Set(devDependencies)],\n scripts,\n }\n}\n\n// Backward-compatible export for tests during migration\nexport function getPackageGroups(framework: Framework): Omit<PackageGroups, 'scripts'> & { scripts?: Record<string, string> } {\n const groups = frameworkPackages(framework)\n return groups\n}\n"],"mappings":";;AAGA,SAAS,kBAAkB,WAAqC;CAC9D,MAAM,eAAe,CAAC,iBAAiB;CACvC,MAAM,kBAAkB;EACtB;EACA;EACA;EACA;EACA;EACA;CACF;CACA,MAAM,UAAkC,CAAC;CAEzC,QAAQ,WAAR;EACE,KAAK;GACH,aAAa,KAAK,4BAA4B,SAAS;GACvD,gBAAgB,KAAK,gBAAgB;GACrC;EACF,KAAK;GACH,aAAa,KAAK,qBAAqB,MAAM;GAC7C;EACF,KAAK;GACH,aAAa,KAAK,4BAA4B,SAAS;GACvD;EAEF,SACE,aAAa,KAAK,uBAAuB;CAE7C;CAEA,OAAO;EAAE;EAAc;EAAiB;CAAQ;AAClD;AAEA,SAAgB,gBAAgB,KAAqC;CACnE,MAAM,OAAO,kBAAkB,IAAI,SAAS;CAC5C,MAAM,SAAS,iBAAA,cAAc,GAAG;CAEhC,MAAM,eAAe,CAAC,GAAG,KAAK,YAAY;CAC1C,MAAM,kBAAkB,CAAC,GAAG,KAAK,eAAe;CAChD,MAAM,UAAU,EAAE,GAAG,KAAK,QAAQ;CAElC,KAAK,MAAM,SAAS,QAAQ;EAC1B,aAAa,KAAK,GAAG,MAAM,aAAa,GAAG,CAAC;EAC5C,gBAAgB,KAAK,GAAG,MAAM,gBAAgB,GAAG,CAAC;EAClD,IAAI,MAAM,SACR,OAAO,OAAO,SAAS,MAAM,QAAQ,GAAG,CAAC;CAE7C;CAEA,OAAO;EACL,cAAc,CAAC,GAAG,IAAI,IAAI,YAAY,CAAC;EACvC,iBAAiB,CAAC,GAAG,IAAI,IAAI,eAAe,CAAC;EAC7C;CACF;AACF"}
@@ -23,7 +23,8 @@ async function scaffoldProject(options) {
23
23
  db: options.db,
24
24
  driver: options.driver
25
25
  } : {},
26
- ...options.logger ? { logger: options.logger } : {}
26
+ ...options.logger ? { logger: options.logger } : {},
27
+ ...options.validator ? { validator: options.validator } : {}
27
28
  };
28
29
  const addons = require_registry.resolveAddons(ctx);
29
30
  const packages = require_resolve_packages.resolvePackages(ctx);
@@ -1 +1 @@
1
- {"version":3,"file":"scaffold-engine.cjs","names":[],"sources":["../../../src/core/scaffold-engine.ts"],"sourcesContent":["import { mkdir, writeFile } from 'node:fs/promises'\nimport path from 'node:path'\n\nimport { collectBootBindings, resolveAddons } from '../addons/registry.js'\nimport { indexTemplate, taserTsTemplate } from '../frameworks/index.js'\nimport { installPackages, resolveUserAgent } from './package-manager.js'\nimport { writeProjectConfig } from './project-config.js'\nimport { resolvePackages } from './resolve-packages.js'\nimport type { ScaffoldOptions, ScaffoldResult } from './types.js'\nimport {\n contextTemplate,\n gitignoreTemplate,\n healthRouteTemplate,\n indexRouteTemplate,\n packageJsonTemplate,\n rootLayoutTemplate,\n starterManifestTemplate,\n tsconfigTemplate,\n tsdownConfigTemplate,\n} from '../templates/base.js'\n\nasync function write(filePath: string, contents: string): Promise<void> {\n await mkdir(path.dirname(filePath), { recursive: true })\n await writeFile(filePath, contents, 'utf8')\n}\n\nexport async function scaffoldProject(options: ScaffoldOptions): Promise<ScaffoldResult> {\n const root = options.targetDir\n const ctx = {\n projectName: options.projectName,\n targetDir: root,\n framework: options.framework,\n ...(options.db ? { db: options.db, driver: options.driver } : {}),\n ...(options.logger ? { logger: options.logger } : {}),\n }\n\n const addons = resolveAddons(ctx)\n const packages = resolvePackages(ctx)\n const bootBindings = collectBootBindings(ctx)\n\n await write(path.join(root, 'package.json'), packageJsonTemplate(options.projectName, packages.scripts))\n await write(path.join(root, 'tsconfig.json'), tsconfigTemplate())\n await write(path.join(root, 'tsdown.config.ts'), tsdownConfigTemplate())\n await write(path.join(root, '.gitignore'), gitignoreTemplate())\n await write(path.join(root, 'src/context.ts'), contextTemplate(bootBindings))\n await write(path.join(root, 'src/taser.ts'), taserTsTemplate(options.framework))\n await write(path.join(root, 'src/index.ts'), indexTemplate(options.framework))\n await write(path.join(root, 'src/routes/$.ts'), rootLayoutTemplate())\n await write(path.join(root, 'src/routes/index.get.ts'), indexRouteTemplate())\n await write(path.join(root, 'src/routes/health.get.ts'), healthRouteTemplate(ctx))\n await write(path.join(root, 'src/routeManifest.gen.ts'), starterManifestTemplate())\n\n for (const addon of addons) {\n await addon.apply(ctx, (filePath, contents) => write(path.join(root, filePath), contents))\n }\n\n await writeProjectConfig(root, ctx)\n\n if (options.skipInstall) {\n return {\n projectName: ctx.projectName,\n targetDir: root,\n framework: ctx.framework,\n ...(ctx.db ? { db: ctx.db, driver: ctx.driver } : {}),\n ...(ctx.logger ? { logger: ctx.logger } : {}),\n }\n }\n\n const agent = options.agent ?? resolveUserAgent()\n await installPackages(agent, root, {\n dependencies: packages.dependencies,\n devDependencies: packages.devDependencies,\n })\n\n return {\n projectName: ctx.projectName,\n targetDir: root,\n framework: ctx.framework,\n ...(ctx.db ? { db: ctx.db, driver: ctx.driver } : {}),\n ...(ctx.logger ? { logger: ctx.logger } : {}),\n }\n}\n"],"mappings":";;;;;;;;;;;AAqBA,eAAe,MAAM,UAAkB,UAAiC;CACtE,OAAA,GAAM,iBAAA,MAAA,CAAM,UAAA,QAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;CACvD,OAAA,GAAM,iBAAA,UAAA,CAAU,UAAU,UAAU,MAAM;AAC5C;AAEA,eAAsB,gBAAgB,SAAmD;CACvF,MAAM,OAAO,QAAQ;CACrB,MAAM,MAAM;EACV,aAAa,QAAQ;EACrB,WAAW;EACX,WAAW,QAAQ;EACnB,GAAI,QAAQ,KAAK;GAAE,IAAI,QAAQ;GAAI,QAAQ,QAAQ;EAAO,IAAI,CAAC;EAC/D,GAAI,QAAQ,SAAS,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;CACrD;CAEA,MAAM,SAAS,iBAAA,cAAc,GAAG;CAChC,MAAM,WAAW,yBAAA,gBAAgB,GAAG;CACpC,MAAM,eAAe,iBAAA,oBAAoB,GAAG;CAE5C,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,cAAc,GAAG,aAAA,oBAAoB,QAAQ,aAAa,SAAS,OAAO,CAAC;CACvG,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,eAAe,GAAG,aAAA,iBAAiB,CAAC;CAChE,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,kBAAkB,GAAG,aAAA,qBAAqB,CAAC;CACvE,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,YAAY,GAAG,aAAA,kBAAkB,CAAC;CAC9D,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,gBAAgB,GAAG,aAAA,gBAAgB,YAAY,CAAC;CAC5E,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,cAAc,GAAG,cAAA,gBAAgB,QAAQ,SAAS,CAAC;CAC/E,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,cAAc,GAAG,cAAA,cAAc,QAAQ,SAAS,CAAC;CAC7E,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,iBAAiB,GAAG,aAAA,mBAAmB,CAAC;CACpE,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,yBAAyB,GAAG,aAAA,mBAAmB,CAAC;CAC5E,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,0BAA0B,GAAG,aAAA,oBAAoB,GAAG,CAAC;CACjF,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,0BAA0B,GAAG,aAAA,wBAAwB,CAAC;CAElF,KAAK,MAAM,SAAS,QAClB,MAAM,MAAM,MAAM,MAAM,UAAU,aAAa,MAAM,UAAA,QAAK,KAAK,MAAM,QAAQ,GAAG,QAAQ,CAAC;CAG3F,MAAM,uBAAA,mBAAmB,MAAM,GAAG;CAElC,IAAI,QAAQ,aACV,OAAO;EACL,aAAa,IAAI;EACjB,WAAW;EACX,WAAW,IAAI;EACf,GAAI,IAAI,KAAK;GAAE,IAAI,IAAI;GAAI,QAAQ,IAAI;EAAO,IAAI,CAAC;EACnD,GAAI,IAAI,SAAS,EAAE,QAAQ,IAAI,OAAO,IAAI,CAAC;CAC7C;CAGF,MAAM,QAAQ,QAAQ,SAAS,wBAAA,iBAAiB;CAChD,MAAM,wBAAA,gBAAgB,OAAO,MAAM;EACjC,cAAc,SAAS;EACvB,iBAAiB,SAAS;CAC5B,CAAC;CAED,OAAO;EACL,aAAa,IAAI;EACjB,WAAW;EACX,WAAW,IAAI;EACf,GAAI,IAAI,KAAK;GAAE,IAAI,IAAI;GAAI,QAAQ,IAAI;EAAO,IAAI,CAAC;EACnD,GAAI,IAAI,SAAS,EAAE,QAAQ,IAAI,OAAO,IAAI,CAAC;CAC7C;AACF"}
1
+ {"version":3,"file":"scaffold-engine.cjs","names":[],"sources":["../../../src/core/scaffold-engine.ts"],"sourcesContent":["import { mkdir, writeFile } from 'node:fs/promises'\nimport path from 'node:path'\n\nimport { collectBootBindings, resolveAddons } from '../addons/registry.js'\nimport { indexTemplate, taserTsTemplate } from '../frameworks/index.js'\nimport { installPackages, resolveUserAgent } from './package-manager.js'\nimport { writeProjectConfig } from './project-config.js'\nimport { resolvePackages } from './resolve-packages.js'\nimport type { ScaffoldOptions, ScaffoldResult } from './types.js'\nimport {\n contextTemplate,\n gitignoreTemplate,\n healthRouteTemplate,\n indexRouteTemplate,\n packageJsonTemplate,\n rootLayoutTemplate,\n starterManifestTemplate,\n tsconfigTemplate,\n tsdownConfigTemplate,\n} from '../templates/base.js'\n\nasync function write(filePath: string, contents: string): Promise<void> {\n await mkdir(path.dirname(filePath), { recursive: true })\n await writeFile(filePath, contents, 'utf8')\n}\n\nexport async function scaffoldProject(options: ScaffoldOptions): Promise<ScaffoldResult> {\n const root = options.targetDir\n const ctx = {\n projectName: options.projectName,\n targetDir: root,\n framework: options.framework,\n ...(options.db ? { db: options.db, driver: options.driver } : {}),\n ...(options.logger ? { logger: options.logger } : {}),\n ...(options.validator ? { validator: options.validator } : {}),\n }\n\n const addons = resolveAddons(ctx)\n const packages = resolvePackages(ctx)\n const bootBindings = collectBootBindings(ctx)\n\n await write(path.join(root, 'package.json'), packageJsonTemplate(options.projectName, packages.scripts))\n await write(path.join(root, 'tsconfig.json'), tsconfigTemplate())\n await write(path.join(root, 'tsdown.config.ts'), tsdownConfigTemplate())\n await write(path.join(root, '.gitignore'), gitignoreTemplate())\n await write(path.join(root, 'src/context.ts'), contextTemplate(bootBindings))\n await write(path.join(root, 'src/taser.ts'), taserTsTemplate(options.framework))\n await write(path.join(root, 'src/index.ts'), indexTemplate(options.framework))\n await write(path.join(root, 'src/routes/$.ts'), rootLayoutTemplate())\n await write(path.join(root, 'src/routes/index.get.ts'), indexRouteTemplate())\n await write(path.join(root, 'src/routes/health.get.ts'), healthRouteTemplate(ctx))\n await write(path.join(root, 'src/routeManifest.gen.ts'), starterManifestTemplate())\n\n for (const addon of addons) {\n await addon.apply(ctx, (filePath, contents) => write(path.join(root, filePath), contents))\n }\n\n await writeProjectConfig(root, ctx)\n\n if (options.skipInstall) {\n return {\n projectName: ctx.projectName,\n targetDir: root,\n framework: ctx.framework,\n ...(ctx.db ? { db: ctx.db, driver: ctx.driver } : {}),\n ...(ctx.logger ? { logger: ctx.logger } : {}),\n }\n }\n\n const agent = options.agent ?? resolveUserAgent()\n await installPackages(agent, root, {\n dependencies: packages.dependencies,\n devDependencies: packages.devDependencies,\n })\n\n return {\n projectName: ctx.projectName,\n targetDir: root,\n framework: ctx.framework,\n ...(ctx.db ? { db: ctx.db, driver: ctx.driver } : {}),\n ...(ctx.logger ? { logger: ctx.logger } : {}),\n }\n}\n"],"mappings":";;;;;;;;;;;AAqBA,eAAe,MAAM,UAAkB,UAAiC;CACtE,OAAA,GAAM,iBAAA,MAAA,CAAM,UAAA,QAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;CACvD,OAAA,GAAM,iBAAA,UAAA,CAAU,UAAU,UAAU,MAAM;AAC5C;AAEA,eAAsB,gBAAgB,SAAmD;CACvF,MAAM,OAAO,QAAQ;CACrB,MAAM,MAAM;EACV,aAAa,QAAQ;EACrB,WAAW;EACX,WAAW,QAAQ;EACnB,GAAI,QAAQ,KAAK;GAAE,IAAI,QAAQ;GAAI,QAAQ,QAAQ;EAAO,IAAI,CAAC;EAC/D,GAAI,QAAQ,SAAS,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;EACnD,GAAI,QAAQ,YAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;CAC9D;CAEA,MAAM,SAAS,iBAAA,cAAc,GAAG;CAChC,MAAM,WAAW,yBAAA,gBAAgB,GAAG;CACpC,MAAM,eAAe,iBAAA,oBAAoB,GAAG;CAE5C,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,cAAc,GAAG,aAAA,oBAAoB,QAAQ,aAAa,SAAS,OAAO,CAAC;CACvG,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,eAAe,GAAG,aAAA,iBAAiB,CAAC;CAChE,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,kBAAkB,GAAG,aAAA,qBAAqB,CAAC;CACvE,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,YAAY,GAAG,aAAA,kBAAkB,CAAC;CAC9D,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,gBAAgB,GAAG,aAAA,gBAAgB,YAAY,CAAC;CAC5E,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,cAAc,GAAG,cAAA,gBAAgB,QAAQ,SAAS,CAAC;CAC/E,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,cAAc,GAAG,cAAA,cAAc,QAAQ,SAAS,CAAC;CAC7E,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,iBAAiB,GAAG,aAAA,mBAAmB,CAAC;CACpE,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,yBAAyB,GAAG,aAAA,mBAAmB,CAAC;CAC5E,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,0BAA0B,GAAG,aAAA,oBAAoB,GAAG,CAAC;CACjF,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,0BAA0B,GAAG,aAAA,wBAAwB,CAAC;CAElF,KAAK,MAAM,SAAS,QAClB,MAAM,MAAM,MAAM,MAAM,UAAU,aAAa,MAAM,UAAA,QAAK,KAAK,MAAM,QAAQ,GAAG,QAAQ,CAAC;CAG3F,MAAM,uBAAA,mBAAmB,MAAM,GAAG;CAElC,IAAI,QAAQ,aACV,OAAO;EACL,aAAa,IAAI;EACjB,WAAW;EACX,WAAW,IAAI;EACf,GAAI,IAAI,KAAK;GAAE,IAAI,IAAI;GAAI,QAAQ,IAAI;EAAO,IAAI,CAAC;EACnD,GAAI,IAAI,SAAS,EAAE,QAAQ,IAAI,OAAO,IAAI,CAAC;CAC7C;CAGF,MAAM,QAAQ,QAAQ,SAAS,wBAAA,iBAAiB;CAChD,MAAM,wBAAA,gBAAgB,OAAO,MAAM;EACjC,cAAc,SAAS;EACvB,iBAAiB,SAAS;CAC5B,CAAC;CAED,OAAO;EACL,aAAa,IAAI;EACjB,WAAW;EACX,WAAW,IAAI;EACf,GAAI,IAAI,KAAK;GAAE,IAAI,IAAI;GAAI,QAAQ,IAAI;EAAO,IAAI,CAAC;EACnD,GAAI,IAAI,SAAS,EAAE,QAAQ,IAAI,OAAO,IAAI,CAAC;CAC7C;AACF"}
@@ -17,11 +17,17 @@ var DB_DRIVERS = [
17
17
  ];
18
18
  var DEFAULT_DB_DRIVER = "sqlite";
19
19
  var LOGGERS = ["pino", "winston"];
20
+ var VALIDATORS = [
21
+ "zod",
22
+ "arktype",
23
+ "valibot"
24
+ ];
20
25
  //#endregion
21
26
  exports.DB_DRIVERS = DB_DRIVERS;
22
27
  exports.DB_ODMS = DB_ODMS;
23
28
  exports.DEFAULT_DB_DRIVER = DEFAULT_DB_DRIVER;
24
29
  exports.FRAMEWORKS = FRAMEWORKS;
25
30
  exports.LOGGERS = LOGGERS;
31
+ exports.VALIDATORS = VALIDATORS;
26
32
 
27
33
  //# sourceMappingURL=types.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.cjs","names":[],"sources":["../../../src/core/types.ts"],"sourcesContent":["import type { Agent } from 'package-manager-detector'\n\nexport type Framework = 'node' | 'express' | 'hono' | 'fastify'\n\nexport const FRAMEWORKS: readonly Framework[] = ['node', 'express', 'hono', 'fastify']\n\nexport type DbOdm = 'drizzle' | 'prisma' | 'kysely'\n\nexport const DB_ODMS: readonly DbOdm[] = ['drizzle', 'prisma', 'kysely']\n\nexport type DbDriver = 'postgres' | 'sqlite' | 'mysql'\n\nexport const DB_DRIVERS: readonly DbDriver[] = ['postgres', 'sqlite', 'mysql']\n\nexport const DEFAULT_DB_DRIVER: DbDriver = 'sqlite'\n\nexport type LoggerId = 'pino' | 'winston'\n\nexport const LOGGERS: readonly LoggerId[] = ['pino', 'winston']\n\nexport type PackageGroups = {\n dependencies: string[]\n devDependencies: string[]\n scripts: Record<string, string>\n}\n\nexport type ScaffoldContext = {\n projectName: string\n targetDir: string\n framework: Framework\n db?: DbOdm\n driver?: DbDriver\n logger?: LoggerId\n}\n\nexport type ScaffoldOptions = ScaffoldContext & {\n skipInstall?: boolean\n agent?: Agent\n}\n\nexport type ScaffoldResult = ScaffoldContext\n\nexport type CapabilitiesCatalog = {\n frameworks: Framework[]\n db: {\n odms: DbOdm[]\n drivers: DbDriver[]\n defaultDriver: DbDriver\n }\n loggers: LoggerId[]\n}\n"],"mappings":";AAIA,IAAa,aAAmC;CAAC;CAAQ;CAAW;CAAQ;AAAS;AAIrF,IAAa,UAA4B;CAAC;CAAW;CAAU;AAAQ;AAIvE,IAAa,aAAkC;CAAC;CAAY;CAAU;AAAO;AAE7E,IAAa,oBAA8B;AAI3C,IAAa,UAA+B,CAAC,QAAQ,SAAS"}
1
+ {"version":3,"file":"types.cjs","names":[],"sources":["../../../src/core/types.ts"],"sourcesContent":["import type { Agent } from 'package-manager-detector'\n\nexport type Framework = 'node' | 'express' | 'hono' | 'fastify'\n\nexport const FRAMEWORKS: readonly Framework[] = ['node', 'express', 'hono', 'fastify']\n\nexport type DbOdm = 'drizzle' | 'prisma' | 'kysely'\n\nexport const DB_ODMS: readonly DbOdm[] = ['drizzle', 'prisma', 'kysely']\n\nexport type DbDriver = 'postgres' | 'sqlite' | 'mysql'\n\nexport const DB_DRIVERS: readonly DbDriver[] = ['postgres', 'sqlite', 'mysql']\n\nexport const DEFAULT_DB_DRIVER: DbDriver = 'sqlite'\n\nexport type LoggerId = 'pino' | 'winston'\n\nexport const LOGGERS: readonly LoggerId[] = ['pino', 'winston']\n\nexport type ValidatorId = 'zod' | 'arktype' | 'valibot'\n\nexport const VALIDATORS: readonly ValidatorId[] = ['zod', 'arktype', 'valibot']\n\nexport type PackageGroups = {\n dependencies: string[]\n devDependencies: string[]\n scripts: Record<string, string>\n}\n\nexport type ScaffoldContext = {\n projectName: string\n targetDir: string\n framework: Framework\n db?: DbOdm\n driver?: DbDriver\n logger?: LoggerId\n validator?: ValidatorId\n}\n\nexport type ScaffoldOptions = ScaffoldContext & {\n skipInstall?: boolean\n agent?: Agent\n}\n\nexport type ScaffoldResult = ScaffoldContext\n\nexport type CapabilitiesCatalog = {\n frameworks: Framework[]\n db: {\n odms: DbOdm[]\n drivers: DbDriver[]\n defaultDriver: DbDriver\n }\n loggers: LoggerId[]\n validators: ValidatorId[]\n}\n"],"mappings":";AAIA,IAAa,aAAmC;CAAC;CAAQ;CAAW;CAAQ;AAAS;AAIrF,IAAa,UAA4B;CAAC;CAAW;CAAU;AAAQ;AAIvE,IAAa,aAAkC;CAAC;CAAY;CAAU;AAAO;AAE7E,IAAa,oBAA8B;AAI3C,IAAa,UAA+B,CAAC,QAAQ,SAAS;AAI9D,IAAa,aAAqC;CAAC;CAAO;CAAW;AAAS"}
@@ -8,6 +8,8 @@ export declare const DB_DRIVERS: readonly DbDriver[];
8
8
  export declare const DEFAULT_DB_DRIVER: DbDriver;
9
9
  export type LoggerId = 'pino' | 'winston';
10
10
  export declare const LOGGERS: readonly LoggerId[];
11
+ export type ValidatorId = 'zod' | 'arktype' | 'valibot';
12
+ export declare const VALIDATORS: readonly ValidatorId[];
11
13
  export type PackageGroups = {
12
14
  dependencies: string[];
13
15
  devDependencies: string[];
@@ -20,6 +22,7 @@ export type ScaffoldContext = {
20
22
  db?: DbOdm;
21
23
  driver?: DbDriver;
22
24
  logger?: LoggerId;
25
+ validator?: ValidatorId;
23
26
  };
24
27
  export type ScaffoldOptions = ScaffoldContext & {
25
28
  skipInstall?: boolean;
@@ -34,4 +37,5 @@ export type CapabilitiesCatalog = {
34
37
  defaultDriver: DbDriver;
35
38
  };
36
39
  loggers: LoggerId[];
40
+ validators: ValidatorId[];
37
41
  };
@@ -12,8 +12,8 @@ function packageJsonTemplate(projectName, scripts = {}) {
12
12
  "dev:taser": "taser watch",
13
13
  "start": "tsx src/index.ts",
14
14
  "generate": "taser generate",
15
- "build": "taser generate && tsdown build",
16
- "serve": "node dist/index.js",
15
+ "build": "taser generate && tsdown",
16
+ "serve": "node dist/index.mjs",
17
17
  "typecheck": "tsc --noEmit -p tsconfig.json",
18
18
  ...scripts
19
19
  }
@@ -25,9 +25,7 @@ function tsdownConfigTemplate() {
25
25
 
26
26
  export default defineConfig({
27
27
  entry: ['./src/index.ts'],
28
- format: 'esm',
29
28
  platform: 'node',
30
- target: 'node20',
31
29
  outDir: 'dist',
32
30
  clean: true,
33
31
  sourcemap: true,
@@ -38,9 +36,7 @@ function tsconfigTemplate() {
38
36
  return `${JSON.stringify({
39
37
  compilerOptions: {
40
38
  target: "ES2022",
41
- lib: ["ES2022", "DOM"],
42
- module: "ESNext",
43
- moduleResolution: "bundler",
39
+ module: "NodeNext",
44
40
  paths: { "#src/*": ["./src/*"] },
45
41
  strict: true,
46
42
  skipLibCheck: true,
@@ -1 +1 @@
1
- {"version":3,"file":"base.cjs","names":[],"sources":["../../../src/templates/base.ts"],"sourcesContent":["import type { BootBinding } from '../addons/types.js'\nimport type { ScaffoldContext } from '../core/types.js'\n\nexport function packageJsonTemplate(projectName: string, scripts: Record<string, string> = {}): string {\n const pkg = {\n name: projectName,\n version: '1.0.0',\n private: true,\n type: 'module',\n imports: {\n '#src/*': './src/*',\n },\n scripts: {\n 'dev': 'run-p dev:server dev:taser',\n 'dev:server': 'tsx watch src/index.ts',\n 'dev:taser': 'taser watch',\n 'start': 'tsx src/index.ts',\n 'generate': 'taser generate',\n 'build': 'taser generate && tsdown build',\n 'serve': 'node dist/index.js',\n 'typecheck': 'tsc --noEmit -p tsconfig.json',\n ...scripts,\n },\n }\n\n return `${JSON.stringify(pkg, null, 2)}\\n`\n}\n\nexport function tsdownConfigTemplate(): string {\n return `import { defineConfig } from 'tsdown'\n\nexport default defineConfig({\n entry: ['./src/index.ts'],\n format: 'esm',\n platform: 'node',\n target: 'node20',\n outDir: 'dist',\n clean: true,\n sourcemap: true,\n})\n`\n}\n\nexport function tsconfigTemplate(): string {\n return `${JSON.stringify({\n compilerOptions: {\n target: 'ES2022',\n lib: ['ES2022', 'DOM'],\n module: 'ESNext',\n moduleResolution: 'bundler',\n paths: {\n '#src/*': ['./src/*'],\n },\n strict: true,\n skipLibCheck: true,\n verbatimModuleSyntax: true,\n isolatedModules: true,\n noEmit: true,\n types: ['node'],\n },\n include: ['src'],\n }, null, 2)}\\n`\n}\n\nexport function gitignoreTemplate(): string {\n return `node_modules\ndist\n.DS_Store\n*.log\n.env\nlocal.db\ndrizzle\n`\n}\n\nexport function contextTemplate(bindings: BootBinding[]): string {\n const imports = bindings.map(\n binding => `import { ${binding.factoryName} } from '${binding.importPath}'`,\n )\n\n const bootBody = bindings.length > 0\n ? bindings.map(binding => ` ${binding.key}: ${binding.factoryName}(),`).join('\\n')\n : ''\n\n const bootBlock = bindings.length > 0\n ? ` boot: () => ({\\n${bootBody}\\n }),`\n : ''\n\n const importBlock = imports.length > 0 ? `${imports.join('\\n')}\\n\\n` : ''\n\n return `${importBlock}import { createContext } from '@taserjs/router'\n\nexport const context = createContext({\n${bootBlock}\n request: () => ({\n requestId: crypto.randomUUID(),\n }),\n})\n`\n}\n\nexport function rootLayoutTemplate(): string {\n return `import { bodyLimit } from '@taserjs/router/body-limit'\nimport { secureHeaders } from '@taserjs/router/secure-headers'\n\nimport { t } from '#src/taser.js'\n\nexport const Middleware = t.middleware('/$')\n .use(secureHeaders())\n .use(bodyLimit({ maxSize: 1_000_000 }))\n`\n}\n\nexport function indexRouteTemplate(): string {\n return `import { t } from '#src/taser.js'\n\nexport const Route = t.get('/').handler((ctx) => {\n return ctx.reply.json({ message: 'Welcome to Taser' })\n})\n`\n}\n\nexport function healthRouteTemplate(ctx: ScaffoldContext): string {\n const lines: string[] = []\n\n if (ctx.logger) {\n lines.push(' ctx.logger.info(\\'health check\\')')\n }\n\n if (ctx.db) {\n lines.push(' // ctx.db is available from context boot')\n }\n\n const body = lines.length > 0 ? `${lines.join('\\n')}\\n` : ''\n\n return `import { t } from '#src/taser.js'\n\nexport const Route = t.get('/health').handler((ctx) => {\n${body} return ctx.reply.json({ ok: true })\n})\n`\n}\n\n/** Minimal placeholder until `taser generate` runs. */\nexport function starterManifestTemplate(): string {\n return `/* eslint-disable */\n// Run \\`pnpm generate\\` (taser generate) to replace this file.\nimport { Middleware as RootSplatLayoutImport } from './routes/$.js'\nimport { Route as RootIndexGetRouteImport } from './routes/index.get.js'\nimport { Route as HealthGetRouteImport } from './routes/health.get.js'\n\nexport const routeManifest = {\n layouts: {\n '/$': {\n middlewares: RootSplatLayoutImport,\n },\n },\n routes: {\n '/': {\n GET: {\n layoutChain: ['/$'],\n route: RootIndexGetRouteImport,\n },\n },\n '/health': {\n GET: {\n layoutChain: ['/$'],\n route: HealthGetRouteImport,\n },\n },\n },\n} as const\n\nexport type RoutePathGen = '/' | '/health'\nexport type LayoutIdGen = '/$'\nexport type LayoutTreeGen = {\n '/$': {\n parent: null\n middlewares: typeof RootSplatLayoutImport\n }\n}\nexport type RouteByPathMethodGen = {\n '/': {\n GET: {\n parent: '/$'\n layoutChain: ['/$']\n route: typeof RootIndexGetRouteImport\n }\n }\n '/health': {\n GET: {\n parent: '/$'\n layoutChain: ['/$']\n route: typeof HealthGetRouteImport\n }\n }\n}\nexport type RouteManifest = typeof routeManifest\n\ndeclare module '@taserjs/router' {\n interface RouterRegister {\n RoutePath: RoutePathGen\n LayoutId: LayoutIdGen\n LayoutTree: LayoutTreeGen\n RouteByPathMethod: RouteByPathMethodGen\n }\n}\n`\n}\n"],"mappings":";AAGA,SAAgB,oBAAoB,aAAqB,UAAkC,CAAC,GAAW;CACrG,MAAM,MAAM;EACV,MAAM;EACN,SAAS;EACT,SAAS;EACT,MAAM;EACN,SAAS,EACP,UAAU,UACZ;EACA,SAAS;GACP,OAAO;GACP,cAAc;GACd,aAAa;GACb,SAAS;GACT,YAAY;GACZ,SAAS;GACT,SAAS;GACT,aAAa;GACb,GAAG;EACL;CACF;CAEA,OAAO,GAAG,KAAK,UAAU,KAAK,MAAM,CAAC,EAAE;AACzC;AAEA,SAAgB,uBAA+B;CAC7C,OAAO;;;;;;;;;;;;AAYT;AAEA,SAAgB,mBAA2B;CACzC,OAAO,GAAG,KAAK,UAAU;EACvB,iBAAiB;GACf,QAAQ;GACR,KAAK,CAAC,UAAU,KAAK;GACrB,QAAQ;GACR,kBAAkB;GAClB,OAAO,EACL,UAAU,CAAC,SAAS,EACtB;GACA,QAAQ;GACR,cAAc;GACd,sBAAsB;GACtB,iBAAiB;GACjB,QAAQ;GACR,OAAO,CAAC,MAAM;EAChB;EACA,SAAS,CAAC,KAAK;CACjB,GAAG,MAAM,CAAC,EAAE;AACd;AAEA,SAAgB,oBAA4B;CAC1C,OAAO;;;;;;;;AAQT;AAEA,SAAgB,gBAAgB,UAAiC;CAC/D,MAAM,UAAU,SAAS,KACvB,YAAW,YAAY,QAAQ,YAAY,WAAW,QAAQ,WAAW,EAC3E;CAEA,MAAM,WAAW,SAAS,SAAS,IAC/B,SAAS,KAAI,YAAW,OAAO,QAAQ,IAAI,IAAI,QAAQ,YAAY,IAAI,CAAC,CAAC,KAAK,IAAI,IAClF;CAEJ,MAAM,YAAY,SAAS,SAAS,IAChC,qBAAqB,SAAS,WAC9B;CAIJ,OAAO,GAFa,QAAQ,SAAS,IAAI,GAAG,QAAQ,KAAK,IAAI,EAAE,QAAQ,GAEjD;;;EAGtB,UAAU;;;;;;AAMZ;AAEA,SAAgB,qBAA6B;CAC3C,OAAO;;;;;;;;;AAST;AAEA,SAAgB,qBAA6B;CAC3C,OAAO;;;;;;AAMT;AAEA,SAAgB,oBAAoB,KAA8B;CAChE,MAAM,QAAkB,CAAC;CAEzB,IAAI,IAAI,QACN,MAAM,KAAK,mCAAqC;CAGlD,IAAI,IAAI,IACN,MAAM,KAAK,4CAA4C;CAKzD,OAAO;;;EAFM,MAAM,SAAS,IAAI,GAAG,MAAM,KAAK,IAAI,EAAE,MAAM,GAKrD;;;AAGP;;AAGA,SAAgB,0BAAkC;CAChD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DT"}
1
+ {"version":3,"file":"base.cjs","names":[],"sources":["../../../src/templates/base.ts"],"sourcesContent":["import type { BootBinding } from '../addons/types.js'\nimport type { ScaffoldContext } from '../core/types.js'\n\nexport function packageJsonTemplate(projectName: string, scripts: Record<string, string> = {}): string {\n const pkg = {\n name: projectName,\n version: '1.0.0',\n private: true,\n type: 'module',\n imports: {\n '#src/*': './src/*',\n },\n scripts: {\n 'dev': 'run-p dev:server dev:taser',\n 'dev:server': 'tsx watch src/index.ts',\n 'dev:taser': 'taser watch',\n 'start': 'tsx src/index.ts',\n 'generate': 'taser generate',\n 'build': 'taser generate && tsdown',\n 'serve': 'node dist/index.mjs',\n 'typecheck': 'tsc --noEmit -p tsconfig.json',\n ...scripts,\n },\n }\n\n return `${JSON.stringify(pkg, null, 2)}\\n`\n}\n\nexport function tsdownConfigTemplate(): string {\n return `import { defineConfig } from 'tsdown'\n\nexport default defineConfig({\n entry: ['./src/index.ts'],\n platform: 'node',\n outDir: 'dist',\n clean: true,\n sourcemap: true,\n})\n`\n}\n\nexport function tsconfigTemplate(): string {\n return `${JSON.stringify({\n compilerOptions: {\n target: 'ES2022',\n module: 'NodeNext',\n paths: {\n '#src/*': ['./src/*'],\n },\n strict: true,\n skipLibCheck: true,\n verbatimModuleSyntax: true,\n isolatedModules: true,\n noEmit: true,\n types: ['node'],\n },\n include: ['src'],\n }, null, 2)}\\n`\n}\n\nexport function gitignoreTemplate(): string {\n return `node_modules\ndist\n.DS_Store\n*.log\n.env\nlocal.db\ndrizzle\n`\n}\n\nexport function contextTemplate(bindings: BootBinding[]): string {\n const imports = bindings.map(\n binding => `import { ${binding.factoryName} } from '${binding.importPath}'`,\n )\n\n const bootBody = bindings.length > 0\n ? bindings.map(binding => ` ${binding.key}: ${binding.factoryName}(),`).join('\\n')\n : ''\n\n const bootBlock = bindings.length > 0\n ? ` boot: () => ({\\n${bootBody}\\n }),`\n : ''\n\n const importBlock = imports.length > 0 ? `${imports.join('\\n')}\\n\\n` : ''\n\n return `${importBlock}import { createContext } from '@taserjs/router'\n\nexport const context = createContext({\n${bootBlock}\n request: () => ({\n requestId: crypto.randomUUID(),\n }),\n})\n`\n}\n\nexport function rootLayoutTemplate(): string {\n return `import { bodyLimit } from '@taserjs/router/body-limit'\nimport { secureHeaders } from '@taserjs/router/secure-headers'\n\nimport { t } from '#src/taser.js'\n\nexport const Middleware = t.middleware('/$')\n .use(secureHeaders())\n .use(bodyLimit({ maxSize: 1_000_000 }))\n`\n}\n\nexport function indexRouteTemplate(): string {\n return `import { t } from '#src/taser.js'\n\nexport const Route = t.get('/').handler((ctx) => {\n return ctx.reply.json({ message: 'Welcome to Taser' })\n})\n`\n}\n\nexport function healthRouteTemplate(ctx: ScaffoldContext): string {\n const lines: string[] = []\n\n if (ctx.logger) {\n lines.push(' ctx.logger.info(\\'health check\\')')\n }\n\n if (ctx.db) {\n lines.push(' // ctx.db is available from context boot')\n }\n\n const body = lines.length > 0 ? `${lines.join('\\n')}\\n` : ''\n\n return `import { t } from '#src/taser.js'\n\nexport const Route = t.get('/health').handler((ctx) => {\n${body} return ctx.reply.json({ ok: true })\n})\n`\n}\n\n/** Minimal placeholder until `taser generate` runs. */\nexport function starterManifestTemplate(): string {\n return `/* eslint-disable */\n// Run \\`pnpm generate\\` (taser generate) to replace this file.\nimport { Middleware as RootSplatLayoutImport } from './routes/$.js'\nimport { Route as RootIndexGetRouteImport } from './routes/index.get.js'\nimport { Route as HealthGetRouteImport } from './routes/health.get.js'\n\nexport const routeManifest = {\n layouts: {\n '/$': {\n middlewares: RootSplatLayoutImport,\n },\n },\n routes: {\n '/': {\n GET: {\n layoutChain: ['/$'],\n route: RootIndexGetRouteImport,\n },\n },\n '/health': {\n GET: {\n layoutChain: ['/$'],\n route: HealthGetRouteImport,\n },\n },\n },\n} as const\n\nexport type RoutePathGen = '/' | '/health'\nexport type LayoutIdGen = '/$'\nexport type LayoutTreeGen = {\n '/$': {\n parent: null\n middlewares: typeof RootSplatLayoutImport\n }\n}\nexport type RouteByPathMethodGen = {\n '/': {\n GET: {\n parent: '/$'\n layoutChain: ['/$']\n route: typeof RootIndexGetRouteImport\n }\n }\n '/health': {\n GET: {\n parent: '/$'\n layoutChain: ['/$']\n route: typeof HealthGetRouteImport\n }\n }\n}\nexport type RouteManifest = typeof routeManifest\n\ndeclare module '@taserjs/router' {\n interface RouterRegister {\n RoutePath: RoutePathGen\n LayoutId: LayoutIdGen\n LayoutTree: LayoutTreeGen\n RouteByPathMethod: RouteByPathMethodGen\n }\n}\n`\n}\n"],"mappings":";AAGA,SAAgB,oBAAoB,aAAqB,UAAkC,CAAC,GAAW;CACrG,MAAM,MAAM;EACV,MAAM;EACN,SAAS;EACT,SAAS;EACT,MAAM;EACN,SAAS,EACP,UAAU,UACZ;EACA,SAAS;GACP,OAAO;GACP,cAAc;GACd,aAAa;GACb,SAAS;GACT,YAAY;GACZ,SAAS;GACT,SAAS;GACT,aAAa;GACb,GAAG;EACL;CACF;CAEA,OAAO,GAAG,KAAK,UAAU,KAAK,MAAM,CAAC,EAAE;AACzC;AAEA,SAAgB,uBAA+B;CAC7C,OAAO;;;;;;;;;;AAUT;AAEA,SAAgB,mBAA2B;CACzC,OAAO,GAAG,KAAK,UAAU;EACvB,iBAAiB;GACf,QAAQ;GACR,QAAQ;GACR,OAAO,EACL,UAAU,CAAC,SAAS,EACtB;GACA,QAAQ;GACR,cAAc;GACd,sBAAsB;GACtB,iBAAiB;GACjB,QAAQ;GACR,OAAO,CAAC,MAAM;EAChB;EACA,SAAS,CAAC,KAAK;CACjB,GAAG,MAAM,CAAC,EAAE;AACd;AAEA,SAAgB,oBAA4B;CAC1C,OAAO;;;;;;;;AAQT;AAEA,SAAgB,gBAAgB,UAAiC;CAC/D,MAAM,UAAU,SAAS,KACvB,YAAW,YAAY,QAAQ,YAAY,WAAW,QAAQ,WAAW,EAC3E;CAEA,MAAM,WAAW,SAAS,SAAS,IAC/B,SAAS,KAAI,YAAW,OAAO,QAAQ,IAAI,IAAI,QAAQ,YAAY,IAAI,CAAC,CAAC,KAAK,IAAI,IAClF;CAEJ,MAAM,YAAY,SAAS,SAAS,IAChC,qBAAqB,SAAS,WAC9B;CAIJ,OAAO,GAFa,QAAQ,SAAS,IAAI,GAAG,QAAQ,KAAK,IAAI,EAAE,QAAQ,GAEjD;;;EAGtB,UAAU;;;;;;AAMZ;AAEA,SAAgB,qBAA6B;CAC3C,OAAO;;;;;;;;;AAST;AAEA,SAAgB,qBAA6B;CAC3C,OAAO;;;;;;AAMT;AAEA,SAAgB,oBAAoB,KAA8B;CAChE,MAAM,QAAkB,CAAC;CAEzB,IAAI,IAAI,QACN,MAAM,KAAK,mCAAqC;CAGlD,IAAI,IAAI,IACN,MAAM,KAAK,4CAA4C;CAKzD,OAAO;;;EAFM,MAAM,SAAS,IAAI,GAAG,MAAM,KAAK,IAAI,EAAE,MAAM,GAKrD;;;AAGP;;AAGA,SAAgB,0BAAkC;CAChD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DT"}
@@ -0,0 +1 @@
1
+ export declare const arktypeAddon: import('../types.js').AddonDefinition;
@@ -2,18 +2,21 @@ import { drizzleAddon } from "./drizzle/index.js";
2
2
  import { kyselyAddon } from "./kysely/index.js";
3
3
  import { pinoAddon } from "./pino/index.js";
4
4
  import { prismaAddon } from "./prisma/index.js";
5
+ import { zodAddon } from "./zod/index.js";
5
6
  import { winstonAddon } from "./winston/index.js";
6
- import { DB_DRIVERS, DB_ODMS, DEFAULT_DB_DRIVER, FRAMEWORKS, LOGGERS } from "../core/types.js";
7
+ import { DB_DRIVERS, DB_ODMS, DEFAULT_DB_DRIVER, FRAMEWORKS, LOGGERS, VALIDATORS } from "../core/types.js";
7
8
  //#region src/addons/registry.ts
8
9
  var ALL_ADDONS = [
9
10
  drizzleAddon,
10
11
  prismaAddon,
11
12
  kyselyAddon,
12
13
  pinoAddon,
13
- winstonAddon
14
+ winstonAddon,
15
+ zodAddon
14
16
  ];
15
17
  var DB_ADDONS = ALL_ADDONS.filter((addon) => addon.category === "database");
16
18
  var LOGGER_ADDONS = ALL_ADDONS.filter((addon) => addon.category === "logger");
19
+ var VALIDATOR_ADDONS = ALL_ADDONS.filter((addon) => addon.category === "validator");
17
20
  function getCapabilitiesCatalog() {
18
21
  return {
19
22
  frameworks: [...FRAMEWORKS],
@@ -22,7 +25,8 @@ function getCapabilitiesCatalog() {
22
25
  drivers: [...DB_DRIVERS],
23
26
  defaultDriver: DEFAULT_DB_DRIVER
24
27
  },
25
- loggers: [...LOGGERS]
28
+ loggers: [...LOGGERS],
29
+ validators: [...VALIDATORS]
26
30
  };
27
31
  }
28
32
  function resolveAddons(ctx) {
@@ -39,10 +43,16 @@ function resolveAddons(ctx) {
39
43
  }
40
44
  if (selected.filter((addon) => addon.category === "database").length > 1) throw new Error("Only one database addon can be selected");
41
45
  if (selected.filter((addon) => addon.category === "logger").length > 1) throw new Error("Only one logger addon can be selected");
46
+ if (ctx.validator) {
47
+ const validatorAddon = VALIDATOR_ADDONS.find((addon) => addon.id === ctx.validator);
48
+ if (!validatorAddon) throw new Error(`Unknown validator addon "${ctx.validator}"`);
49
+ selected.push(validatorAddon);
50
+ }
51
+ if (selected.filter((addon) => addon.category === "validator").length > 1) throw new Error("Only one validator addon can be selected");
42
52
  return selected;
43
53
  }
44
54
  function collectBootBindings(ctx) {
45
- return resolveAddons(ctx).map((addon) => addon.bootBinding(ctx));
55
+ return resolveAddons(ctx).map((addon) => addon.bootBinding?.(ctx)).filter((v) => Boolean(v));
46
56
  }
47
57
  //#endregion
48
58
  export { collectBootBindings, getCapabilitiesCatalog, resolveAddons };
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","names":[],"sources":["../../../src/addons/registry.ts"],"sourcesContent":["import { drizzleAddon } from './drizzle/index.js'\nimport { kyselyAddon } from './kysely/index.js'\nimport { pinoAddon } from './pino/index.js'\nimport { prismaAddon } from './prisma/index.js'\nimport type { AddonDefinition } from './types.js'\nimport { winstonAddon } from './winston/index.js'\nimport type { CapabilitiesCatalog, ScaffoldContext } from '../core/types.js'\nimport {\n DB_DRIVERS,\n DB_ODMS,\n DEFAULT_DB_DRIVER,\n FRAMEWORKS,\n LOGGERS,\n} from '../core/types.js'\n\nconst ALL_ADDONS: AddonDefinition[] = [\n drizzleAddon,\n prismaAddon,\n kyselyAddon,\n pinoAddon,\n winstonAddon,\n]\n\nconst DB_ADDONS = ALL_ADDONS.filter(addon => addon.category === 'database')\nconst LOGGER_ADDONS = ALL_ADDONS.filter(addon => addon.category === 'logger')\n\nexport function getCapabilitiesCatalog(): CapabilitiesCatalog {\n return {\n frameworks: [...FRAMEWORKS],\n db: {\n odms: [...DB_ODMS],\n drivers: [...DB_DRIVERS],\n defaultDriver: DEFAULT_DB_DRIVER,\n },\n loggers: [...LOGGERS],\n }\n}\n\nexport function resolveAddons(ctx: ScaffoldContext): AddonDefinition[] {\n const selected: AddonDefinition[] = []\n\n if (ctx.db) {\n const dbAddon = DB_ADDONS.find(addon => addon.id === ctx.db)\n if (!dbAddon) {\n throw new Error(`Unknown database addon \"${ctx.db}\"`)\n }\n selected.push(dbAddon)\n }\n\n if (ctx.logger) {\n const loggerAddon = LOGGER_ADDONS.find(addon => addon.id === ctx.logger)\n if (!loggerAddon) {\n throw new Error(`Unknown logger addon \"${ctx.logger}\"`)\n }\n selected.push(loggerAddon)\n }\n\n const dbCount = selected.filter(addon => addon.category === 'database').length\n if (dbCount > 1) {\n throw new Error('Only one database addon can be selected')\n }\n\n const loggerCount = selected.filter(addon => addon.category === 'logger').length\n if (loggerCount > 1) {\n throw new Error('Only one logger addon can be selected')\n }\n\n return selected\n}\n\nexport function collectBootBindings(ctx: ScaffoldContext) {\n return resolveAddons(ctx).map(addon => addon.bootBinding(ctx))\n}\n"],"mappings":";;;;;;;AAeA,IAAM,aAAgC;CACpC;CACA;CACA;CACA;CACA;AACF;AAEA,IAAM,YAAY,WAAW,QAAO,UAAS,MAAM,aAAa,UAAU;AAC1E,IAAM,gBAAgB,WAAW,QAAO,UAAS,MAAM,aAAa,QAAQ;AAE5E,SAAgB,yBAA8C;CAC5D,OAAO;EACL,YAAY,CAAC,GAAG,UAAU;EAC1B,IAAI;GACF,MAAM,CAAC,GAAG,OAAO;GACjB,SAAS,CAAC,GAAG,UAAU;GACvB,eAAe;EACjB;EACA,SAAS,CAAC,GAAG,OAAO;CACtB;AACF;AAEA,SAAgB,cAAc,KAAyC;CACrE,MAAM,WAA8B,CAAC;CAErC,IAAI,IAAI,IAAI;EACV,MAAM,UAAU,UAAU,MAAK,UAAS,MAAM,OAAO,IAAI,EAAE;EAC3D,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,2BAA2B,IAAI,GAAG,EAAE;EAEtD,SAAS,KAAK,OAAO;CACvB;CAEA,IAAI,IAAI,QAAQ;EACd,MAAM,cAAc,cAAc,MAAK,UAAS,MAAM,OAAO,IAAI,MAAM;EACvE,IAAI,CAAC,aACH,MAAM,IAAI,MAAM,yBAAyB,IAAI,OAAO,EAAE;EAExD,SAAS,KAAK,WAAW;CAC3B;CAGA,IADgB,SAAS,QAAO,UAAS,MAAM,aAAa,UAAU,CAAC,CAAC,SAC1D,GACZ,MAAM,IAAI,MAAM,yCAAyC;CAI3D,IADoB,SAAS,QAAO,UAAS,MAAM,aAAa,QAAQ,CAAC,CAAC,SACxD,GAChB,MAAM,IAAI,MAAM,uCAAuC;CAGzD,OAAO;AACT;AAEA,SAAgB,oBAAoB,KAAsB;CACxD,OAAO,cAAc,GAAG,CAAC,CAAC,KAAI,UAAS,MAAM,YAAY,GAAG,CAAC;AAC/D"}
1
+ {"version":3,"file":"registry.js","names":[],"sources":["../../../src/addons/registry.ts"],"sourcesContent":["import { drizzleAddon } from './drizzle/index.js'\nimport { kyselyAddon } from './kysely/index.js'\nimport { pinoAddon } from './pino/index.js'\nimport { prismaAddon } from './prisma/index.js'\nimport { zodAddon } from './zod/index.js'\nimport type { AddonDefinition } from './types.js'\nimport { winstonAddon } from './winston/index.js'\nimport type { CapabilitiesCatalog, ScaffoldContext } from '../core/types.js'\nimport {\n DB_DRIVERS,\n DB_ODMS,\n DEFAULT_DB_DRIVER,\n FRAMEWORKS,\n LOGGERS,\n VALIDATORS,\n} from '../core/types.js'\n\nconst ALL_ADDONS: AddonDefinition[] = [\n drizzleAddon,\n prismaAddon,\n kyselyAddon,\n pinoAddon,\n winstonAddon,\n zodAddon,\n]\n\nconst DB_ADDONS = ALL_ADDONS.filter(addon => addon.category === 'database')\nconst LOGGER_ADDONS = ALL_ADDONS.filter(addon => addon.category === 'logger')\nconst VALIDATOR_ADDONS = ALL_ADDONS.filter(addon => addon.category === 'validator')\n\nexport function getCapabilitiesCatalog(): CapabilitiesCatalog {\n return {\n frameworks: [...FRAMEWORKS],\n db: {\n odms: [...DB_ODMS],\n drivers: [...DB_DRIVERS],\n defaultDriver: DEFAULT_DB_DRIVER,\n },\n loggers: [...LOGGERS],\n validators: [...VALIDATORS],\n }\n}\n\nexport function resolveAddons(ctx: ScaffoldContext): AddonDefinition[] {\n const selected: AddonDefinition[] = []\n\n if (ctx.db) {\n const dbAddon = DB_ADDONS.find(addon => addon.id === ctx.db)\n if (!dbAddon) {\n throw new Error(`Unknown database addon \"${ctx.db}\"`)\n }\n selected.push(dbAddon)\n }\n\n if (ctx.logger) {\n const loggerAddon = LOGGER_ADDONS.find(addon => addon.id === ctx.logger)\n if (!loggerAddon) {\n throw new Error(`Unknown logger addon \"${ctx.logger}\"`)\n }\n selected.push(loggerAddon)\n }\n\n const dbCount = selected.filter(addon => addon.category === 'database').length\n if (dbCount > 1) {\n throw new Error('Only one database addon can be selected')\n }\n\n const loggerCount = selected.filter(addon => addon.category === 'logger').length\n if (loggerCount > 1) {\n throw new Error('Only one logger addon can be selected')\n }\n\n if (ctx.validator) {\n const validatorAddon = VALIDATOR_ADDONS.find(addon => addon.id === ctx.validator)\n if (!validatorAddon) {\n throw new Error(`Unknown validator addon \"${ctx.validator}\"`)\n }\n selected.push(validatorAddon)\n }\n\n const validatorCount = selected.filter(addon => addon.category === 'validator').length\n if (validatorCount > 1) {\n throw new Error('Only one validator addon can be selected')\n }\n\n return selected\n}\n\nexport function collectBootBindings(ctx: ScaffoldContext) {\n return resolveAddons(ctx)\n .map(addon => addon.bootBinding?.(ctx))\n .filter((v): v is NonNullable<typeof v> => Boolean(v))\n}\n"],"mappings":";;;;;;;;AAiBA,IAAM,aAAgC;CACpC;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,IAAM,YAAY,WAAW,QAAO,UAAS,MAAM,aAAa,UAAU;AAC1E,IAAM,gBAAgB,WAAW,QAAO,UAAS,MAAM,aAAa,QAAQ;AAC5E,IAAM,mBAAmB,WAAW,QAAO,UAAS,MAAM,aAAa,WAAW;AAElF,SAAgB,yBAA8C;CAC5D,OAAO;EACL,YAAY,CAAC,GAAG,UAAU;EAC1B,IAAI;GACF,MAAM,CAAC,GAAG,OAAO;GACjB,SAAS,CAAC,GAAG,UAAU;GACvB,eAAe;EACjB;EACA,SAAS,CAAC,GAAG,OAAO;EACpB,YAAY,CAAC,GAAG,UAAU;CAC5B;AACF;AAEA,SAAgB,cAAc,KAAyC;CACrE,MAAM,WAA8B,CAAC;CAErC,IAAI,IAAI,IAAI;EACV,MAAM,UAAU,UAAU,MAAK,UAAS,MAAM,OAAO,IAAI,EAAE;EAC3D,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,2BAA2B,IAAI,GAAG,EAAE;EAEtD,SAAS,KAAK,OAAO;CACvB;CAEA,IAAI,IAAI,QAAQ;EACd,MAAM,cAAc,cAAc,MAAK,UAAS,MAAM,OAAO,IAAI,MAAM;EACvE,IAAI,CAAC,aACH,MAAM,IAAI,MAAM,yBAAyB,IAAI,OAAO,EAAE;EAExD,SAAS,KAAK,WAAW;CAC3B;CAGA,IADgB,SAAS,QAAO,UAAS,MAAM,aAAa,UAAU,CAAC,CAAC,SAC1D,GACZ,MAAM,IAAI,MAAM,yCAAyC;CAI3D,IADoB,SAAS,QAAO,UAAS,MAAM,aAAa,QAAQ,CAAC,CAAC,SACxD,GAChB,MAAM,IAAI,MAAM,uCAAuC;CAGzD,IAAI,IAAI,WAAW;EACjB,MAAM,iBAAiB,iBAAiB,MAAK,UAAS,MAAM,OAAO,IAAI,SAAS;EAChF,IAAI,CAAC,gBACH,MAAM,IAAI,MAAM,4BAA4B,IAAI,UAAU,EAAE;EAE9D,SAAS,KAAK,cAAc;CAC9B;CAGA,IADuB,SAAS,QAAO,UAAS,MAAM,aAAa,WAAW,CAAC,CAAC,SAC3D,GACnB,MAAM,IAAI,MAAM,0CAA0C;CAG5D,OAAO;AACT;AAEA,SAAgB,oBAAoB,KAAsB;CACxD,OAAO,cAAc,GAAG,CAAC,CACtB,KAAI,UAAS,MAAM,cAAc,GAAG,CAAC,CAAC,CACtC,QAAQ,MAAkC,QAAQ,CAAC,CAAC;AACzD"}
@@ -7,10 +7,10 @@ export type BootBinding = {
7
7
  export type FileWriter = (filePath: string, contents: string) => Promise<void>;
8
8
  export type AddonDefinition = {
9
9
  id: string;
10
- category: 'database' | 'logger';
10
+ category: 'database' | 'logger' | 'validator';
11
11
  dependencies: (ctx: ScaffoldContext) => string[];
12
12
  devDependencies: (ctx: ScaffoldContext) => string[];
13
13
  scripts?: (ctx: ScaffoldContext) => Record<string, string>;
14
- bootBinding: (ctx: ScaffoldContext) => BootBinding;
14
+ bootBinding?: (ctx: ScaffoldContext) => BootBinding;
15
15
  apply: (ctx: ScaffoldContext, write: FileWriter) => Promise<void>;
16
16
  };
@@ -0,0 +1 @@
1
+ export declare const valibotAddon: import('../types.js').AddonDefinition;
@@ -0,0 +1,5 @@
1
+ import { ValidatorId } from '../core/types.js';
2
+ import { AddonDefinition } from './types.js';
3
+ export declare const IMPORT_LINES: Record<ValidatorId, string>;
4
+ export declare const VALIDATION_BLOCK_TEMPLATE: Record<ValidatorId, string>;
5
+ export declare const ValidatorAddon: (validator: ValidatorId) => AddonDefinition;