create-taserjs 0.0.1 → 0.0.3

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 (123) hide show
  1. package/README.md +2 -0
  2. package/dist/cjs/addons/arktype/index.cjs +6 -0
  3. package/dist/cjs/addons/arktype/index.cjs.map +1 -0
  4. package/dist/cjs/addons/drizzle/index.cjs +9 -2
  5. package/dist/cjs/addons/drizzle/index.cjs.map +1 -1
  6. package/dist/cjs/addons/kysely/index.cjs +9 -2
  7. package/dist/cjs/addons/kysely/index.cjs.map +1 -1
  8. package/dist/cjs/addons/pino/index.cjs.map +1 -1
  9. package/dist/cjs/addons/prisma/index.cjs +84 -24
  10. package/dist/cjs/addons/prisma/index.cjs.map +1 -1
  11. package/dist/cjs/addons/registry.cjs +17 -13
  12. package/dist/cjs/addons/registry.cjs.map +1 -1
  13. package/dist/cjs/addons/types.d.cts +1 -1
  14. package/dist/cjs/addons/valibot/index.cjs +6 -0
  15. package/dist/cjs/addons/valibot/index.cjs.map +1 -0
  16. package/dist/cjs/addons/validators.cjs +2 -2
  17. package/dist/cjs/addons/validators.cjs.map +1 -1
  18. package/dist/cjs/addons/winston/index.cjs.map +1 -1
  19. package/dist/cjs/addons/zod/index.cjs.map +1 -1
  20. package/dist/cjs/cli.cjs +7 -0
  21. package/dist/cjs/cli.cjs.map +1 -1
  22. package/dist/cjs/commands/create.cjs +45 -11
  23. package/dist/cjs/commands/create.cjs.map +1 -1
  24. package/dist/cjs/commands/create.d.cts +2 -0
  25. package/dist/cjs/core/json-output.cjs.map +1 -1
  26. package/dist/cjs/core/package-manager.cjs +5 -13
  27. package/dist/cjs/core/package-manager.cjs.map +1 -1
  28. package/dist/cjs/core/package-manager.d.cts +3 -2
  29. package/dist/cjs/core/parse-options.cjs +17 -7
  30. package/dist/cjs/core/parse-options.cjs.map +1 -1
  31. package/dist/cjs/core/parse-options.d.cts +4 -3
  32. package/dist/cjs/core/project-config.cjs +2 -1
  33. package/dist/cjs/core/project-config.cjs.map +1 -1
  34. package/dist/cjs/core/resolve-packages.cjs +41 -7
  35. package/dist/cjs/core/resolve-packages.cjs.map +1 -1
  36. package/dist/cjs/core/resolve-packages.d.cts +2 -2
  37. package/dist/cjs/core/scaffold-engine.cjs +37 -8
  38. package/dist/cjs/core/scaffold-engine.cjs.map +1 -1
  39. package/dist/cjs/core/types.cjs +11 -3
  40. package/dist/cjs/core/types.cjs.map +1 -1
  41. package/dist/cjs/core/types.d.cts +8 -8
  42. package/dist/cjs/core/validate-project-name.cjs.map +1 -1
  43. package/dist/cjs/frameworks/index.cjs +138 -17
  44. package/dist/cjs/frameworks/index.cjs.map +1 -1
  45. package/dist/cjs/frameworks/index.d.cts +3 -3
  46. package/dist/cjs/scaffold.d.cts +1 -1
  47. package/dist/cjs/templates/base.cjs +15 -12
  48. package/dist/cjs/templates/base.cjs.map +1 -1
  49. package/dist/cjs/types.d.cts +1 -1
  50. package/dist/esm/addons/arktype/index.js +7 -0
  51. package/dist/esm/addons/arktype/index.js.map +1 -0
  52. package/dist/esm/addons/drizzle/index.js +9 -2
  53. package/dist/esm/addons/drizzle/index.js.map +1 -1
  54. package/dist/esm/addons/kysely/index.js +9 -2
  55. package/dist/esm/addons/kysely/index.js.map +1 -1
  56. package/dist/esm/addons/pino/index.js.map +1 -1
  57. package/dist/esm/addons/prisma/index.js +84 -24
  58. package/dist/esm/addons/prisma/index.js.map +1 -1
  59. package/dist/esm/addons/registry.js +8 -4
  60. package/dist/esm/addons/registry.js.map +1 -1
  61. package/dist/esm/addons/types.d.ts +1 -1
  62. package/dist/esm/addons/valibot/index.js +7 -0
  63. package/dist/esm/addons/valibot/index.js.map +1 -0
  64. package/dist/esm/addons/validators.js +2 -2
  65. package/dist/esm/addons/validators.js.map +1 -1
  66. package/dist/esm/addons/winston/index.js.map +1 -1
  67. package/dist/esm/addons/zod/index.js.map +1 -1
  68. package/dist/esm/cli.js +7 -0
  69. package/dist/esm/cli.js.map +1 -1
  70. package/dist/esm/commands/create.d.ts +2 -0
  71. package/dist/esm/commands/create.js +47 -13
  72. package/dist/esm/commands/create.js.map +1 -1
  73. package/dist/esm/core/json-output.js.map +1 -1
  74. package/dist/esm/core/package-manager.d.ts +3 -2
  75. package/dist/esm/core/package-manager.js +5 -14
  76. package/dist/esm/core/package-manager.js.map +1 -1
  77. package/dist/esm/core/parse-options.d.ts +4 -3
  78. package/dist/esm/core/parse-options.js +17 -8
  79. package/dist/esm/core/parse-options.js.map +1 -1
  80. package/dist/esm/core/project-config.js +2 -1
  81. package/dist/esm/core/project-config.js.map +1 -1
  82. package/dist/esm/core/resolve-packages.d.ts +2 -2
  83. package/dist/esm/core/resolve-packages.js +41 -7
  84. package/dist/esm/core/resolve-packages.js.map +1 -1
  85. package/dist/esm/core/scaffold-engine.js +38 -9
  86. package/dist/esm/core/scaffold-engine.js.map +1 -1
  87. package/dist/esm/core/types.d.ts +8 -8
  88. package/dist/esm/core/types.js +11 -3
  89. package/dist/esm/core/types.js.map +1 -1
  90. package/dist/esm/core/validate-project-name.js.map +1 -1
  91. package/dist/esm/frameworks/index.d.ts +3 -3
  92. package/dist/esm/frameworks/index.js +138 -17
  93. package/dist/esm/frameworks/index.js.map +1 -1
  94. package/dist/esm/scaffold.d.ts +1 -1
  95. package/dist/esm/templates/base.js +15 -12
  96. package/dist/esm/templates/base.js.map +1 -1
  97. package/dist/esm/types.d.ts +1 -1
  98. package/package.json +13 -13
  99. package/src/addons/arktype/index.ts +2 -2
  100. package/src/addons/drizzle/index.ts +60 -47
  101. package/src/addons/kysely/index.ts +49 -36
  102. package/src/addons/pino/index.ts +12 -12
  103. package/src/addons/prisma/index.ts +128 -55
  104. package/src/addons/registry.ts +39 -35
  105. package/src/addons/types.ts +14 -14
  106. package/src/addons/valibot/index.ts +2 -2
  107. package/src/addons/validators.ts +11 -11
  108. package/src/addons/winston/index.ts +12 -12
  109. package/src/addons/zod/index.ts +2 -2
  110. package/src/cli.ts +28 -25
  111. package/src/commands/create.ts +185 -150
  112. package/src/core/json-output.ts +4 -4
  113. package/src/core/package-manager.ts +39 -35
  114. package/src/core/parse-options.ts +62 -43
  115. package/src/core/project-config.ts +13 -13
  116. package/src/core/resolve-packages.ts +79 -41
  117. package/src/core/scaffold-engine.ts +108 -36
  118. package/src/core/types.ts +61 -36
  119. package/src/core/validate-project-name.ts +40 -40
  120. package/src/frameworks/index.ts +164 -29
  121. package/src/scaffold.ts +3 -3
  122. package/src/templates/base.ts +65 -56
  123. package/src/types.ts +5 -4
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../src/addons/prisma/index.ts"],"sourcesContent":["import type { AddonDefinition } from '../types.js'\nimport type { DbDriver } from '../../core/types.js'\n\nfunction prismaProvider(driver: DbDriver): string {\n switch (driver) {\n case 'postgres':\n return 'postgresql'\n case 'mysql':\n return 'mysql'\n case 'sqlite':\n default:\n return 'sqlite'\n }\n}\n\nfunction envExample(driver: DbDriver): string {\n switch (driver) {\n case 'postgres':\n return 'DATABASE_URL=postgresql://user:password@localhost:5432/mydb\\n'\n case 'mysql':\n return 'DATABASE_URL=mysql://user:password@localhost:3306/mydb\\n'\n case 'sqlite':\n default:\n return 'DATABASE_URL=file:./local.db\\n'\n }\n}\n\nexport const prismaAddon: AddonDefinition = {\n id: 'prisma',\n category: 'database',\n dependencies() {\n return ['@prisma/client']\n },\n devDependencies() {\n return ['prisma']\n },\n scripts() {\n return {\n 'db:generate': 'prisma generate',\n 'db:push': 'prisma db push',\n }\n },\n bootBinding() {\n return {\n key: 'db',\n importPath: './db/index.js',\n factoryName: 'createDb',\n }\n },\n async apply(ctx, write) {\n const driver = ctx.driver ?? 'sqlite'\n const provider = prismaProvider(driver)\n await write(\n 'prisma/schema.prisma',\n `generator client {\n provider = \"prisma-client-js\"\n}\n\ndatasource db {\n provider = \"${provider}\"\n url = env(\"DATABASE_URL\")\n}\n\nmodel User {\n id Int @id @default(autoincrement())\n email String\n}\n`,\n )\n await write(\n 'src/db/index.ts',\n `import { PrismaClient } from '@prisma/client'\n\nexport function createDb() {\n return new PrismaClient()\n}\n`,\n )\n await write('.env.example', envExample(driver))\n },\n}\n"],"mappings":";AAGA,SAAS,eAAe,QAA0B;CAChD,QAAQ,QAAR;EACE,KAAK,YACH,OAAO;EACT,KAAK,SACH,OAAO;EAET,SACE,OAAO;CACX;AACF;AAEA,SAAS,WAAW,QAA0B;CAC5C,QAAQ,QAAR;EACE,KAAK,YACH,OAAO;EACT,KAAK,SACH,OAAO;EAET,SACE,OAAO;CACX;AACF;AAEA,IAAa,cAA+B;CAC1C,IAAI;CACJ,UAAU;CACV,eAAe;EACb,OAAO,CAAC,gBAAgB;CAC1B;CACA,kBAAkB;EAChB,OAAO,CAAC,QAAQ;CAClB;CACA,UAAU;EACR,OAAO;GACL,eAAe;GACf,WAAW;EACb;CACF;CACA,cAAc;EACZ,OAAO;GACL,KAAK;GACL,YAAY;GACZ,aAAa;EACf;CACF;CACA,MAAM,MAAM,KAAK,OAAO;EACtB,MAAM,SAAS,IAAI,UAAU;EAE7B,MAAM,MACJ,wBACA;;;;;gBAHe,eAAe,MAQpB,EAAS;;;;;;;;CASrB;EACA,MAAM,MACJ,mBACA;;;;;CAMF;EACA,MAAM,MAAM,gBAAgB,WAAW,MAAM,CAAC;CAChD;AACF"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../src/addons/prisma/index.ts"],"sourcesContent":["import type { AddonDefinition } from \"../types.js\";\nimport type { DbDriver } from \"../../core/types.js\";\n\nfunction prismaProvider(driver: DbDriver): string {\n switch (driver) {\n case \"postgres\":\n return \"postgresql\";\n case \"mysql\":\n return \"mysql\";\n case \"sqlite\":\n default:\n return \"sqlite\";\n }\n}\n\nfunction envExample(driver: DbDriver): string {\n switch (driver) {\n case \"postgres\":\n return \"DATABASE_URL=postgresql://user:password@localhost:5432/mydb\\n\";\n case \"mysql\":\n return \"DATABASE_URL=mysql://user:password@localhost:3306/mydb\\n\";\n case \"sqlite\":\n default:\n return \"DATABASE_URL=file:./local.db\\n\";\n }\n}\n\nfunction driverPackages(driver: DbDriver): string[] {\n switch (driver) {\n case \"postgres\":\n return [\"@prisma/adapter-pg\", \"pg\"];\n case \"mysql\":\n return [\"@prisma/adapter-mariadb\", \"mariadb\"];\n case \"sqlite\":\n default:\n return [\"@prisma/adapter-better-sqlite3\", \"better-sqlite3\"];\n }\n}\n\nfunction driverDevPackages(driver: DbDriver): string[] {\n switch (driver) {\n case \"postgres\":\n return [\"@types/pg\"];\n case \"sqlite\":\n return [\"@types/better-sqlite3\"];\n case \"mysql\":\n default:\n return [];\n }\n}\n\nfunction dbIndexSource(driver: DbDriver): string {\n switch (driver) {\n case \"postgres\":\n return `import { PrismaPg } from '@prisma/adapter-pg'\n\nimport { PrismaClient } from './prisma/client.js'\n\nexport function createDb() {\n const adapter = new PrismaPg({\n connectionString: process.env.DATABASE_URL,\n })\n return new PrismaClient({ adapter })\n}\n`;\n case \"mysql\":\n return `import { PrismaMariaDb } from '@prisma/adapter-mariadb'\n\nimport { PrismaClient } from './prisma/client.js'\n\nexport function createDb() {\n const adapter = new PrismaMariaDb(process.env.DATABASE_URL ?? 'mariadb://root:@localhost:3306/mydb')\n return new PrismaClient({ adapter })\n}\n`;\n case \"sqlite\":\n default:\n return `import { PrismaBetterSqlite3 } from '@prisma/adapter-better-sqlite3'\n\nimport { PrismaClient } from './prisma/client.js'\n\nexport function createDb() {\n const adapter = new PrismaBetterSqlite3({\n url: process.env.DATABASE_URL ?? 'file:./local.db',\n })\n return new PrismaClient({ adapter })\n}\n`;\n }\n}\n\nfunction prismaConfigSource(): string {\n return `import 'dotenv/config'\nimport { defineConfig, env } from 'prisma/config'\n\nexport default defineConfig({\n schema: 'prisma/schema.prisma',\n datasource: {\n url: env('DATABASE_URL'),\n },\n})\n`;\n}\n\nfunction schemaSource(driver: DbDriver): string {\n const provider = prismaProvider(driver);\n return `generator client {\n provider = \"prisma-client\"\n output = \"../src/db/prisma\"\n}\n\ndatasource db {\n provider = \"${provider}\"\n}\n\nmodel User {\n id Int @id @default(autoincrement())\n email String\n}\n`;\n}\n\nexport const prismaAddon: AddonDefinition = {\n id: \"prisma\",\n category: \"database\",\n dependencies(ctx) {\n const driver = ctx.driver ?? \"sqlite\";\n return [\"@prisma/client\", ...driverPackages(driver)];\n },\n devDependencies(ctx) {\n const driver = ctx.driver ?? \"sqlite\";\n return [\"prisma\", ...driverDevPackages(driver)];\n },\n scripts() {\n return {\n \"db:generate\": \"prisma generate\",\n \"db:push\": \"prisma db push\",\n };\n },\n bootBinding() {\n return {\n key: \"db\",\n importPath: \"./db/index.js\",\n factoryName: \"createDb\",\n };\n },\n async apply(ctx, write) {\n const driver = ctx.driver ?? \"sqlite\";\n await write(\"prisma.config.ts\", prismaConfigSource());\n await write(\"prisma/schema.prisma\", schemaSource(driver));\n await write(\"src/db/index.ts\", dbIndexSource(driver));\n await write(\".env.example\", envExample(driver));\n },\n};\n"],"mappings":";AAGA,SAAS,eAAe,QAA0B;CAChD,QAAQ,QAAR;EACE,KAAK,YACH,OAAO;EACT,KAAK,SACH,OAAO;EAET,SACE,OAAO;CACX;AACF;AAEA,SAAS,WAAW,QAA0B;CAC5C,QAAQ,QAAR;EACE,KAAK,YACH,OAAO;EACT,KAAK,SACH,OAAO;EAET,SACE,OAAO;CACX;AACF;AAEA,SAAS,eAAe,QAA4B;CAClD,QAAQ,QAAR;EACE,KAAK,YACH,OAAO,CAAC,sBAAsB,IAAI;EACpC,KAAK,SACH,OAAO,CAAC,2BAA2B,SAAS;EAE9C,SACE,OAAO,CAAC,kCAAkC,gBAAgB;CAC9D;AACF;AAEA,SAAS,kBAAkB,QAA4B;CACrD,QAAQ,QAAR;EACE,KAAK,YACH,OAAO,CAAC,WAAW;EACrB,KAAK,UACH,OAAO,CAAC,uBAAuB;EAEjC,SACE,OAAO,CAAC;CACZ;AACF;AAEA,SAAS,cAAc,QAA0B;CAC/C,QAAQ,QAAR;EACE,KAAK,YACH,OAAO;;;;;;;;;;;EAWT,KAAK,SACH,OAAO;;;;;;;;;EAUT,SACE,OAAO;;;;;;;;;;;CAWX;AACF;AAEA,SAAS,qBAA6B;CACpC,OAAO;;;;;;;;;;AAUT;AAEA,SAAS,aAAa,QAA0B;CAE9C,OAAO;;;;;;gBADU,eAAe,MAOlB,EAAS;;;;;;;;AAQzB;AAEA,IAAa,cAA+B;CAC1C,IAAI;CACJ,UAAU;CACV,aAAa,KAAK;EAEhB,OAAO,CAAC,kBAAkB,GAAG,eADd,IAAI,UAAU,QACqB,CAAC;CACrD;CACA,gBAAgB,KAAK;EAEnB,OAAO,CAAC,UAAU,GAAG,kBADN,IAAI,UAAU,QACgB,CAAC;CAChD;CACA,UAAU;EACR,OAAO;GACL,eAAe;GACf,WAAW;EACb;CACF;CACA,cAAc;EACZ,OAAO;GACL,KAAK;GACL,YAAY;GACZ,aAAa;EACf;CACF;CACA,MAAM,MAAM,KAAK,OAAO;EACtB,MAAM,SAAS,IAAI,UAAU;EAC7B,MAAM,MAAM,oBAAoB,mBAAmB,CAAC;EACpD,MAAM,MAAM,wBAAwB,aAAa,MAAM,CAAC;EACxD,MAAM,MAAM,mBAAmB,cAAc,MAAM,CAAC;EACpD,MAAM,MAAM,gBAAgB,WAAW,MAAM,CAAC;CAChD;AACF"}
@@ -1,10 +1,12 @@
1
+ import { arktypeAddon } from "./arktype/index.js";
1
2
  import { drizzleAddon } from "./drizzle/index.js";
2
3
  import { kyselyAddon } from "./kysely/index.js";
3
4
  import { pinoAddon } from "./pino/index.js";
4
5
  import { prismaAddon } from "./prisma/index.js";
5
- import { zodAddon } from "./zod/index.js";
6
+ import { valibotAddon } from "./valibot/index.js";
6
7
  import { winstonAddon } from "./winston/index.js";
7
- import { DB_DRIVERS, DB_ODMS, DEFAULT_DB_DRIVER, FRAMEWORKS, LOGGERS, VALIDATORS } from "../core/types.js";
8
+ import { zodAddon } from "./zod/index.js";
9
+ import { DB_DRIVERS, DB_ODMS, DEFAULT_DB_DRIVER, LOGGERS, PROJECT_TYPES, VALIDATORS } from "../core/types.js";
8
10
  //#region src/addons/registry.ts
9
11
  var ALL_ADDONS = [
10
12
  drizzleAddon,
@@ -12,14 +14,16 @@ var ALL_ADDONS = [
12
14
  kyselyAddon,
13
15
  pinoAddon,
14
16
  winstonAddon,
15
- zodAddon
17
+ zodAddon,
18
+ arktypeAddon,
19
+ valibotAddon
16
20
  ];
17
21
  var DB_ADDONS = ALL_ADDONS.filter((addon) => addon.category === "database");
18
22
  var LOGGER_ADDONS = ALL_ADDONS.filter((addon) => addon.category === "logger");
19
23
  var VALIDATOR_ADDONS = ALL_ADDONS.filter((addon) => addon.category === "validator");
20
24
  function getCapabilitiesCatalog() {
21
25
  return {
22
- frameworks: [...FRAMEWORKS],
26
+ types: [...PROJECT_TYPES],
23
27
  db: {
24
28
  odms: [...DB_ODMS],
25
29
  drivers: [...DB_DRIVERS],
@@ -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 { 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"}
1
+ {"version":3,"file":"registry.js","names":[],"sources":["../../../src/addons/registry.ts"],"sourcesContent":["import { arktypeAddon } from \"./arktype/index.js\";\nimport { drizzleAddon } from \"./drizzle/index.js\";\nimport { kyselyAddon } from \"./kysely/index.js\";\nimport { pinoAddon } from \"./pino/index.js\";\nimport { prismaAddon } from \"./prisma/index.js\";\nimport { valibotAddon } from \"./valibot/index.js\";\nimport { winstonAddon } from \"./winston/index.js\";\nimport { zodAddon } from \"./zod/index.js\";\nimport type { AddonDefinition } from \"./types.js\";\nimport type { CapabilitiesCatalog, ScaffoldContext } from \"../core/types.js\";\nimport {\n DB_DRIVERS,\n DB_ODMS,\n DEFAULT_DB_DRIVER,\n LOGGERS,\n PROJECT_TYPES,\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 arktypeAddon,\n valibotAddon,\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 types: [...PROJECT_TYPES],\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":";;;;;;;;;;AAmBA,IAAM,aAAgC;CACpC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,IAAM,YAAY,WAAW,QAAQ,UAAU,MAAM,aAAa,UAAU;AAC5E,IAAM,gBAAgB,WAAW,QAAQ,UAAU,MAAM,aAAa,QAAQ;AAC9E,IAAM,mBAAmB,WAAW,QAAQ,UAAU,MAAM,aAAa,WAAW;AAEpF,SAAgB,yBAA8C;CAC5D,OAAO;EACL,OAAO,CAAC,GAAG,aAAa;EACxB,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,MAAM,UAAU,MAAM,OAAO,IAAI,EAAE;EAC7D,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,2BAA2B,IAAI,GAAG,EAAE;EAEtD,SAAS,KAAK,OAAO;CACvB;CAEA,IAAI,IAAI,QAAQ;EACd,MAAM,cAAc,cAAc,MAAM,UAAU,MAAM,OAAO,IAAI,MAAM;EACzE,IAAI,CAAC,aACH,MAAM,IAAI,MAAM,yBAAyB,IAAI,OAAO,EAAE;EAExD,SAAS,KAAK,WAAW;CAC3B;CAGA,IADgB,SAAS,QAAQ,UAAU,MAAM,aAAa,UAAU,CAAC,CAAC,SAC5D,GACZ,MAAM,IAAI,MAAM,yCAAyC;CAI3D,IADoB,SAAS,QAAQ,UAAU,MAAM,aAAa,QAAQ,CAAC,CAAC,SAC1D,GAChB,MAAM,IAAI,MAAM,uCAAuC;CAGzD,IAAI,IAAI,WAAW;EACjB,MAAM,iBAAiB,iBAAiB,MAAM,UAAU,MAAM,OAAO,IAAI,SAAS;EAClF,IAAI,CAAC,gBACH,MAAM,IAAI,MAAM,4BAA4B,IAAI,UAAU,EAAE;EAE9D,SAAS,KAAK,cAAc;CAC9B;CAGA,IADuB,SAAS,QAAQ,UAAU,MAAM,aAAa,WAAW,CAAC,CAAC,SAC7D,GACnB,MAAM,IAAI,MAAM,0CAA0C;CAG5D,OAAO;AACT;AAEA,SAAgB,oBAAoB,KAAsB;CACxD,OAAO,cAAc,GAAG,CAAC,CACtB,KAAK,UAAU,MAAM,cAAc,GAAG,CAAC,CAAC,CACxC,QAAQ,MAAkC,QAAQ,CAAC,CAAC;AACzD"}
@@ -7,7 +7,7 @@ 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' | 'validator';
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>;
@@ -0,0 +1,7 @@
1
+ import { ValidatorAddon } from "../validators.js";
2
+ //#region src/addons/valibot/index.ts
3
+ var valibotAddon = ValidatorAddon("valibot");
4
+ //#endregion
5
+ export { valibotAddon };
6
+
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../src/addons/valibot/index.ts"],"sourcesContent":["import { ValidatorAddon } from \"../validators.js\";\n\nexport const valibotAddon = ValidatorAddon(\"valibot\");\n"],"mappings":";;AAEA,IAAa,eAAe,eAAe,SAAS"}
@@ -15,12 +15,12 @@ var VALIDATION_BLOCK_TEMPLATE = {
15
15
  query: v.object({ name: v.string() }),
16
16
  }`
17
17
  };
18
- var ROUTE_TEMPLATE = (validator) => `
18
+ var ROUTE_TEMPLATE = (validator) => `import { reply } from '@taserjs/router'
19
19
  import { t } from '#src/taser.js'
20
20
  ${IMPORT_LINES[validator]}
21
21
 
22
22
  export const Route = t.get('/'${VALIDATION_BLOCK_TEMPLATE[validator]}).handler((ctx) => {
23
- return ctx.reply.json({ message: \`Hello, \${ctx.query.name}!\` })
23
+ return reply.json({ message: \`Hello, \${ctx.query.name}!\` })
24
24
  })
25
25
  `;
26
26
  var ValidatorAddon = (validator) => {
@@ -1 +1 @@
1
- {"version":3,"file":"validators.js","names":[],"sources":["../../../src/addons/validators.ts"],"sourcesContent":["import type { ValidatorId } from '../core/types'\nimport type { AddonDefinition } from './types'\n\nexport const IMPORT_LINES: Record<ValidatorId, string> = {\n zod: `import { z } from 'zod'`,\n arktype: `import { type } from 'arktype'`,\n valibot: `import * as v from 'valibot'`,\n}\n\nexport const VALIDATION_BLOCK_TEMPLATE: Record<ValidatorId, string> = {\n zod: `, {\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"}
1
+ {"version":3,"file":"validators.js","names":[],"sources":["../../../src/addons/validators.ts"],"sourcesContent":["import type { ValidatorId } from \"../core/types\";\nimport type { AddonDefinition } from \"./types\";\n\nexport const IMPORT_LINES: Record<ValidatorId, string> = {\n zod: `import { z } from 'zod'`,\n arktype: `import { type } from 'arktype'`,\n valibot: `import * as v from 'valibot'`,\n};\n\nexport const VALIDATION_BLOCK_TEMPLATE: Record<ValidatorId, string> = {\n zod: `, {\n query: z.object({ name: z.string() }),\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) => `import { reply } from '@taserjs/router'\nimport { t } from '#src/taser.js'\n${IMPORT_LINES[validator]}\n\nexport const Route = t.get('/'${VALIDATION_BLOCK_TEMPLATE[validator]}).handler((ctx) => {\n return 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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../src/addons/winston/index.ts"],"sourcesContent":["import type { AddonDefinition } from '../types.js'\n\nexport const winstonAddon: AddonDefinition = {\n id: 'winston',\n category: 'logger',\n dependencies() {\n return ['winston']\n },\n devDependencies() {\n return []\n },\n bootBinding() {\n return {\n key: 'logger',\n importPath: './logger.js',\n factoryName: 'createLogger',\n }\n },\n async apply(_ctx, write) {\n await write(\n 'src/logger.ts',\n `import winston from 'winston'\n\nexport function createLogger() {\n return winston.createLogger({\n level: process.env.LOG_LEVEL ?? 'info',\n format: winston.format.json(),\n transports: [new winston.transports.Console()],\n })\n}\n`,\n )\n },\n}\n"],"mappings":";AAEA,IAAa,eAAgC;CAC3C,IAAI;CACJ,UAAU;CACV,eAAe;EACb,OAAO,CAAC,SAAS;CACnB;CACA,kBAAkB;EAChB,OAAO,CAAC;CACV;CACA,cAAc;EACZ,OAAO;GACL,KAAK;GACL,YAAY;GACZ,aAAa;EACf;CACF;CACA,MAAM,MAAM,MAAM,OAAO;EACvB,MAAM,MACJ,iBACA;;;;;;;;;CAUF;CACF;AACF"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../src/addons/winston/index.ts"],"sourcesContent":["import type { AddonDefinition } from \"../types.js\";\n\nexport const winstonAddon: AddonDefinition = {\n id: \"winston\",\n category: \"logger\",\n dependencies() {\n return [\"winston\"];\n },\n devDependencies() {\n return [];\n },\n bootBinding() {\n return {\n key: \"logger\",\n importPath: \"./logger.js\",\n factoryName: \"createLogger\",\n };\n },\n async apply(_ctx, write) {\n await write(\n \"src/logger.ts\",\n `import winston from 'winston'\n\nexport function createLogger() {\n return winston.createLogger({\n level: process.env.LOG_LEVEL ?? 'info',\n format: winston.format.json(),\n transports: [new winston.transports.Console()],\n })\n}\n`,\n );\n },\n};\n"],"mappings":";AAEA,IAAa,eAAgC;CAC3C,IAAI;CACJ,UAAU;CACV,eAAe;EACb,OAAO,CAAC,SAAS;CACnB;CACA,kBAAkB;EAChB,OAAO,CAAC;CACV;CACA,cAAc;EACZ,OAAO;GACL,KAAK;GACL,YAAY;GACZ,aAAa;EACf;CACF;CACA,MAAM,MAAM,MAAM,OAAO;EACvB,MAAM,MACJ,iBACA;;;;;;;;;CAUF;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../src/addons/zod/index.ts"],"sourcesContent":["import { ValidatorAddon } from '../validators.js'\n\nexport const zodAddon = ValidatorAddon('zod')\n"],"mappings":";;AAEA,IAAa,WAAW,eAAe,KAAK"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../src/addons/zod/index.ts"],"sourcesContent":["import { ValidatorAddon } from \"../validators.js\";\n\nexport const zodAddon = ValidatorAddon(\"zod\");\n"],"mappings":";;AAEA,IAAa,WAAW,eAAe,KAAK"}
package/dist/esm/cli.js CHANGED
@@ -9,9 +9,14 @@ async function main() {
9
9
  const { values, positionals } = parseArgs({
10
10
  args: process.argv.slice(2),
11
11
  options: {
12
+ type: {
13
+ type: "string",
14
+ short: "t"
15
+ },
12
16
  framework: { type: "string" },
13
17
  db: { type: "string" },
14
18
  logger: { type: "string" },
19
+ validator: { type: "string" },
15
20
  y: {
16
21
  type: "boolean",
17
22
  short: "y"
@@ -22,9 +27,11 @@ async function main() {
22
27
  allowPositionals: true
23
28
  });
24
29
  const parsed = buildParsedArgsFromCli({
30
+ ...values.type !== void 0 ? { type: values.type } : {},
25
31
  ...values.framework !== void 0 ? { framework: values.framework } : {},
26
32
  ...values.db !== void 0 ? { db: values.db } : {},
27
33
  ...values.logger !== void 0 ? { logger: values.logger } : {},
34
+ ...values.validator !== void 0 ? { validator: values.validator } : {},
28
35
  ...values.y !== void 0 ? { y: values.y } : {},
29
36
  ...values.noInstall !== void 0 ? { noInstall: values.noInstall } : {},
30
37
  ...values.json !== void 0 ? { json: values.json } : {}
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","names":[],"sources":["../../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { parseArgs } from 'node:util'\n\nimport * as p from '@clack/prompts'\nimport color from 'picocolors'\n\nimport { buildParsedArgsFromCli, runCreateCommand } from './commands/create.js'\nimport { printJsonError } from './core/json-output.js'\n\nasync function main(): Promise<void> {\n const { values, positionals } = parseArgs({\n args: process.argv.slice(2),\n options: {\n framework: { type: 'string' },\n db: { type: 'string' },\n logger: { type: 'string' },\n y: { type: 'boolean', short: 'y' },\n noInstall: { type: 'boolean' },\n json: { type: 'boolean' },\n },\n allowPositionals: true,\n })\n\n const parsed = buildParsedArgsFromCli(\n {\n ...(values.framework !== undefined ? { framework: values.framework } : {}),\n ...(values.db !== undefined ? { db: values.db } : {}),\n ...(values.logger !== undefined ? { logger: values.logger } : {}),\n ...(values.y !== undefined ? { y: values.y } : {}),\n ...(values.noInstall !== undefined ? { noInstall: values.noInstall } : {}),\n ...(values.json !== undefined ? { json: values.json } : {}),\n },\n positionals,\n )\n\n if (!parsed.json) {\n console.clear()\n p.intro(color.bgCyan(color.black(' create-taser ')))\n }\n\n try {\n await runCreateCommand(parsed)\n }\n catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n if (parsed.json) {\n printJsonError(message)\n process.exit(1)\n }\n throw error\n }\n}\n\nmain().catch((error: unknown) => {\n console.error(error)\n process.exit(1)\n})\n"],"mappings":";;;;;;;AASA,eAAe,OAAsB;CACnC,MAAM,EAAE,QAAQ,gBAAgB,UAAU;EACxC,MAAM,QAAQ,KAAK,MAAM,CAAC;EAC1B,SAAS;GACP,WAAW,EAAE,MAAM,SAAS;GAC5B,IAAI,EAAE,MAAM,SAAS;GACrB,QAAQ,EAAE,MAAM,SAAS;GACzB,GAAG;IAAE,MAAM;IAAW,OAAO;GAAI;GACjC,WAAW,EAAE,MAAM,UAAU;GAC7B,MAAM,EAAE,MAAM,UAAU;EAC1B;EACA,kBAAkB;CACpB,CAAC;CAED,MAAM,SAAS,uBACb;EACE,GAAI,OAAO,cAAc,KAAA,IAAY,EAAE,WAAW,OAAO,UAAU,IAAI,CAAC;EACxE,GAAI,OAAO,OAAO,KAAA,IAAY,EAAE,IAAI,OAAO,GAAG,IAAI,CAAC;EACnD,GAAI,OAAO,WAAW,KAAA,IAAY,EAAE,QAAQ,OAAO,OAAO,IAAI,CAAC;EAC/D,GAAI,OAAO,MAAM,KAAA,IAAY,EAAE,GAAG,OAAO,EAAE,IAAI,CAAC;EAChD,GAAI,OAAO,cAAc,KAAA,IAAY,EAAE,WAAW,OAAO,UAAU,IAAI,CAAC;EACxE,GAAI,OAAO,SAAS,KAAA,IAAY,EAAE,MAAM,OAAO,KAAK,IAAI,CAAC;CAC3D,GACA,WACF;CAEA,IAAI,CAAC,OAAO,MAAM;EAChB,QAAQ,MAAM;EACd,EAAE,MAAM,MAAM,OAAO,MAAM,MAAM,gBAAgB,CAAC,CAAC;CACrD;CAEA,IAAI;EACF,MAAM,iBAAiB,MAAM;CAC/B,SACO,OAAO;EACZ,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EACrE,IAAI,OAAO,MAAM;GACf,eAAe,OAAO;GACtB,QAAQ,KAAK,CAAC;EAChB;EACA,MAAM;CACR;AACF;AAEA,KAAK,CAAC,CAAC,OAAO,UAAmB;CAC/B,QAAQ,MAAM,KAAK;CACnB,QAAQ,KAAK,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"cli.js","names":[],"sources":["../../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { parseArgs } from \"node:util\";\n\nimport * as p from \"@clack/prompts\";\nimport color from \"picocolors\";\n\nimport { buildParsedArgsFromCli, runCreateCommand } from \"./commands/create.js\";\nimport { printJsonError } from \"./core/json-output.js\";\n\nasync function main(): Promise<void> {\n const { values, positionals } = parseArgs({\n args: process.argv.slice(2),\n options: {\n type: { type: \"string\", short: \"t\" },\n framework: { type: \"string\" },\n db: { type: \"string\" },\n logger: { type: \"string\" },\n validator: { type: \"string\" },\n y: { type: \"boolean\", short: \"y\" },\n noInstall: { type: \"boolean\" },\n json: { type: \"boolean\" },\n },\n allowPositionals: true,\n });\n\n const parsed = buildParsedArgsFromCli(\n {\n ...(values.type !== undefined ? { type: values.type } : {}),\n ...(values.framework !== undefined ? { framework: values.framework } : {}),\n ...(values.db !== undefined ? { db: values.db } : {}),\n ...(values.logger !== undefined ? { logger: values.logger } : {}),\n ...(values.validator !== undefined ? { validator: values.validator } : {}),\n ...(values.y !== undefined ? { y: values.y } : {}),\n ...(values.noInstall !== undefined ? { noInstall: values.noInstall } : {}),\n ...(values.json !== undefined ? { json: values.json } : {}),\n },\n positionals,\n );\n\n if (!parsed.json) {\n console.clear();\n p.intro(color.bgCyan(color.black(\" create-taser \")));\n }\n\n try {\n await runCreateCommand(parsed);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (parsed.json) {\n printJsonError(message);\n process.exit(1);\n }\n throw error;\n }\n}\n\nmain().catch((error: unknown) => {\n console.error(error);\n process.exit(1);\n});\n"],"mappings":";;;;;;;AASA,eAAe,OAAsB;CACnC,MAAM,EAAE,QAAQ,gBAAgB,UAAU;EACxC,MAAM,QAAQ,KAAK,MAAM,CAAC;EAC1B,SAAS;GACP,MAAM;IAAE,MAAM;IAAU,OAAO;GAAI;GACnC,WAAW,EAAE,MAAM,SAAS;GAC5B,IAAI,EAAE,MAAM,SAAS;GACrB,QAAQ,EAAE,MAAM,SAAS;GACzB,WAAW,EAAE,MAAM,SAAS;GAC5B,GAAG;IAAE,MAAM;IAAW,OAAO;GAAI;GACjC,WAAW,EAAE,MAAM,UAAU;GAC7B,MAAM,EAAE,MAAM,UAAU;EAC1B;EACA,kBAAkB;CACpB,CAAC;CAED,MAAM,SAAS,uBACb;EACE,GAAI,OAAO,SAAS,KAAA,IAAY,EAAE,MAAM,OAAO,KAAK,IAAI,CAAC;EACzD,GAAI,OAAO,cAAc,KAAA,IAAY,EAAE,WAAW,OAAO,UAAU,IAAI,CAAC;EACxE,GAAI,OAAO,OAAO,KAAA,IAAY,EAAE,IAAI,OAAO,GAAG,IAAI,CAAC;EACnD,GAAI,OAAO,WAAW,KAAA,IAAY,EAAE,QAAQ,OAAO,OAAO,IAAI,CAAC;EAC/D,GAAI,OAAO,cAAc,KAAA,IAAY,EAAE,WAAW,OAAO,UAAU,IAAI,CAAC;EACxE,GAAI,OAAO,MAAM,KAAA,IAAY,EAAE,GAAG,OAAO,EAAE,IAAI,CAAC;EAChD,GAAI,OAAO,cAAc,KAAA,IAAY,EAAE,WAAW,OAAO,UAAU,IAAI,CAAC;EACxE,GAAI,OAAO,SAAS,KAAA,IAAY,EAAE,MAAM,OAAO,KAAK,IAAI,CAAC;CAC3D,GACA,WACF;CAEA,IAAI,CAAC,OAAO,MAAM;EAChB,QAAQ,MAAM;EACd,EAAE,MAAM,MAAM,OAAO,MAAM,MAAM,gBAAgB,CAAC,CAAC;CACrD;CAEA,IAAI;EACF,MAAM,iBAAiB,MAAM;CAC/B,SAAS,OAAO;EACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EACrE,IAAI,OAAO,MAAM;GACf,eAAe,OAAO;GACtB,QAAQ,KAAK,CAAC;EAChB;EACA,MAAM;CACR;AACF;AAEA,KAAK,CAAC,CAAC,OAAO,UAAmB;CAC/B,QAAQ,MAAM,KAAK;CACnB,QAAQ,KAAK,CAAC;AAChB,CAAC"}
@@ -2,9 +2,11 @@ import { ParsedCreateArgs } from '../core/parse-options.js';
2
2
  import { ScaffoldResult } from '../core/types.js';
3
3
  export declare function runCreateCommand(args: ParsedCreateArgs): Promise<ScaffoldResult | undefined>;
4
4
  export declare function buildParsedArgsFromCli(values: {
5
+ type?: string;
5
6
  framework?: string;
6
7
  db?: string;
7
8
  logger?: string;
9
+ validator?: string;
8
10
  y?: boolean;
9
11
  noInstall?: boolean;
10
12
  json?: boolean;
@@ -1,7 +1,7 @@
1
- import { DB_DRIVERS, DB_ODMS, FRAMEWORKS, LOGGERS, VALIDATORS } from "../core/types.js";
1
+ import { DB_DRIVERS, DB_ODMS, LOGGERS, PROJECT_TYPES, VALIDATORS } from "../core/types.js";
2
2
  import { getCapabilitiesCatalog } from "../addons/registry.js";
3
3
  import { printCapabilitiesCatalog, printJsonError, printScaffoldResult } from "../core/json-output.js";
4
- import { parseDbFlag, parseFrameworkFlag, parseLoggerFlag, resolveScaffoldDefaults } from "../core/parse-options.js";
4
+ import { parseDbFlag, parseLoggerFlag, parseTypeFlag, parseValidatorFlag, resolveScaffoldDefaults } from "../core/parse-options.js";
5
5
  import { resolveUserAgent, runScript } from "../core/package-manager.js";
6
6
  import { scaffoldProject } from "../core/scaffold-engine.js";
7
7
  import { validateProjectName } from "../core/validate-project-name.js";
@@ -9,8 +9,8 @@ import * as p from "@clack/prompts";
9
9
  import color from "picocolors";
10
10
  import path from "node:path";
11
11
  //#region src/commands/create.ts
12
- function isFramework(value) {
13
- return typeof value === "string" && FRAMEWORKS.includes(value);
12
+ function isProjectType(value) {
13
+ return typeof value === "string" && PROJECT_TYPES.includes(value);
14
14
  }
15
15
  function isDbOdm(value) {
16
16
  return typeof value === "string" && DB_ODMS.includes(value);
@@ -37,30 +37,62 @@ async function promptInteractiveOptions(args) {
37
37
  p.cancel("Scaffold cancelled.");
38
38
  process.exit(0);
39
39
  }
40
- const framework = args.framework ?? await p.select({
41
- message: "Framework adapter",
40
+ const type = args.type ?? await p.select({
41
+ message: "Project type (runtime / framework)",
42
42
  options: [
43
43
  {
44
44
  value: "node",
45
- label: "Plain Node.js",
45
+ label: "Node.js",
46
46
  hint: "default"
47
47
  },
48
48
  {
49
49
  value: "express",
50
50
  label: "Express"
51
51
  },
52
+ {
53
+ value: "fastify",
54
+ label: "Fastify"
55
+ },
52
56
  {
53
57
  value: "hono",
54
58
  label: "Hono"
55
59
  },
56
60
  {
57
- value: "fastify",
58
- label: "Fastify"
61
+ value: "bun",
62
+ label: "Bun"
63
+ },
64
+ {
65
+ value: "deno",
66
+ label: "Deno"
67
+ },
68
+ {
69
+ value: "aws-lambda",
70
+ label: "AWS Lambda"
71
+ },
72
+ {
73
+ value: "cloudflare-workers",
74
+ label: "Cloudflare Workers"
75
+ },
76
+ {
77
+ value: "netlify",
78
+ label: "Netlify"
79
+ },
80
+ {
81
+ value: "vercel",
82
+ label: "Vercel"
83
+ },
84
+ {
85
+ value: "azure-functions",
86
+ label: "Azure Functions"
87
+ },
88
+ {
89
+ value: "google-cloud-run",
90
+ label: "Google Cloud Run"
59
91
  }
60
92
  ],
61
93
  initialValue: "node"
62
94
  });
63
- if (p.isCancel(framework) || !isFramework(framework)) {
95
+ if (p.isCancel(type) || !isProjectType(type)) {
64
96
  p.cancel("Scaffold cancelled.");
65
97
  process.exit(0);
66
98
  }
@@ -174,7 +206,7 @@ async function promptInteractiveOptions(args) {
174
206
  const validator = validatorChoice === "none" ? void 0 : isValidatorId(validatorChoice) ? validatorChoice : void 0;
175
207
  return {
176
208
  projectName: String(projectName).trim(),
177
- framework,
209
+ type,
178
210
  yes: args.yes,
179
211
  noInstall: args.noInstall,
180
212
  json: args.json,
@@ -195,7 +227,7 @@ async function runCreateCommand(args) {
195
227
  const resolved = !args.yes ? await promptInteractiveOptions(args) : {
196
228
  ...args,
197
229
  projectName: args.projectName?.trim(),
198
- framework: args.framework ?? "node"
230
+ type: args.type ?? "node"
199
231
  };
200
232
  if (!resolved.projectName) {
201
233
  const message = "Project name is required";
@@ -255,13 +287,15 @@ function buildParsedArgsFromCli(values, positionals) {
255
287
  json: values.json ?? false
256
288
  };
257
289
  if (positionals[0]) args.projectName = positionals[0];
258
- if (values.framework) args.framework = parseFrameworkFlag(values.framework);
290
+ const typeFlag = values.type ?? values.framework;
291
+ if (typeFlag) args.type = parseTypeFlag(typeFlag);
259
292
  if (values.db) {
260
293
  const parsed = parseDbFlag(values.db);
261
294
  args.db = parsed.db;
262
295
  args.driver = parsed.driver;
263
296
  }
264
297
  if (values.logger) args.logger = parseLoggerFlag(values.logger);
298
+ if (values.validator) args.validator = parseValidatorFlag(values.validator);
265
299
  return args;
266
300
  }
267
301
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"create.js","names":[],"sources":["../../../src/commands/create.ts"],"sourcesContent":["import path from 'node:path'\n\nimport * as p from '@clack/prompts'\nimport color from 'picocolors'\n\nimport { getCapabilitiesCatalog } from '../addons/registry.js'\nimport { 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
+ {"version":3,"file":"create.js","names":[],"sources":["../../../src/commands/create.ts"],"sourcesContent":["import path from \"node:path\";\n\nimport * as p from \"@clack/prompts\";\nimport color from \"picocolors\";\n\nimport { getCapabilitiesCatalog } from \"../addons/registry.js\";\nimport {\n printCapabilitiesCatalog,\n printJsonError,\n printScaffoldResult,\n} from \"../core/json-output.js\";\nimport {\n parseDbFlag,\n parseLoggerFlag,\n parseTypeFlag,\n parseValidatorFlag,\n type ParsedCreateArgs,\n resolveScaffoldDefaults,\n} from \"../core/parse-options.js\";\nimport { scaffoldProject } from \"../core/scaffold-engine.js\";\nimport type {\n DbDriver,\n DbOdm,\n LoggerId,\n ProjectType,\n ScaffoldResult,\n ValidatorId,\n} from \"../core/types.js\";\nimport { DB_DRIVERS, DB_ODMS, LOGGERS, PROJECT_TYPES, VALIDATORS } from \"../core/types.js\";\nimport { validateProjectName } from \"../core/validate-project-name.js\";\nimport { resolveUserAgent, runScript } from \"../core/package-manager.js\";\n\nfunction isProjectType(value: unknown): value is ProjectType {\n return typeof value === \"string\" && (PROJECT_TYPES as readonly string[]).includes(value);\n}\n\nfunction isDbOdm(value: unknown): value is DbOdm {\n return typeof value === \"string\" && (DB_ODMS as readonly string[]).includes(value);\n}\n\nfunction isDbDriver(value: unknown): value is DbDriver {\n return typeof value === \"string\" && (DB_DRIVERS as readonly string[]).includes(value);\n}\n\nfunction isLoggerId(value: unknown): value is LoggerId {\n return typeof value === \"string\" && (LOGGERS as readonly string[]).includes(value);\n}\n\nfunction isValidatorId(value: unknown): value is ValidatorId {\n return typeof value === \"string\" && (VALIDATORS as readonly string[]).includes(value);\n}\n\nasync function promptInteractiveOptions(args: ParsedCreateArgs): Promise<ParsedCreateArgs> {\n const projectName =\n args.projectName ??\n (await p.text({\n message: \"Project name\",\n placeholder: \"my-taser-app\",\n defaultValue: \"my-taser-app\",\n validate(value) {\n return validateProjectName(value);\n },\n }));\n\n if (p.isCancel(projectName)) {\n p.cancel(\"Scaffold cancelled.\");\n process.exit(0);\n }\n\n const type =\n args.type ??\n (await p.select({\n message: \"Project type (runtime / framework)\",\n options: [\n { value: \"node\", label: \"Node.js\", hint: \"default\" },\n { value: \"express\", label: \"Express\" },\n { value: \"fastify\", label: \"Fastify\" },\n { value: \"hono\", label: \"Hono\" },\n { value: \"bun\", label: \"Bun\" },\n { value: \"deno\", label: \"Deno\" },\n { value: \"aws-lambda\", label: \"AWS Lambda\" },\n { value: \"cloudflare-workers\", label: \"Cloudflare Workers\" },\n { value: \"netlify\", label: \"Netlify\" },\n { value: \"vercel\", label: \"Vercel\" },\n { value: \"azure-functions\", label: \"Azure Functions\" },\n { value: \"google-cloud-run\", label: \"Google Cloud Run\" },\n ],\n initialValue: \"node\",\n }));\n\n if (p.isCancel(type) || !isProjectType(type)) {\n p.cancel(\"Scaffold cancelled.\");\n process.exit(0);\n }\n\n const dbChoice =\n args.db ??\n (await p.select({\n message: \"Database\",\n options: [\n { value: \"none\", label: \"None\", hint: \"default\" },\n { value: \"drizzle\", label: \"Drizzle\" },\n { value: \"prisma\", label: \"Prisma\" },\n { value: \"kysely\", label: \"Kysely\" },\n ],\n initialValue: \"none\",\n }));\n\n if (p.isCancel(dbChoice)) {\n p.cancel(\"Scaffold cancelled.\");\n process.exit(0);\n }\n\n let db: DbOdm | undefined;\n let driver: DbDriver | undefined;\n\n if (dbChoice !== \"none\" && isDbOdm(dbChoice)) {\n db = dbChoice;\n const driverChoice =\n args.driver ??\n (await p.select({\n message: \"Database driver\",\n options: [\n { value: \"sqlite\", label: \"SQLite\", hint: \"default\" },\n { value: \"postgres\", label: \"PostgreSQL\" },\n { value: \"mysql\", label: \"MySQL\" },\n ],\n initialValue: \"sqlite\",\n }));\n\n if (p.isCancel(driverChoice) || !isDbDriver(driverChoice)) {\n p.cancel(\"Scaffold cancelled.\");\n process.exit(0);\n }\n driver = driverChoice;\n }\n\n const loggerChoice =\n args.logger ??\n (await p.select({\n message: \"Logger\",\n options: [\n { value: \"none\", label: \"None\", hint: \"default\" },\n { value: \"pino\", label: \"Pino\" },\n { value: \"winston\", label: \"Winston\" },\n ],\n initialValue: \"none\",\n }));\n\n if (p.isCancel(loggerChoice)) {\n p.cancel(\"Scaffold cancelled.\");\n process.exit(0);\n }\n\n const logger =\n loggerChoice === \"none\" ? undefined : isLoggerId(loggerChoice) ? loggerChoice : undefined;\n\n const validatorChoice =\n args.validator ??\n (await p.select({\n message: \"Validator\",\n options: [\n { value: \"none\", label: \"None\", hint: \"default\" },\n { value: \"zod\", label: \"Zod\" },\n { value: \"arktype\", label: \"Arktype\" },\n { value: \"valibot\", label: \"Valibot\" },\n ],\n initialValue: \"none\",\n }));\n\n if (p.isCancel(validatorChoice)) {\n p.cancel(\"Scaffold cancelled.\");\n process.exit(0);\n }\n\n const validator =\n validatorChoice === \"none\"\n ? undefined\n : isValidatorId(validatorChoice)\n ? validatorChoice\n : undefined;\n\n return {\n projectName: String(projectName).trim(),\n type,\n yes: args.yes,\n noInstall: args.noInstall,\n json: args.json,\n ...(db ? { db, driver: driver! } : {}),\n ...(logger ? { logger } : {}),\n ...(validator ? { validator } : {}),\n };\n}\n\nexport async function runCreateCommand(\n args: ParsedCreateArgs,\n): Promise<ScaffoldResult | undefined> {\n if (args.json && !args.projectName) {\n printCapabilitiesCatalog(getCapabilitiesCatalog());\n return undefined;\n }\n\n const cwd = process.cwd();\n const interactive = !args.yes;\n const resolved = interactive\n ? await promptInteractiveOptions(args)\n : {\n ...args,\n projectName: args.projectName?.trim(),\n type: args.type ?? \"node\",\n };\n\n if (!resolved.projectName) {\n const message = \"Project name is required\";\n if (args.json) {\n printJsonError(message);\n process.exit(1);\n }\n throw new Error(message);\n }\n\n const nameError = validateProjectName(resolved.projectName, cwd);\n if (nameError) {\n if (args.json) {\n printJsonError(nameError);\n process.exit(1);\n }\n throw new Error(nameError);\n }\n\n const targetDir = path.resolve(cwd, resolved.projectName);\n const scaffoldCtx = resolveScaffoldDefaults({\n ...resolved,\n projectName: resolved.projectName,\n });\n scaffoldCtx.targetDir = targetDir;\n\n if (!args.json) {\n const spinner = p.spinner();\n spinner.start(\"Scaffolding project\");\n try {\n const result = await scaffoldProject({\n ...scaffoldCtx,\n targetDir,\n skipInstall: args.noInstall,\n agent: resolveUserAgent(),\n });\n spinner.stop(\"Project created\");\n const cdPath = path.relative(cwd, targetDir) || \".\";\n p.note([`cd ${cdPath}`, runScript(resolveUserAgent(), \"dev\")].join(\"\\n\"), \"Next steps\");\n p.outro(color.green(\"Done.\"));\n return result;\n } catch (error) {\n spinner.stop(\"Scaffold failed\");\n throw error;\n }\n }\n\n const result = await scaffoldProject({\n ...scaffoldCtx,\n targetDir,\n skipInstall: args.noInstall,\n agent: resolveUserAgent(),\n });\n printScaffoldResult(result);\n return result;\n}\n\nexport function buildParsedArgsFromCli(\n values: {\n type?: string;\n framework?: string;\n db?: string;\n logger?: string;\n validator?: string;\n y?: boolean;\n noInstall?: boolean;\n json?: boolean;\n },\n positionals: string[],\n): ParsedCreateArgs {\n const args: ParsedCreateArgs = {\n yes: values.y ?? false,\n noInstall: values.noInstall ?? false,\n json: values.json ?? false,\n };\n\n if (positionals[0]) {\n args.projectName = positionals[0];\n }\n\n const typeFlag = values.type ?? values.framework;\n if (typeFlag) {\n args.type = parseTypeFlag(typeFlag);\n }\n\n if (values.db) {\n const parsed = parseDbFlag(values.db);\n args.db = parsed.db;\n args.driver = parsed.driver;\n }\n\n if (values.logger) {\n args.logger = parseLoggerFlag(values.logger);\n }\n\n if (values.validator) {\n args.validator = parseValidatorFlag(values.validator);\n }\n\n return args;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"json-output.js","names":[],"sources":["../../../src/core/json-output.ts"],"sourcesContent":["import type { CapabilitiesCatalog, ScaffoldResult } from './types.js'\n\nexport function printCapabilitiesCatalog(catalog: CapabilitiesCatalog): void {\n console.log(JSON.stringify(catalog, null, 2))\n}\n\nexport function printScaffoldResult(result: ScaffoldResult): void {\n console.log(JSON.stringify(result, null, 2))\n}\n\nexport function printJsonError(message: string): void {\n console.error(JSON.stringify({ error: message }))\n}\n"],"mappings":";AAEA,SAAgB,yBAAyB,SAAoC;CAC3E,QAAQ,IAAI,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAC9C;AAEA,SAAgB,oBAAoB,QAA8B;CAChE,QAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAC7C;AAEA,SAAgB,eAAe,SAAuB;CACpD,QAAQ,MAAM,KAAK,UAAU,EAAE,OAAO,QAAQ,CAAC,CAAC;AAClD"}
1
+ {"version":3,"file":"json-output.js","names":[],"sources":["../../../src/core/json-output.ts"],"sourcesContent":["import type { CapabilitiesCatalog, ScaffoldResult } from \"./types.js\";\n\nexport function printCapabilitiesCatalog(catalog: CapabilitiesCatalog): void {\n console.log(JSON.stringify(catalog, null, 2));\n}\n\nexport function printScaffoldResult(result: ScaffoldResult): void {\n console.log(JSON.stringify(result, null, 2));\n}\n\nexport function printJsonError(message: string): void {\n console.error(JSON.stringify({ error: message }));\n}\n"],"mappings":";AAEA,SAAgB,yBAAyB,SAAoC;CAC3E,QAAQ,IAAI,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAC9C;AAEA,SAAgB,oBAAoB,QAA8B;CAChE,QAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAC7C;AAEA,SAAgB,eAAe,SAAuB;CACpD,QAAQ,MAAM,KAAK,UAAU,EAAE,OAAO,QAAQ,CAAC,CAAC;AAClD"}
@@ -1,6 +1,7 @@
1
- import { Agent } from 'package-manager-detector';
1
+ import { Agent, ResolvedCommand } from 'package-manager-detector';
2
2
  export declare function resolveUserAgent(): Agent;
3
- export declare function installPackages(agent: Agent, cwd: string, { dependencies, devDependencies }: {
3
+ export declare function resolveInstallCommand(agent: Agent, packages: string[], dev: boolean): ResolvedCommand;
4
+ export declare function installPackages(agent: Agent, cwd: string, { dependencies, devDependencies, }: {
4
5
  dependencies: string[];
5
6
  devDependencies: string[];
6
7
  }): Promise<void>;
@@ -23,22 +23,13 @@ function runCommand(command, args, cwd) {
23
23
  });
24
24
  });
25
25
  }
26
- var fallback = {
27
- agent: "npm",
28
- install: (packages, dev) => {
29
- return [
30
- "install",
31
- ...packages,
32
- dev ? "-D" : ""
33
- ];
34
- }
35
- };
36
26
  function resolveInstallCommand(agent, packages, dev) {
37
- const command = resolveCommand(agent, "install", packages);
27
+ const args = dev ? ["-D", ...packages] : packages;
28
+ const command = resolveCommand(agent, "add", args);
38
29
  if (command) return command;
39
30
  return {
40
- command: fallback.agent,
41
- args: fallback.install(packages, dev)
31
+ command: "npm",
32
+ args: ["install", ...args]
42
33
  };
43
34
  }
44
35
  async function installPackages(agent, cwd, { dependencies, devDependencies }) {
@@ -57,6 +48,6 @@ function runScript(agent, script) {
57
48
  return `${resolved.command} ${resolved.args.join(" ")}`;
58
49
  }
59
50
  //#endregion
60
- export { installPackages, resolveUserAgent, runScript };
51
+ export { installPackages, resolveInstallCommand, resolveUserAgent, runScript };
61
52
 
62
53
  //# sourceMappingURL=package-manager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"package-manager.js","names":[],"sources":["../../../src/core/package-manager.ts"],"sourcesContent":["import { spawn } from 'node:child_process'\n\nimport type { Agent, ResolvedCommand } from 'package-manager-detector'\nimport { resolveCommand } from 'package-manager-detector/commands'\nimport { getUserAgent } from 'package-manager-detector/detect'\n\nexport function resolveUserAgent(): Agent {\n return getUserAgent() || 'npm'\n}\n\nfunction runCommand(command: string, args: string[], cwd: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd,\n stdio: 'inherit',\n shell: false,\n env: process.env,\n })\n child.on('error', reject)\n child.on('close', (code) => {\n if (code === 0) {\n resolve()\n return\n }\n reject(new Error(`${command} ${args.join(' ')} exited with code ${code}`))\n })\n })\n}\n\nconst fallback = {\n agent: 'npm',\n install: (packages: string[], dev: boolean) => {\n return ['install', ...packages, dev ? '-D' : '']\n },\n}\n\nfunction resolveInstallCommand(agent: Agent, packages: string[], dev: boolean): ResolvedCommand {\n const command = resolveCommand(agent, 'install', packages)\n if (command) return command\n\n return { command: fallback.agent, args: fallback.install(packages, dev) }\n}\n\nexport async function installPackages(\n agent: Agent,\n cwd: string,\n { dependencies, devDependencies }: {\n dependencies: string[]\n devDependencies: string[]\n },\n): Promise<void> {\n if (dependencies.length > 0) {\n const { command, args } = resolveInstallCommand(agent, dependencies, false)\n await runCommand(command, args, cwd)\n }\n if (devDependencies.length > 0) {\n const { command, args } = resolveInstallCommand(agent, devDependencies, true)\n await runCommand(command, args, cwd)\n }\n}\n\nexport function runScript(agent: Agent, script: string): string {\n const resolved = resolveCommand(agent, 'run', [script])\n if (!resolved) {\n throw new Error(`Unable to resolve run command for ${agent}`)\n }\n return `${resolved.command} ${resolved.args.join(' ')}`\n}\n"],"mappings":";;;;AAMA,SAAgB,mBAA0B;CACxC,OAAO,aAAa,KAAK;AAC3B;AAEA,SAAS,WAAW,SAAiB,MAAgB,KAA4B;CAC/E,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,MAAM,QAAQ,MAAM,SAAS,MAAM;GACjC;GACA,OAAO;GACP,OAAO;GACP,KAAK,QAAQ;EACf,CAAC;EACD,MAAM,GAAG,SAAS,MAAM;EACxB,MAAM,GAAG,UAAU,SAAS;GAC1B,IAAI,SAAS,GAAG;IACd,QAAQ;IACR;GACF;GACA,uBAAO,IAAI,MAAM,GAAG,QAAQ,GAAG,KAAK,KAAK,GAAG,EAAE,oBAAoB,MAAM,CAAC;EAC3E,CAAC;CACH,CAAC;AACH;AAEA,IAAM,WAAW;CACf,OAAO;CACP,UAAU,UAAoB,QAAiB;EAC7C,OAAO;GAAC;GAAW,GAAG;GAAU,MAAM,OAAO;EAAE;CACjD;AACF;AAEA,SAAS,sBAAsB,OAAc,UAAoB,KAA+B;CAC9F,MAAM,UAAU,eAAe,OAAO,WAAW,QAAQ;CACzD,IAAI,SAAS,OAAO;CAEpB,OAAO;EAAE,SAAS,SAAS;EAAO,MAAM,SAAS,QAAQ,UAAU,GAAG;CAAE;AAC1E;AAEA,eAAsB,gBACpB,OACA,KACA,EAAE,cAAc,mBAID;CACf,IAAI,aAAa,SAAS,GAAG;EAC3B,MAAM,EAAE,SAAS,SAAS,sBAAsB,OAAO,cAAc,KAAK;EAC1E,MAAM,WAAW,SAAS,MAAM,GAAG;CACrC;CACA,IAAI,gBAAgB,SAAS,GAAG;EAC9B,MAAM,EAAE,SAAS,SAAS,sBAAsB,OAAO,iBAAiB,IAAI;EAC5E,MAAM,WAAW,SAAS,MAAM,GAAG;CACrC;AACF;AAEA,SAAgB,UAAU,OAAc,QAAwB;CAC9D,MAAM,WAAW,eAAe,OAAO,OAAO,CAAC,MAAM,CAAC;CACtD,IAAI,CAAC,UACH,MAAM,IAAI,MAAM,qCAAqC,OAAO;CAE9D,OAAO,GAAG,SAAS,QAAQ,GAAG,SAAS,KAAK,KAAK,GAAG;AACtD"}
1
+ {"version":3,"file":"package-manager.js","names":[],"sources":["../../../src/core/package-manager.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\n\nimport type { Agent, ResolvedCommand } from \"package-manager-detector\";\nimport { resolveCommand } from \"package-manager-detector/commands\";\nimport { getUserAgent } from \"package-manager-detector/detect\";\n\nexport function resolveUserAgent(): Agent {\n return getUserAgent() || \"npm\";\n}\n\nfunction runCommand(command: string, args: string[], cwd: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd,\n stdio: \"inherit\",\n shell: false,\n env: process.env,\n });\n child.on(\"error\", reject);\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve();\n return;\n }\n reject(new Error(`${command} ${args.join(\" \")} exited with code ${code}`));\n });\n });\n}\n\nexport function resolveInstallCommand(\n agent: Agent,\n packages: string[],\n dev: boolean,\n): ResolvedCommand {\n const args = dev ? [\"-D\", ...packages] : packages;\n const command = resolveCommand(agent, \"add\", args);\n if (command) return command;\n\n return {\n command: \"npm\",\n args: [\"install\", ...args],\n };\n}\n\nexport async function installPackages(\n agent: Agent,\n cwd: string,\n {\n dependencies,\n devDependencies,\n }: {\n dependencies: string[];\n devDependencies: string[];\n },\n): Promise<void> {\n if (dependencies.length > 0) {\n const { command, args } = resolveInstallCommand(agent, dependencies, false);\n await runCommand(command, args, cwd);\n }\n if (devDependencies.length > 0) {\n const { command, args } = resolveInstallCommand(agent, devDependencies, true);\n await runCommand(command, args, cwd);\n }\n}\n\nexport function runScript(agent: Agent, script: string): string {\n const resolved = resolveCommand(agent, \"run\", [script]);\n if (!resolved) {\n throw new Error(`Unable to resolve run command for ${agent}`);\n }\n return `${resolved.command} ${resolved.args.join(\" \")}`;\n}\n"],"mappings":";;;;AAMA,SAAgB,mBAA0B;CACxC,OAAO,aAAa,KAAK;AAC3B;AAEA,SAAS,WAAW,SAAiB,MAAgB,KAA4B;CAC/E,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,MAAM,QAAQ,MAAM,SAAS,MAAM;GACjC;GACA,OAAO;GACP,OAAO;GACP,KAAK,QAAQ;EACf,CAAC;EACD,MAAM,GAAG,SAAS,MAAM;EACxB,MAAM,GAAG,UAAU,SAAS;GAC1B,IAAI,SAAS,GAAG;IACd,QAAQ;IACR;GACF;GACA,uBAAO,IAAI,MAAM,GAAG,QAAQ,GAAG,KAAK,KAAK,GAAG,EAAE,oBAAoB,MAAM,CAAC;EAC3E,CAAC;CACH,CAAC;AACH;AAEA,SAAgB,sBACd,OACA,UACA,KACiB;CACjB,MAAM,OAAO,MAAM,CAAC,MAAM,GAAG,QAAQ,IAAI;CACzC,MAAM,UAAU,eAAe,OAAO,OAAO,IAAI;CACjD,IAAI,SAAS,OAAO;CAEpB,OAAO;EACL,SAAS;EACT,MAAM,CAAC,WAAW,GAAG,IAAI;CAC3B;AACF;AAEA,eAAsB,gBACpB,OACA,KACA,EACE,cACA,mBAKa;CACf,IAAI,aAAa,SAAS,GAAG;EAC3B,MAAM,EAAE,SAAS,SAAS,sBAAsB,OAAO,cAAc,KAAK;EAC1E,MAAM,WAAW,SAAS,MAAM,GAAG;CACrC;CACA,IAAI,gBAAgB,SAAS,GAAG;EAC9B,MAAM,EAAE,SAAS,SAAS,sBAAsB,OAAO,iBAAiB,IAAI;EAC5E,MAAM,WAAW,SAAS,MAAM,GAAG;CACrC;AACF;AAEA,SAAgB,UAAU,OAAc,QAAwB;CAC9D,MAAM,WAAW,eAAe,OAAO,OAAO,CAAC,MAAM,CAAC;CACtD,IAAI,CAAC,UACH,MAAM,IAAI,MAAM,qCAAqC,OAAO;CAE9D,OAAO,GAAG,SAAS,QAAQ,GAAG,SAAS,KAAK,KAAK,GAAG;AACtD"}
@@ -1,7 +1,7 @@
1
- import { DbDriver, DbOdm, Framework, LoggerId, ScaffoldContext, ValidatorId } from './types.js';
1
+ import { DbDriver, DbOdm, LoggerId, ProjectType, ScaffoldContext, ValidatorId } from './types.js';
2
2
  export type ParsedCreateArgs = {
3
3
  projectName?: string;
4
- framework?: Framework;
4
+ type?: ProjectType;
5
5
  db?: DbOdm;
6
6
  driver?: DbDriver;
7
7
  logger?: LoggerId;
@@ -15,5 +15,6 @@ export declare function parseDbFlag(value: string): {
15
15
  driver: DbDriver;
16
16
  };
17
17
  export declare function resolveScaffoldDefaults(args: ParsedCreateArgs): ScaffoldContext;
18
- export declare function parseFrameworkFlag(value: string): Framework;
18
+ export declare function parseTypeFlag(value: string): ProjectType;
19
19
  export declare function parseLoggerFlag(value: string): LoggerId;
20
+ export declare function parseValidatorFlag(value: string): ValidatorId;
@@ -1,7 +1,7 @@
1
- import { DB_DRIVERS, DB_ODMS, DEFAULT_DB_DRIVER, FRAMEWORKS, LOGGERS } from "./types.js";
1
+ import { DB_DRIVERS, DB_ODMS, DEFAULT_DB_DRIVER, LOGGERS, PROJECT_TYPES, VALIDATORS } from "./types.js";
2
2
  //#region src/core/parse-options.ts
3
- function isFramework(value) {
4
- return FRAMEWORKS.includes(value);
3
+ function isProjectType(value) {
4
+ return PROJECT_TYPES.includes(value);
5
5
  }
6
6
  function isDbOdm(value) {
7
7
  return DB_ODMS.includes(value);
@@ -12,6 +12,9 @@ function isDbDriver(value) {
12
12
  function isLoggerId(value) {
13
13
  return LOGGERS.includes(value);
14
14
  }
15
+ function isValidatorId(value) {
16
+ return VALIDATORS.includes(value);
17
+ }
15
18
  function parseDbFlag(value) {
16
19
  const [odm, driver] = value.split(":");
17
20
  if (!odm || !isDbOdm(odm)) throw new Error(`Invalid --db value "${value}". Use drizzle, prisma, or kysely (optionally with :postgres, :sqlite, or :mysql).`);
@@ -26,31 +29,37 @@ function parseDbFlag(value) {
26
29
  };
27
30
  }
28
31
  function resolveScaffoldDefaults(args) {
29
- const framework = args.framework ?? "node";
32
+ const type = args.type ?? "node";
30
33
  const db = args.db;
31
34
  const logger = args.logger;
35
+ const validator = args.validator;
32
36
  if (!args.projectName) throw new Error("Project name is required");
33
37
  const result = {
34
38
  projectName: args.projectName.trim(),
35
39
  targetDir: "",
36
- framework
40
+ type
37
41
  };
38
42
  if (db) {
39
43
  result.db = db;
40
44
  result.driver = args.driver ?? "sqlite";
41
45
  }
42
46
  if (logger) result.logger = logger;
47
+ if (validator) result.validator = validator;
43
48
  return result;
44
49
  }
45
- function parseFrameworkFlag(value) {
46
- if (!isFramework(value)) throw new Error(`Invalid --framework "${value}". Use node, express, hono, or fastify.`);
50
+ function parseTypeFlag(value) {
51
+ if (!isProjectType(value)) throw new Error(`Invalid --type "${value}". Use ${PROJECT_TYPES.join(", ")}.`);
47
52
  return value;
48
53
  }
49
54
  function parseLoggerFlag(value) {
50
55
  if (!isLoggerId(value)) throw new Error(`Invalid --logger "${value}". Use pino or winston.`);
51
56
  return value;
52
57
  }
58
+ function parseValidatorFlag(value) {
59
+ if (!isValidatorId(value)) throw new Error(`Invalid --validator "${value}". Use zod, arktype, or valibot.`);
60
+ return value;
61
+ }
53
62
  //#endregion
54
- export { parseDbFlag, parseFrameworkFlag, parseLoggerFlag, resolveScaffoldDefaults };
63
+ export { parseDbFlag, parseLoggerFlag, parseTypeFlag, parseValidatorFlag, resolveScaffoldDefaults };
55
64
 
56
65
  //# sourceMappingURL=parse-options.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse-options.js","names":[],"sources":["../../../src/core/parse-options.ts"],"sourcesContent":["import {\n DB_DRIVERS,\n DB_ODMS,\n DEFAULT_DB_DRIVER,\n 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,WAAiC,SAAS,KAAK;AACzD;AAEA,SAAS,QAAQ,OAA+B;CAC9C,OAAQ,QAA8B,SAAS,KAAK;AACtD;AAEA,SAAS,WAAW,OAAkC;CACpD,OAAQ,WAAiC,SAAS,KAAK;AACzD;AAEA,SAAS,WAAW,OAAkC;CACpD,OAAQ,QAA8B,SAAS,KAAK;AACtD;AAEA,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;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.js","names":[],"sources":["../../../src/core/parse-options.ts"],"sourcesContent":["import {\n DB_DRIVERS,\n DB_ODMS,\n DEFAULT_DB_DRIVER,\n LOGGERS,\n PROJECT_TYPES,\n VALIDATORS,\n type DbDriver,\n type DbOdm,\n type LoggerId,\n type ProjectType,\n type ScaffoldContext,\n type ValidatorId,\n} from \"./types.js\";\n\nexport type ParsedCreateArgs = {\n projectName?: string;\n type?: ProjectType;\n db?: DbOdm;\n driver?: DbDriver;\n logger?: LoggerId;\n validator?: ValidatorId;\n yes: boolean;\n noInstall: boolean;\n json: boolean;\n};\n\nfunction isProjectType(value: string): value is ProjectType {\n return (PROJECT_TYPES as readonly string[]).includes(value);\n}\n\nfunction isDbOdm(value: string): value is DbOdm {\n return (DB_ODMS as readonly string[]).includes(value);\n}\n\nfunction isDbDriver(value: string): value is DbDriver {\n return (DB_DRIVERS as readonly string[]).includes(value);\n}\n\nfunction isLoggerId(value: string): value is LoggerId {\n return (LOGGERS as readonly string[]).includes(value);\n}\n\nfunction isValidatorId(value: string): value is ValidatorId {\n return (VALIDATORS as readonly string[]).includes(value);\n}\n\nexport function parseDbFlag(value: string): { db: DbOdm; driver: DbDriver } {\n const [odm, driver] = value.split(\":\");\n if (!odm || !isDbOdm(odm)) {\n throw new Error(\n `Invalid --db value \"${value}\". Use drizzle, prisma, or kysely (optionally with :postgres, :sqlite, or :mysql).`,\n );\n }\n\n if (driver === undefined || driver === \"\") {\n return { db: odm, driver: DEFAULT_DB_DRIVER };\n }\n\n if (!isDbDriver(driver)) {\n throw new Error(`Invalid database driver \"${driver}\". Use postgres, sqlite, or mysql.`);\n }\n\n return { db: odm, driver };\n}\n\nexport function resolveScaffoldDefaults(args: ParsedCreateArgs): ScaffoldContext {\n const type = args.type ?? \"node\";\n const db = args.db;\n const logger = args.logger;\n const validator = args.validator;\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 type,\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 if (validator) {\n result.validator = validator;\n }\n\n return result;\n}\n\nexport function parseTypeFlag(value: string): ProjectType {\n if (!isProjectType(value)) {\n throw new Error(`Invalid --type \"${value}\". Use ${PROJECT_TYPES.join(\", \")}.`);\n }\n return value;\n}\n\nexport function parseLoggerFlag(value: string): LoggerId {\n if (!isLoggerId(value)) {\n throw new Error(`Invalid --logger \"${value}\". Use pino or winston.`);\n }\n return value;\n}\n\nexport function parseValidatorFlag(value: string): ValidatorId {\n if (!isValidatorId(value)) {\n throw new Error(`Invalid --validator \"${value}\". Use zod, arktype, or valibot.`);\n }\n return value;\n}\n"],"mappings":";;AA2BA,SAAS,cAAc,OAAqC;CAC1D,OAAQ,cAAoC,SAAS,KAAK;AAC5D;AAEA,SAAS,QAAQ,OAA+B;CAC9C,OAAQ,QAA8B,SAAS,KAAK;AACtD;AAEA,SAAS,WAAW,OAAkC;CACpD,OAAQ,WAAiC,SAAS,KAAK;AACzD;AAEA,SAAS,WAAW,OAAkC;CACpD,OAAQ,QAA8B,SAAS,KAAK;AACtD;AAEA,SAAS,cAAc,OAAqC;CAC1D,OAAQ,WAAiC,SAAS,KAAK;AACzD;AAEA,SAAgB,YAAY,OAAgD;CAC1E,MAAM,CAAC,KAAK,UAAU,MAAM,MAAM,GAAG;CACrC,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,GACtB,MAAM,IAAI,MACR,uBAAuB,MAAM,mFAC/B;CAGF,IAAI,WAAW,KAAA,KAAa,WAAW,IACrC,OAAO;EAAE,IAAI;EAAK,QAAQ;CAAkB;CAG9C,IAAI,CAAC,WAAW,MAAM,GACpB,MAAM,IAAI,MAAM,4BAA4B,OAAO,mCAAmC;CAGxF,OAAO;EAAE,IAAI;EAAK;CAAO;AAC3B;AAEA,SAAgB,wBAAwB,MAAyC;CAC/E,MAAM,OAAO,KAAK,QAAQ;CAC1B,MAAM,KAAK,KAAK;CAChB,MAAM,SAAS,KAAK;CACpB,MAAM,YAAY,KAAK;CAEvB,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,IAAI,WACF,OAAO,YAAY;CAGrB,OAAO;AACT;AAEA,SAAgB,cAAc,OAA4B;CACxD,IAAI,CAAC,cAAc,KAAK,GACtB,MAAM,IAAI,MAAM,mBAAmB,MAAM,SAAS,cAAc,KAAK,IAAI,EAAE,EAAE;CAE/E,OAAO;AACT;AAEA,SAAgB,gBAAgB,OAAyB;CACvD,IAAI,CAAC,WAAW,KAAK,GACnB,MAAM,IAAI,MAAM,qBAAqB,MAAM,wBAAwB;CAErE,OAAO;AACT;AAEA,SAAgB,mBAAmB,OAA4B;CAC7D,IAAI,CAAC,cAAc,KAAK,GACtB,MAAM,IAAI,MAAM,wBAAwB,MAAM,iCAAiC;CAEjF,OAAO;AACT"}
@@ -2,12 +2,13 @@ import path from "node:path";
2
2
  import { writeFile } from "node:fs/promises";
3
3
  //#region src/core/project-config.ts
4
4
  async function writeProjectConfig(root, ctx) {
5
- const config = { framework: ctx.framework };
5
+ const config = { type: ctx.type };
6
6
  if (ctx.db) {
7
7
  config.db = ctx.db;
8
8
  if (ctx.driver) config.driver = ctx.driver;
9
9
  }
10
10
  if (ctx.logger) config.logger = ctx.logger;
11
+ if (ctx.validator) config.validator = ctx.validator;
11
12
  await writeFile(path.join(root, ".taser.json"), `${JSON.stringify(config, null, 2)}\n`, "utf8");
12
13
  }
13
14
  //#endregion