create-taserjs 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/addons/registry.cjs +0 -3
- package/dist/cjs/addons/registry.cjs.map +1 -1
- package/dist/cjs/addons/validators.cjs +7 -4
- package/dist/cjs/addons/validators.cjs.map +1 -1
- package/dist/cjs/core/resolve-packages.cjs +1 -1
- package/dist/cjs/core/resolve-packages.cjs.map +1 -1
- package/dist/cjs/core/scaffold-engine.cjs +2 -22
- package/dist/cjs/core/scaffold-engine.cjs.map +1 -1
- package/dist/cjs/frameworks/index.cjs +7 -26
- package/dist/cjs/frameworks/index.cjs.map +1 -1
- package/dist/cjs/frameworks/index.d.cts +1 -1
- package/dist/cjs/templates/base.cjs +10 -6
- package/dist/cjs/templates/base.cjs.map +1 -1
- package/dist/esm/addons/registry.js +0 -3
- package/dist/esm/addons/registry.js.map +1 -1
- package/dist/esm/addons/validators.js +7 -4
- package/dist/esm/addons/validators.js.map +1 -1
- package/dist/esm/core/resolve-packages.js +1 -1
- package/dist/esm/core/resolve-packages.js.map +1 -1
- package/dist/esm/core/scaffold-engine.js +2 -22
- package/dist/esm/core/scaffold-engine.js.map +1 -1
- package/dist/esm/frameworks/index.d.ts +1 -1
- package/dist/esm/frameworks/index.js +7 -26
- package/dist/esm/frameworks/index.js.map +1 -1
- package/dist/esm/templates/base.js +10 -6
- package/dist/esm/templates/base.js.map +1 -1
- package/package.json +1 -1
- package/src/addons/registry.ts +0 -15
- package/src/addons/validators.ts +7 -4
- package/src/core/resolve-packages.ts +1 -1
- package/src/core/scaffold-engine.ts +2 -16
- package/src/frameworks/index.ts +7 -35
- package/src/templates/base.ts +11 -7
|
@@ -45,14 +45,11 @@ function resolveAddons(ctx) {
|
|
|
45
45
|
if (!loggerAddon) throw new Error(`Unknown logger addon "${ctx.logger}"`);
|
|
46
46
|
selected.push(loggerAddon);
|
|
47
47
|
}
|
|
48
|
-
if (selected.filter((addon) => addon.category === "database").length > 1) throw new Error("Only one database addon can be selected");
|
|
49
|
-
if (selected.filter((addon) => addon.category === "logger").length > 1) throw new Error("Only one logger addon can be selected");
|
|
50
48
|
if (ctx.validator) {
|
|
51
49
|
const validatorAddon = VALIDATOR_ADDONS.find((addon) => addon.id === ctx.validator);
|
|
52
50
|
if (!validatorAddon) throw new Error(`Unknown validator addon "${ctx.validator}"`);
|
|
53
51
|
selected.push(validatorAddon);
|
|
54
52
|
}
|
|
55
|
-
if (selected.filter((addon) => addon.category === "validator").length > 1) throw new Error("Only one validator addon can be selected");
|
|
56
53
|
return selected;
|
|
57
54
|
}
|
|
58
55
|
function collectBootBindings(ctx) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.cjs","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
|
|
1
|
+
{"version":3,"file":"registry.cjs","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 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 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,gBAAA;CACA,gBAAA;CACA,gBAAA;CACA,gBAAA;CACA,gBAAA;CACA,gBAAA;CACA,cAAA;CACA,gBAAA;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,cAAA,aAAa;EACxB,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,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;CAEA,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;CAEA,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"}
|
|
@@ -6,20 +6,23 @@ var IMPORT_LINES = {
|
|
|
6
6
|
};
|
|
7
7
|
var VALIDATION_BLOCK_TEMPLATE = {
|
|
8
8
|
zod: `, {
|
|
9
|
-
query: z.object({ name: z.string() }),
|
|
9
|
+
query: z.object({ name: z.string().default('Taser') }),
|
|
10
10
|
}`,
|
|
11
11
|
arktype: `, {
|
|
12
|
-
query: type({ name: 'string' }),
|
|
12
|
+
query: type({ 'name?': 'string = "Taser"' }),
|
|
13
13
|
}`,
|
|
14
14
|
valibot: `, {
|
|
15
|
-
query: v.object({ name: v.string() }),
|
|
15
|
+
query: v.object({ name: v.optional(v.string(), 'Taser') }),
|
|
16
16
|
}`
|
|
17
17
|
};
|
|
18
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
|
+
const GET = t.get('/'${VALIDATION_BLOCK_TEMPLATE[validator]})
|
|
23
|
+
|
|
24
|
+
export type RouteContext = typeof GET.$Infer.Context
|
|
25
|
+
export const Route = GET.handler((ctx) => {
|
|
23
26
|
return reply.json({ message: \`Hello, \${ctx.query.name}!\` })
|
|
24
27
|
})
|
|
25
28
|
`;
|
|
@@ -1 +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) => `import { reply } from '@taserjs/router'\nimport { t } from '#src/taser.js'\n${IMPORT_LINES[validator]}\n\
|
|
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().default('Taser') }),\n}`,\n arktype: `, {\n query: type({ 'name?': 'string = \"Taser\"' }),\n}`,\n valibot: `, {\n query: v.object({ name: v.optional(v.string(), 'Taser') }),\n}`,\n};\n\nconst ROUTE_TEMPLATE = (validator: ValidatorId) => `import { reply } from '@taserjs/router'\nimport { t } from '#src/taser.js'\n${IMPORT_LINES[validator]}\n\nconst GET = t.get('/'${VALIDATION_BLOCK_TEMPLATE[validator]})\n\nexport type RouteContext = typeof GET.$Infer.Context\nexport const Route = GET.handler((ctx) => {\n return 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;;uBAEH,0BAA0B,WAAW;;;;;;;AAQ5D,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":"resolve-packages.cjs","names":[],"sources":["../../../src/core/resolve-packages.ts"],"sourcesContent":["import { resolveAddons } from \"../addons/registry.js\";\nimport type { PackageGroups, ProjectType, ScaffoldContext } from \"../core/types.js\";\n\nfunction typePackages(type: ProjectType): PackageGroups {\n const dependencies = [\"@taserjs/router\", \"dotenv\"];\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 (type) {\n case \"express\":\n dependencies.push(\"@taserjs/adapter-express\", \"express\");\n devDependencies.push(\"@types/express\");\n break;\n case \"fastify\":\n dependencies.push(\"@taserjs/adapter-fastify\", \"fastify\");\n break;\n case \"hono\":\n dependencies.push(\"@hono/node-server\", \"hono\");\n break;\n case \"bun\":\n // Bun has native TypeScript and runtime execution\n devDependencies.push(\"@types/bun\");\n scripts[\"dev:server\"] = \"bun --watch src/index.ts\";\n scripts.start = \"bun src/index.ts\";\n scripts.serve = \"bun dist/index.mjs\";\n break;\n case \"deno\":\n scripts[\"dev:server\"] = \"deno run --watch --allow-net --allow-env --allow-read src/index.ts\";\n scripts.start = \"deno run --allow-net --allow-env --allow-read src/index.ts\";\n scripts.serve = \"deno run --allow-net --allow-env --allow-read dist/index.mjs\";\n break;\n case \"aws-lambda\":\n dependencies.push(\"hono\");\n devDependencies.push(\"@types/aws-lambda\");\n break;\n case \"cloudflare-workers\": {\n // Cloudflare workers uses wrangler\n const cfDevDeps = devDependencies.filter((d) => d !== \"tsx\");\n cfDevDeps.push(\"wrangler\", \"@cloudflare/workers-types\");\n devDependencies.length = 0;\n devDependencies.push(...cfDevDeps);\n scripts[\"dev:server\"] = \"wrangler dev\";\n scripts.deploy = \"wrangler deploy\";\n break;\n }\n case \"netlify\":\n dependencies.push(\"hono\", \"@netlify/functions\");\n break;\n case \"vercel\":\n dependencies.push(\"hono\");\n devDependencies.push(\"@vercel/node\");\n break;\n case \"azure-functions\":\n dependencies.push(\"hono\", \"@azure/functions\", \"@marplex/hono-azurefunc-adapter\");\n break;\n case \"google-cloud-run\":\n case \"node\":\n default:\n dependencies.push(\"@hono/node-server\");\n break;\n }\n\n return { dependencies, devDependencies, scripts };\n}\n\nexport function resolvePackages(ctx: ScaffoldContext): PackageGroups {\n const base = typePackages(ctx.type);\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\nexport function getPackageGroups(\n type: ProjectType,\n): Omit<PackageGroups, \"scripts\"> & { scripts?: Record<string, string> } {\n const groups = typePackages(type);\n return groups;\n}\n"],"mappings":";;AAGA,SAAS,aAAa,MAAkC;CACtD,MAAM,eAAe,CAAC,mBAAmB,QAAQ;CACjD,MAAM,kBAAkB;EACtB;EACA;EACA;EACA;EACA;EACA;CACF;CACA,MAAM,UAAkC,CAAC;CAEzC,QAAQ,MAAR;EACE,KAAK;GACH,aAAa,KAAK,4BAA4B,SAAS;GACvD,gBAAgB,KAAK,gBAAgB;GACrC;EACF,KAAK;GACH,aAAa,KAAK,4BAA4B,SAAS;GACvD;EACF,KAAK;GACH,aAAa,KAAK,qBAAqB,MAAM;GAC7C;EACF,KAAK;GAEH,gBAAgB,KAAK,YAAY;GACjC,QAAQ,gBAAgB;GACxB,QAAQ,QAAQ;GAChB,QAAQ,QAAQ;GAChB;EACF,KAAK;GACH,QAAQ,gBAAgB;GACxB,QAAQ,QAAQ;GAChB,QAAQ,QAAQ;GAChB;EACF,KAAK;GACH,aAAa,KAAK,MAAM;GACxB,gBAAgB,KAAK,mBAAmB;GACxC;EACF,KAAK,sBAAsB;GAEzB,MAAM,YAAY,gBAAgB,QAAQ,MAAM,MAAM,KAAK;GAC3D,UAAU,KAAK,YAAY,2BAA2B;GACtD,gBAAgB,SAAS;GACzB,gBAAgB,KAAK,GAAG,SAAS;GACjC,QAAQ,gBAAgB;GACxB,QAAQ,SAAS;GACjB;EACF;EACA,KAAK;GACH,aAAa,KAAK,QAAQ,oBAAoB;GAC9C;EACF,KAAK;GACH,aAAa,KAAK,MAAM;GACxB,gBAAgB,KAAK,cAAc;GACnC;EACF,KAAK;GACH,aAAa,KAAK,QAAQ,oBAAoB,iCAAiC;GAC/E;EAGF,SACE,aAAa,KAAK,mBAAmB;CAEzC;CAEA,OAAO;EAAE;EAAc;EAAiB;CAAQ;AAClD;AAEA,SAAgB,gBAAgB,KAAqC;CACnE,MAAM,OAAO,aAAa,IAAI,IAAI;CAClC,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, ProjectType, ScaffoldContext } from \"../core/types.js\";\n\nfunction typePackages(type: ProjectType): PackageGroups {\n const dependencies = [\"@taserjs/router\", \"dotenv\"];\n const devDependencies = [\n \"@taserjs/router-cli\",\n \"npm-run-all2\",\n \"tsdown\",\n \"tsx\",\n \"typescript@^5.9.3\",\n \"@types/node\",\n ];\n const scripts: Record<string, string> = {};\n\n switch (type) {\n case \"express\":\n dependencies.push(\"@taserjs/adapter-express\", \"express\");\n devDependencies.push(\"@types/express\");\n break;\n case \"fastify\":\n dependencies.push(\"@taserjs/adapter-fastify\", \"fastify\");\n break;\n case \"hono\":\n dependencies.push(\"@hono/node-server\", \"hono\");\n break;\n case \"bun\":\n // Bun has native TypeScript and runtime execution\n devDependencies.push(\"@types/bun\");\n scripts[\"dev:server\"] = \"bun --watch src/index.ts\";\n scripts.start = \"bun src/index.ts\";\n scripts.serve = \"bun dist/index.mjs\";\n break;\n case \"deno\":\n scripts[\"dev:server\"] = \"deno run --watch --allow-net --allow-env --allow-read src/index.ts\";\n scripts.start = \"deno run --allow-net --allow-env --allow-read src/index.ts\";\n scripts.serve = \"deno run --allow-net --allow-env --allow-read dist/index.mjs\";\n break;\n case \"aws-lambda\":\n dependencies.push(\"hono\");\n devDependencies.push(\"@types/aws-lambda\");\n break;\n case \"cloudflare-workers\": {\n // Cloudflare workers uses wrangler\n const cfDevDeps = devDependencies.filter((d) => d !== \"tsx\");\n cfDevDeps.push(\"wrangler\", \"@cloudflare/workers-types\");\n devDependencies.length = 0;\n devDependencies.push(...cfDevDeps);\n scripts[\"dev:server\"] = \"wrangler dev\";\n scripts.deploy = \"wrangler deploy\";\n break;\n }\n case \"netlify\":\n dependencies.push(\"hono\", \"@netlify/functions\");\n break;\n case \"vercel\":\n dependencies.push(\"hono\");\n devDependencies.push(\"@vercel/node\");\n break;\n case \"azure-functions\":\n dependencies.push(\"hono\", \"@azure/functions\", \"@marplex/hono-azurefunc-adapter\");\n break;\n case \"google-cloud-run\":\n case \"node\":\n default:\n dependencies.push(\"@hono/node-server\");\n break;\n }\n\n return { dependencies, devDependencies, scripts };\n}\n\nexport function resolvePackages(ctx: ScaffoldContext): PackageGroups {\n const base = typePackages(ctx.type);\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\nexport function getPackageGroups(\n type: ProjectType,\n): Omit<PackageGroups, \"scripts\"> & { scripts?: Record<string, string> } {\n const groups = typePackages(type);\n return groups;\n}\n"],"mappings":";;AAGA,SAAS,aAAa,MAAkC;CACtD,MAAM,eAAe,CAAC,mBAAmB,QAAQ;CACjD,MAAM,kBAAkB;EACtB;EACA;EACA;EACA;EACA;EACA;CACF;CACA,MAAM,UAAkC,CAAC;CAEzC,QAAQ,MAAR;EACE,KAAK;GACH,aAAa,KAAK,4BAA4B,SAAS;GACvD,gBAAgB,KAAK,gBAAgB;GACrC;EACF,KAAK;GACH,aAAa,KAAK,4BAA4B,SAAS;GACvD;EACF,KAAK;GACH,aAAa,KAAK,qBAAqB,MAAM;GAC7C;EACF,KAAK;GAEH,gBAAgB,KAAK,YAAY;GACjC,QAAQ,gBAAgB;GACxB,QAAQ,QAAQ;GAChB,QAAQ,QAAQ;GAChB;EACF,KAAK;GACH,QAAQ,gBAAgB;GACxB,QAAQ,QAAQ;GAChB,QAAQ,QAAQ;GAChB;EACF,KAAK;GACH,aAAa,KAAK,MAAM;GACxB,gBAAgB,KAAK,mBAAmB;GACxC;EACF,KAAK,sBAAsB;GAEzB,MAAM,YAAY,gBAAgB,QAAQ,MAAM,MAAM,KAAK;GAC3D,UAAU,KAAK,YAAY,2BAA2B;GACtD,gBAAgB,SAAS;GACzB,gBAAgB,KAAK,GAAG,SAAS;GACjC,QAAQ,gBAAgB;GACxB,QAAQ,SAAS;GACjB;EACF;EACA,KAAK;GACH,aAAa,KAAK,QAAQ,oBAAoB;GAC9C;EACF,KAAK;GACH,aAAa,KAAK,MAAM;GACxB,gBAAgB,KAAK,cAAc;GACnC;EACF,KAAK;GACH,aAAa,KAAK,QAAQ,oBAAoB,iCAAiC;GAC/E;EAGF,SACE,aAAa,KAAK,mBAAmB;CAEzC;CAEA,OAAO;EAAE;EAAc;EAAiB;CAAQ;AAClD;AAEA,SAAgB,gBAAgB,KAAqC;CACnE,MAAM,OAAO,aAAa,IAAI,IAAI;CAClC,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"}
|
|
@@ -69,33 +69,13 @@ async function scaffoldProject(options) {
|
|
|
69
69
|
await (0, node_fs_promises.copyFile)(node_path.default.join(root, ".env.example"), node_path.default.join(root, ".env"));
|
|
70
70
|
} catch {}
|
|
71
71
|
await require_project_config.writeProjectConfig(root, ctx);
|
|
72
|
-
if (options.skipInstall) return
|
|
73
|
-
projectName: ctx.projectName,
|
|
74
|
-
targetDir: root,
|
|
75
|
-
type: ctx.type,
|
|
76
|
-
...ctx.db ? {
|
|
77
|
-
db: ctx.db,
|
|
78
|
-
driver: ctx.driver
|
|
79
|
-
} : {},
|
|
80
|
-
...ctx.logger ? { logger: ctx.logger } : {},
|
|
81
|
-
...ctx.validator ? { validator: ctx.validator } : {}
|
|
82
|
-
};
|
|
72
|
+
if (options.skipInstall) return ctx;
|
|
83
73
|
const agent = options.agent ?? require_package_manager.resolveUserAgent();
|
|
84
74
|
await require_package_manager.installPackages(agent, root, {
|
|
85
75
|
dependencies: packages.dependencies,
|
|
86
76
|
devDependencies: packages.devDependencies
|
|
87
77
|
});
|
|
88
|
-
return
|
|
89
|
-
projectName: ctx.projectName,
|
|
90
|
-
targetDir: root,
|
|
91
|
-
type: ctx.type,
|
|
92
|
-
...ctx.db ? {
|
|
93
|
-
db: ctx.db,
|
|
94
|
-
driver: ctx.driver
|
|
95
|
-
} : {},
|
|
96
|
-
...ctx.logger ? { logger: ctx.logger } : {},
|
|
97
|
-
...ctx.validator ? { validator: ctx.validator } : {}
|
|
98
|
-
};
|
|
78
|
+
return ctx;
|
|
99
79
|
}
|
|
100
80
|
//#endregion
|
|
101
81
|
exports.scaffoldProject = scaffoldProject;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold-engine.cjs","names":[],"sources":["../../../src/core/scaffold-engine.ts"],"sourcesContent":["import { copyFile, 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 type: options.type,\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(\n path.join(root, \"package.json\"),\n packageJsonTemplate(options.projectName, packages.scripts),\n );\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.type));\n await write(path.join(root, \"src/index.ts\"), indexTemplate(options.type));\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 if (options.type === \"cloudflare-workers\") {\n await write(\n path.join(root, \"wrangler.jsonc\"),\n JSON.stringify(\n {\n $schema: \"node_modules/wrangler/config-schema.json\",\n name: options.projectName,\n main: \"src/index.ts\",\n compatibility_date: \"2024-11-01\",\n },\n null,\n 2,\n ) + \"\\n\",\n );\n }\n\n if (options.type === \"vercel\") {\n await write(\n path.join(root, \"vercel.json\"),\n JSON.stringify(\n {\n rewrites: [{ source: \"/(.*)\", destination: \"/src/index.ts\" }],\n },\n null,\n 2,\n ) + \"\\n\",\n );\n }\n\n if (options.type === \"azure-functions\") {\n await write(\n path.join(root, \"host.json\"),\n JSON.stringify(\n {\n version: \"2.0\",\n logging: {\n applicationInsights: {\n samplingSettings: {\n isEnabled: true,\n excludedTypes: \"Request\",\n },\n },\n },\n extensionBundle: {\n id: \"Microsoft.Azure.Functions.ExtensionBundle\",\n version: \"[4.*, 5.0.0)\",\n },\n extensions: {\n http: {\n routePrefix: \"\",\n },\n },\n },\n null,\n 2,\n ) + \"\\n\",\n );\n }\n\n await Promise.all(\n addons.map(async (addon) => {\n await addon.apply(ctx, (filePath, contents) => write(path.join(root, filePath), contents));\n }),\n );\n\n try {\n await copyFile(path.join(root, \".env.example\"), path.join(root, \".env\"));\n } catch {\n // .env.example was not created\n }\n\n await writeProjectConfig(root, ctx);\n\n if (options.skipInstall) {\n return
|
|
1
|
+
{"version":3,"file":"scaffold-engine.cjs","names":[],"sources":["../../../src/core/scaffold-engine.ts"],"sourcesContent":["import { copyFile, 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 type: options.type,\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(\n path.join(root, \"package.json\"),\n packageJsonTemplate(options.projectName, packages.scripts),\n );\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.type));\n await write(path.join(root, \"src/index.ts\"), indexTemplate(options.type));\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 if (options.type === \"cloudflare-workers\") {\n await write(\n path.join(root, \"wrangler.jsonc\"),\n JSON.stringify(\n {\n $schema: \"node_modules/wrangler/config-schema.json\",\n name: options.projectName,\n main: \"src/index.ts\",\n compatibility_date: \"2024-11-01\",\n },\n null,\n 2,\n ) + \"\\n\",\n );\n }\n\n if (options.type === \"vercel\") {\n await write(\n path.join(root, \"vercel.json\"),\n JSON.stringify(\n {\n rewrites: [{ source: \"/(.*)\", destination: \"/src/index.ts\" }],\n },\n null,\n 2,\n ) + \"\\n\",\n );\n }\n\n if (options.type === \"azure-functions\") {\n await write(\n path.join(root, \"host.json\"),\n JSON.stringify(\n {\n version: \"2.0\",\n logging: {\n applicationInsights: {\n samplingSettings: {\n isEnabled: true,\n excludedTypes: \"Request\",\n },\n },\n },\n extensionBundle: {\n id: \"Microsoft.Azure.Functions.ExtensionBundle\",\n version: \"[4.*, 5.0.0)\",\n },\n extensions: {\n http: {\n routePrefix: \"\",\n },\n },\n },\n null,\n 2,\n ) + \"\\n\",\n );\n }\n\n await Promise.all(\n addons.map(async (addon) => {\n await addon.apply(ctx, (filePath, contents) => write(path.join(root, filePath), contents));\n }),\n );\n\n try {\n await copyFile(path.join(root, \".env.example\"), path.join(root, \".env\"));\n } catch {\n // .env.example was not created\n }\n\n await writeProjectConfig(root, ctx);\n\n if (options.skipInstall) {\n return ctx as ScaffoldResult;\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 ctx as ScaffoldResult;\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,MAAM,QAAQ;EACd,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,MACJ,UAAA,QAAK,KAAK,MAAM,cAAc,GAC9B,aAAA,oBAAoB,QAAQ,aAAa,SAAS,OAAO,CAC3D;CACA,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,IAAI,CAAC;CAC1E,MAAM,MAAM,UAAA,QAAK,KAAK,MAAM,cAAc,GAAG,cAAA,cAAc,QAAQ,IAAI,CAAC;CACxE,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,IAAI,QAAQ,SAAS,sBACnB,MAAM,MACJ,UAAA,QAAK,KAAK,MAAM,gBAAgB,GAChC,KAAK,UACH;EACE,SAAS;EACT,MAAM,QAAQ;EACd,MAAM;EACN,oBAAoB;CACtB,GACA,MACA,CACF,IAAI,IACN;CAGF,IAAI,QAAQ,SAAS,UACnB,MAAM,MACJ,UAAA,QAAK,KAAK,MAAM,aAAa,GAC7B,KAAK,UACH,EACE,UAAU,CAAC;EAAE,QAAQ;EAAS,aAAa;CAAgB,CAAC,EAC9D,GACA,MACA,CACF,IAAI,IACN;CAGF,IAAI,QAAQ,SAAS,mBACnB,MAAM,MACJ,UAAA,QAAK,KAAK,MAAM,WAAW,GAC3B,KAAK,UACH;EACE,SAAS;EACT,SAAS,EACP,qBAAqB,EACnB,kBAAkB;GAChB,WAAW;GACX,eAAe;EACjB,EACF,EACF;EACA,iBAAiB;GACf,IAAI;GACJ,SAAS;EACX;EACA,YAAY,EACV,MAAM,EACJ,aAAa,GACf,EACF;CACF,GACA,MACA,CACF,IAAI,IACN;CAGF,MAAM,QAAQ,IACZ,OAAO,IAAI,OAAO,UAAU;EAC1B,MAAM,MAAM,MAAM,MAAM,UAAU,aAAa,MAAM,UAAA,QAAK,KAAK,MAAM,QAAQ,GAAG,QAAQ,CAAC;CAC3F,CAAC,CACH;CAEA,IAAI;EACF,OAAA,GAAM,iBAAA,SAAA,CAAS,UAAA,QAAK,KAAK,MAAM,cAAc,GAAG,UAAA,QAAK,KAAK,MAAM,MAAM,CAAC;CACzE,QAAQ,CAER;CAEA,MAAM,uBAAA,mBAAmB,MAAM,GAAG;CAElC,IAAI,QAAQ,aACV,OAAO;CAGT,MAAM,QAAQ,QAAQ,SAAS,wBAAA,iBAAiB;CAChD,MAAM,wBAAA,gBAAgB,OAAO,MAAM;EACjC,cAAc,SAAS;EACvB,iBAAiB,SAAS;CAC5B,CAAC;CAED,OAAO;AACT"}
|
|
@@ -31,7 +31,7 @@ import { t } from '#src/taser.js'
|
|
|
31
31
|
const router = t.create(routeManifest)
|
|
32
32
|
|
|
33
33
|
const app = new Hono()
|
|
34
|
-
app.all('/*', c => router.
|
|
34
|
+
app.all('/*', c => router.fetch(c.req.raw))
|
|
35
35
|
|
|
36
36
|
const port = Number(process.env.PORT ?? 3000)
|
|
37
37
|
serve({ fetch: app.fetch, port }, () => {
|
|
@@ -93,7 +93,7 @@ import { t } from '#src/taser.js'
|
|
|
93
93
|
const router = t.create(routeManifest)
|
|
94
94
|
|
|
95
95
|
const app = new Hono()
|
|
96
|
-
app.all('/*', c => router.
|
|
96
|
+
app.all('/*', c => router.fetch(c.req.raw))
|
|
97
97
|
|
|
98
98
|
export const handler = handle(app)
|
|
99
99
|
`;
|
|
@@ -121,7 +121,7 @@ import { t } from '#src/taser.js'
|
|
|
121
121
|
const router = t.create(routeManifest)
|
|
122
122
|
|
|
123
123
|
const app = new Hono()
|
|
124
|
-
app.all('/*', c => router.
|
|
124
|
+
app.all('/*', c => router.fetch(c.req.raw))
|
|
125
125
|
|
|
126
126
|
export default handle(app)
|
|
127
127
|
`;
|
|
@@ -136,7 +136,7 @@ import { t } from '#src/taser.js'
|
|
|
136
136
|
const router = t.create(routeManifest)
|
|
137
137
|
|
|
138
138
|
const app = new Hono()
|
|
139
|
-
app.all('/*', c => router.
|
|
139
|
+
app.all('/*', c => router.fetch(c.req.raw))
|
|
140
140
|
|
|
141
141
|
export default handle(app)
|
|
142
142
|
`;
|
|
@@ -152,7 +152,7 @@ import { t } from '#src/taser.js'
|
|
|
152
152
|
const router = t.create(routeManifest)
|
|
153
153
|
|
|
154
154
|
const honoApp = new Hono()
|
|
155
|
-
honoApp.all('/*', c => router.
|
|
155
|
+
honoApp.all('/*', c => router.fetch(c.req.raw))
|
|
156
156
|
|
|
157
157
|
app.http('httpTrigger', {
|
|
158
158
|
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'],
|
|
@@ -191,33 +191,14 @@ serve({ fetch: router.fetch, port }, () => {
|
|
|
191
191
|
`;
|
|
192
192
|
}
|
|
193
193
|
}
|
|
194
|
-
function taserTsTemplate(
|
|
195
|
-
|
|
196
|
-
import { createTaserApp, type InferAppContext } from '@taserjs/router'
|
|
194
|
+
function taserTsTemplate(_type = "node") {
|
|
195
|
+
return `import { createTaserApp } from '@taserjs/router'
|
|
197
196
|
|
|
198
197
|
import { context } from '#src/context.js'
|
|
199
198
|
|
|
200
|
-
declare module '@taserjs/router' {
|
|
201
|
-
interface RouterRegister {
|
|
202
|
-
NativeContext: Context
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
199
|
export const t = createTaserApp({
|
|
207
200
|
response: { validate: true },
|
|
208
201
|
}).context(context)
|
|
209
|
-
|
|
210
|
-
export type AppContext = InferAppContext<typeof context>
|
|
211
|
-
`;
|
|
212
|
-
return `import { createTaserApp, type InferAppContext } from '@taserjs/router'
|
|
213
|
-
|
|
214
|
-
import { context } from '#src/context.js'
|
|
215
|
-
|
|
216
|
-
export const t = createTaserApp({
|
|
217
|
-
response: { validate: true },
|
|
218
|
-
}).context(context)
|
|
219
|
-
|
|
220
|
-
export type AppContext = InferAppContext<typeof context>
|
|
221
202
|
`;
|
|
222
203
|
}
|
|
223
204
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../../../src/frameworks/index.ts"],"sourcesContent":["import type { ProjectType } from \"../core/types.js\";\n\nexport function indexTemplate(type: ProjectType): string {\n switch (type) {\n case \"express\":\n return `import 'dotenv/config'\n\nimport express from 'express'\nimport { createExpressHandler } from '@taserjs/adapter-express'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst taser = createExpressHandler(router)\nconst app = express()\ntaser.mount('/{*splat}', app)\n\nconst port = Number(process.env.PORT ?? 3000)\napp.listen(port, () => {\n console.log(\\`Express listening on http://localhost:\\${port}\\`)\n})\n`;\n case \"hono\":\n return `import 'dotenv/config'\n\nimport { serve } from '@hono/node-server'\nimport { Hono } from 'hono'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst app = new Hono()\napp.all('/*', c => router.
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../../../src/frameworks/index.ts"],"sourcesContent":["import type { ProjectType } from \"../core/types.js\";\n\nexport function indexTemplate(type: ProjectType): string {\n switch (type) {\n case \"express\":\n return `import 'dotenv/config'\n\nimport express from 'express'\nimport { createExpressHandler } from '@taserjs/adapter-express'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst taser = createExpressHandler(router)\nconst app = express()\ntaser.mount('/{*splat}', app)\n\nconst port = Number(process.env.PORT ?? 3000)\napp.listen(port, () => {\n console.log(\\`Express listening on http://localhost:\\${port}\\`)\n})\n`;\n case \"hono\":\n return `import 'dotenv/config'\n\nimport { serve } from '@hono/node-server'\nimport { Hono } from 'hono'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst app = new Hono()\napp.all('/*', c => router.fetch(c.req.raw))\n\nconst port = Number(process.env.PORT ?? 3000)\nserve({ fetch: app.fetch, port }, () => {\n console.log(\\`Hono listening on http://localhost:\\${port}\\`)\n})\n`;\n case \"fastify\":\n return `import 'dotenv/config'\n\nimport Fastify from 'fastify'\nimport { createFastifyHandler } from '@taserjs/adapter-fastify'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst taser = createFastifyHandler(router)\nconst app = Fastify()\ntaser.mount('/*', app)\n\nconst port = Number(process.env.PORT ?? 3000)\nawait app.listen({ port })\nconsole.log(\\`Fastify listening on http://localhost:\\${port}\\`)\n`;\n case \"bun\":\n return `import 'dotenv/config'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst port = Number(process.env.PORT ?? 3000)\n\nexport default {\n port,\n fetch(request: Request) {\n return router.fetch(request)\n },\n}\n`;\n case \"deno\":\n return `import 'dotenv/config'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst port = Number(process.env.PORT ?? 8000)\nDeno.serve({ port }, (request: Request) => router.fetch(request))\n`;\n case \"aws-lambda\":\n return `import 'dotenv/config'\n\nimport { Hono } from 'hono'\nimport { handle } from 'hono/aws-lambda'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst app = new Hono()\napp.all('/*', c => router.fetch(c.req.raw))\n\nexport const handler = handle(app)\n`;\n case \"cloudflare-workers\":\n return `import 'dotenv/config'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nexport default {\n fetch(request: Request, env: unknown, ctx: unknown) {\n return router.fetch(request, env, ctx)\n },\n}\n`;\n case \"netlify\":\n return `import 'dotenv/config'\n\nimport { Hono } from 'hono'\nimport { handle } from 'hono/netlify'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst app = new Hono()\napp.all('/*', c => router.fetch(c.req.raw))\n\nexport default handle(app)\n`;\n case \"vercel\":\n return `import 'dotenv/config'\n\nimport { Hono } from 'hono'\nimport { handle } from 'hono/vercel'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst app = new Hono()\napp.all('/*', c => router.fetch(c.req.raw))\n\nexport default handle(app)\n`;\n case \"azure-functions\":\n return `import 'dotenv/config'\n\nimport { app } from '@azure/functions'\nimport { Hono } from 'hono'\nimport { azureHonoHandler } from '@marplex/hono-azurefunc-adapter'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst honoApp = new Hono()\nhonoApp.all('/*', c => router.fetch(c.req.raw))\n\napp.http('httpTrigger', {\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'],\n authLevel: 'anonymous',\n route: '{*proxy}',\n handler: azureHonoHandler(honoApp.fetch),\n})\n`;\n case \"google-cloud-run\":\n return `import 'dotenv/config'\n\nimport { serve } from '@hono/node-server'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst port = Number(process.env.PORT ?? 8080)\nserve({ fetch: router.fetch, port }, () => {\n console.log(\\`Cloud Run listening on http://localhost:\\${port}\\`)\n})\n`;\n case \"node\":\n default:\n return `import 'dotenv/config'\n\nimport { serve } from '@hono/node-server'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst port = Number(process.env.PORT ?? 3000)\nserve({ fetch: router.fetch, port }, () => {\n console.log(\\`Node listening on http://localhost:\\${port}\\`)\n})\n`;\n }\n}\n\nexport function taserTsTemplate(_type: ProjectType = \"node\"): string {\n return `import { createTaserApp } from '@taserjs/router'\n\nimport { context } from '#src/context.js'\n\nexport const t = createTaserApp({\n response: { validate: true },\n}).context(context)\n`;\n}\n"],"mappings":";AAEA,SAAgB,cAAc,MAA2B;CACvD,QAAQ,MAAR;EACE,KAAK,WACH,OAAO;;;;;;;;;;;;;;;;;;;EAmBT,KAAK,QACH,OAAO;;;;;;;;;;;;;;;;;;EAkBT,KAAK,WACH,OAAO;;;;;;;;;;;;;;;;;;EAkBT,KAAK,OACH,OAAO;;;;;;;;;;;;;;;;EAgBT,KAAK,QACH,OAAO;;;;;;;;;;EAUT,KAAK,cACH,OAAO;;;;;;;;;;;;;;;EAeT,KAAK,sBACH,OAAO;;;;;;;;;;;;;EAaT,KAAK,WACH,OAAO;;;;;;;;;;;;;;;EAeT,KAAK,UACH,OAAO;;;;;;;;;;;;;;;EAeT,KAAK,mBACH,OAAO;;;;;;;;;;;;;;;;;;;;;EAqBT,KAAK,oBACH,OAAO;;;;;;;;;;;;;;EAeT,SACE,OAAO;;;;;;;;;;;;;;CAcX;AACF;AAEA,SAAgB,gBAAgB,QAAqB,QAAgB;CACnE,OAAO;;;;;;;;AAQT"}
|
|
@@ -73,21 +73,22 @@ ${bootBlock}
|
|
|
73
73
|
`;
|
|
74
74
|
}
|
|
75
75
|
function rootLayoutTemplate() {
|
|
76
|
-
return `import {
|
|
77
|
-
import { secureHeaders } from '@taserjs/router/secure-headers'
|
|
76
|
+
return `import { cors } from '@taserjs/router/cors'
|
|
78
77
|
|
|
79
78
|
import { t } from '#src/taser.js'
|
|
80
79
|
|
|
81
80
|
export const Middleware = t.middleware('/$')
|
|
82
|
-
.use(
|
|
83
|
-
.use(bodyLimit({ maxSize: 1_000_000 }))
|
|
81
|
+
.use(cors())
|
|
84
82
|
`;
|
|
85
83
|
}
|
|
86
84
|
function indexRouteTemplate() {
|
|
87
85
|
return `import { reply } from '@taserjs/router'
|
|
88
86
|
import { t } from '#src/taser.js'
|
|
89
87
|
|
|
90
|
-
|
|
88
|
+
const GET = t.get('/')
|
|
89
|
+
|
|
90
|
+
export type RouteContext = typeof GET.$Infer.Context
|
|
91
|
+
export const Route = GET.handler((_ctx) => {
|
|
91
92
|
return reply.json({ message: 'Welcome to Taser' })
|
|
92
93
|
})
|
|
93
94
|
`;
|
|
@@ -100,7 +101,10 @@ function healthRouteTemplate(ctx) {
|
|
|
100
101
|
return `import { reply } from '@taserjs/router'
|
|
101
102
|
import { t } from '#src/taser.js'
|
|
102
103
|
|
|
103
|
-
|
|
104
|
+
const GET = t.get('/health')
|
|
105
|
+
|
|
106
|
+
export type RouteContext = typeof GET.$Infer.Context
|
|
107
|
+
export const Route = GET.handler(${lines.length > 0 ? "(ctx)" : "(_ctx)"} => {
|
|
104
108
|
${body} return reply.json({ ok: true })
|
|
105
109
|
})
|
|
106
110
|
`;
|
|
@@ -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(\n projectName: string,\n scripts: Record<string, string> = {},\n): 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 {\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 },\n null,\n 2,\n )}\\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 =\n bindings.length > 0\n ? bindings.map((binding) => ` ${binding.key}: ${binding.factoryName}(),`).join(\"\\n\")\n : \"\";\n\n const bootBlock = bindings.length > 0 ? ` boot: () => ({\\n${bootBody}\\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 {
|
|
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(\n projectName: string,\n scripts: Record<string, string> = {},\n): 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 {\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 },\n null,\n 2,\n )}\\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 =\n bindings.length > 0\n ? bindings.map((binding) => ` ${binding.key}: ${binding.factoryName}(),`).join(\"\\n\")\n : \"\";\n\n const bootBlock = bindings.length > 0 ? ` boot: () => ({\\n${bootBody}\\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 { cors } from '@taserjs/router/cors'\n\nimport { t } from '#src/taser.js'\n\nexport const Middleware = t.middleware('/$')\n .use(cors())\n`;\n}\n\nexport function indexRouteTemplate(): string {\n return `import { reply } from '@taserjs/router'\nimport { t } from '#src/taser.js'\n\nconst GET = t.get('/')\n\nexport type RouteContext = typeof GET.$Infer.Context\nexport const Route = GET.handler((_ctx) => {\n return 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 const ctxArg = lines.length > 0 ? \"(ctx)\" : \"(_ctx)\";\n\n return `import { reply } from '@taserjs/router'\nimport { t } from '#src/taser.js'\n\nconst GET = t.get('/health')\n\nexport type RouteContext = typeof GET.$Infer.Context\nexport const Route = GET.handler(${ctxArg} => {\n${body} return 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,oBACd,aACA,UAAkC,CAAC,GAC3B;CACR,MAAM,MAAM;EACV,MAAM;EACN,SAAS;EACT,SAAS;EACT,MAAM;EACN,SAAS,EACP,UAAU,UACZ;EACA,SAAS;GACP,KAAK;GACL,cAAc;GACd,aAAa;GACb,OAAO;GACP,UAAU;GACV,OAAO;GACP,OAAO;GACP,WAAW;GACX,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,UACb;EACE,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,GACA,MACA,CACF,EAAE;AACJ;AAEA,SAAgB,oBAA4B;CAC1C,OAAO;;;;;;;;AAQT;AAEA,SAAgB,gBAAgB,UAAiC;CAC/D,MAAM,UAAU,SAAS,KACtB,YAAY,YAAY,QAAQ,YAAY,WAAW,QAAQ,WAAW,EAC7E;CAEA,MAAM,WACJ,SAAS,SAAS,IACd,SAAS,KAAK,YAAY,OAAO,QAAQ,IAAI,IAAI,QAAQ,YAAY,IAAI,CAAC,CAAC,KAAK,IAAI,IACpF;CAEN,MAAM,YAAY,SAAS,SAAS,IAAI,qBAAqB,SAAS,WAAW;CAIjF,OAAO,GAFa,QAAQ,SAAS,IAAI,GAAG,QAAQ,KAAK,IAAI,EAAE,QAAQ,GAEjD;;;EAGtB,UAAU;;;;;;AAMZ;AAEA,SAAgB,qBAA6B;CAC3C,OAAO;;;;;;;AAOT;AAEA,SAAgB,qBAA6B;CAC3C,OAAO;;;;;;;;;;AAUT;AAEA,SAAgB,oBAAoB,KAA8B;CAChE,MAAM,QAAkB,CAAC;CAEzB,IAAI,IAAI,QACN,MAAM,KAAK,mCAAmC;CAGhD,IAAI,IAAI,IACN,MAAM,KAAK,4CAA4C;CAGzD,MAAM,OAAO,MAAM,SAAS,IAAI,GAAG,MAAM,KAAK,IAAI,EAAE,MAAM;CAG1D,OAAO;;;;;;mCAFQ,MAAM,SAAS,IAAI,UAAU,SAQJ;EACxC,KAAK;;;AAGP;;AAGA,SAAgB,0BAAkC;CAChD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DT"}
|
|
@@ -45,14 +45,11 @@ function resolveAddons(ctx) {
|
|
|
45
45
|
if (!loggerAddon) throw new Error(`Unknown logger addon "${ctx.logger}"`);
|
|
46
46
|
selected.push(loggerAddon);
|
|
47
47
|
}
|
|
48
|
-
if (selected.filter((addon) => addon.category === "database").length > 1) throw new Error("Only one database addon can be selected");
|
|
49
|
-
if (selected.filter((addon) => addon.category === "logger").length > 1) throw new Error("Only one logger addon can be selected");
|
|
50
48
|
if (ctx.validator) {
|
|
51
49
|
const validatorAddon = VALIDATOR_ADDONS.find((addon) => addon.id === ctx.validator);
|
|
52
50
|
if (!validatorAddon) throw new Error(`Unknown validator addon "${ctx.validator}"`);
|
|
53
51
|
selected.push(validatorAddon);
|
|
54
52
|
}
|
|
55
|
-
if (selected.filter((addon) => addon.category === "validator").length > 1) throw new Error("Only one validator addon can be selected");
|
|
56
53
|
return selected;
|
|
57
54
|
}
|
|
58
55
|
function collectBootBindings(ctx) {
|
|
@@ -1 +1 @@
|
|
|
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
|
|
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 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 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;CAEA,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;CAEA,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"}
|
|
@@ -6,20 +6,23 @@ var IMPORT_LINES = {
|
|
|
6
6
|
};
|
|
7
7
|
var VALIDATION_BLOCK_TEMPLATE = {
|
|
8
8
|
zod: `, {
|
|
9
|
-
query: z.object({ name: z.string() }),
|
|
9
|
+
query: z.object({ name: z.string().default('Taser') }),
|
|
10
10
|
}`,
|
|
11
11
|
arktype: `, {
|
|
12
|
-
query: type({ name: 'string' }),
|
|
12
|
+
query: type({ 'name?': 'string = "Taser"' }),
|
|
13
13
|
}`,
|
|
14
14
|
valibot: `, {
|
|
15
|
-
query: v.object({ name: v.string() }),
|
|
15
|
+
query: v.object({ name: v.optional(v.string(), 'Taser') }),
|
|
16
16
|
}`
|
|
17
17
|
};
|
|
18
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
|
+
const GET = t.get('/'${VALIDATION_BLOCK_TEMPLATE[validator]})
|
|
23
|
+
|
|
24
|
+
export type RouteContext = typeof GET.$Infer.Context
|
|
25
|
+
export const Route = GET.handler((ctx) => {
|
|
23
26
|
return reply.json({ message: \`Hello, \${ctx.query.name}!\` })
|
|
24
27
|
})
|
|
25
28
|
`;
|
|
@@ -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) => `import { reply } from '@taserjs/router'\nimport { t } from '#src/taser.js'\n${IMPORT_LINES[validator]}\n\
|
|
1
|
+
{"version":3,"file":"validators.js","names":[],"sources":["../../../src/addons/validators.ts"],"sourcesContent":["import type { ValidatorId } from \"../core/types\";\nimport type { AddonDefinition } from \"./types\";\n\nexport const IMPORT_LINES: Record<ValidatorId, string> = {\n zod: `import { z } from 'zod'`,\n arktype: `import { type } from 'arktype'`,\n valibot: `import * as v from 'valibot'`,\n};\n\nexport const VALIDATION_BLOCK_TEMPLATE: Record<ValidatorId, string> = {\n zod: `, {\n query: z.object({ name: z.string().default('Taser') }),\n}`,\n arktype: `, {\n query: type({ 'name?': 'string = \"Taser\"' }),\n}`,\n valibot: `, {\n query: v.object({ name: v.optional(v.string(), 'Taser') }),\n}`,\n};\n\nconst ROUTE_TEMPLATE = (validator: ValidatorId) => `import { reply } from '@taserjs/router'\nimport { t } from '#src/taser.js'\n${IMPORT_LINES[validator]}\n\nconst GET = t.get('/'${VALIDATION_BLOCK_TEMPLATE[validator]})\n\nexport type RouteContext = typeof GET.$Infer.Context\nexport const Route = GET.handler((ctx) => {\n return 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;;uBAEH,0BAA0B,WAAW;;;;;;;AAQ5D,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":"resolve-packages.js","names":[],"sources":["../../../src/core/resolve-packages.ts"],"sourcesContent":["import { resolveAddons } from \"../addons/registry.js\";\nimport type { PackageGroups, ProjectType, ScaffoldContext } from \"../core/types.js\";\n\nfunction typePackages(type: ProjectType): PackageGroups {\n const dependencies = [\"@taserjs/router\", \"dotenv\"];\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 (type) {\n case \"express\":\n dependencies.push(\"@taserjs/adapter-express\", \"express\");\n devDependencies.push(\"@types/express\");\n break;\n case \"fastify\":\n dependencies.push(\"@taserjs/adapter-fastify\", \"fastify\");\n break;\n case \"hono\":\n dependencies.push(\"@hono/node-server\", \"hono\");\n break;\n case \"bun\":\n // Bun has native TypeScript and runtime execution\n devDependencies.push(\"@types/bun\");\n scripts[\"dev:server\"] = \"bun --watch src/index.ts\";\n scripts.start = \"bun src/index.ts\";\n scripts.serve = \"bun dist/index.mjs\";\n break;\n case \"deno\":\n scripts[\"dev:server\"] = \"deno run --watch --allow-net --allow-env --allow-read src/index.ts\";\n scripts.start = \"deno run --allow-net --allow-env --allow-read src/index.ts\";\n scripts.serve = \"deno run --allow-net --allow-env --allow-read dist/index.mjs\";\n break;\n case \"aws-lambda\":\n dependencies.push(\"hono\");\n devDependencies.push(\"@types/aws-lambda\");\n break;\n case \"cloudflare-workers\": {\n // Cloudflare workers uses wrangler\n const cfDevDeps = devDependencies.filter((d) => d !== \"tsx\");\n cfDevDeps.push(\"wrangler\", \"@cloudflare/workers-types\");\n devDependencies.length = 0;\n devDependencies.push(...cfDevDeps);\n scripts[\"dev:server\"] = \"wrangler dev\";\n scripts.deploy = \"wrangler deploy\";\n break;\n }\n case \"netlify\":\n dependencies.push(\"hono\", \"@netlify/functions\");\n break;\n case \"vercel\":\n dependencies.push(\"hono\");\n devDependencies.push(\"@vercel/node\");\n break;\n case \"azure-functions\":\n dependencies.push(\"hono\", \"@azure/functions\", \"@marplex/hono-azurefunc-adapter\");\n break;\n case \"google-cloud-run\":\n case \"node\":\n default:\n dependencies.push(\"@hono/node-server\");\n break;\n }\n\n return { dependencies, devDependencies, scripts };\n}\n\nexport function resolvePackages(ctx: ScaffoldContext): PackageGroups {\n const base = typePackages(ctx.type);\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\nexport function getPackageGroups(\n type: ProjectType,\n): Omit<PackageGroups, \"scripts\"> & { scripts?: Record<string, string> } {\n const groups = typePackages(type);\n return groups;\n}\n"],"mappings":";;AAGA,SAAS,aAAa,MAAkC;CACtD,MAAM,eAAe,CAAC,mBAAmB,QAAQ;CACjD,MAAM,kBAAkB;EACtB;EACA;EACA;EACA;EACA;EACA;CACF;CACA,MAAM,UAAkC,CAAC;CAEzC,QAAQ,MAAR;EACE,KAAK;GACH,aAAa,KAAK,4BAA4B,SAAS;GACvD,gBAAgB,KAAK,gBAAgB;GACrC;EACF,KAAK;GACH,aAAa,KAAK,4BAA4B,SAAS;GACvD;EACF,KAAK;GACH,aAAa,KAAK,qBAAqB,MAAM;GAC7C;EACF,KAAK;GAEH,gBAAgB,KAAK,YAAY;GACjC,QAAQ,gBAAgB;GACxB,QAAQ,QAAQ;GAChB,QAAQ,QAAQ;GAChB;EACF,KAAK;GACH,QAAQ,gBAAgB;GACxB,QAAQ,QAAQ;GAChB,QAAQ,QAAQ;GAChB;EACF,KAAK;GACH,aAAa,KAAK,MAAM;GACxB,gBAAgB,KAAK,mBAAmB;GACxC;EACF,KAAK,sBAAsB;GAEzB,MAAM,YAAY,gBAAgB,QAAQ,MAAM,MAAM,KAAK;GAC3D,UAAU,KAAK,YAAY,2BAA2B;GACtD,gBAAgB,SAAS;GACzB,gBAAgB,KAAK,GAAG,SAAS;GACjC,QAAQ,gBAAgB;GACxB,QAAQ,SAAS;GACjB;EACF;EACA,KAAK;GACH,aAAa,KAAK,QAAQ,oBAAoB;GAC9C;EACF,KAAK;GACH,aAAa,KAAK,MAAM;GACxB,gBAAgB,KAAK,cAAc;GACnC;EACF,KAAK;GACH,aAAa,KAAK,QAAQ,oBAAoB,iCAAiC;GAC/E;EAGF,SACE,aAAa,KAAK,mBAAmB;CAEzC;CAEA,OAAO;EAAE;EAAc;EAAiB;CAAQ;AAClD;AAEA,SAAgB,gBAAgB,KAAqC;CACnE,MAAM,OAAO,aAAa,IAAI,IAAI;CAClC,MAAM,SAAS,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.js","names":[],"sources":["../../../src/core/resolve-packages.ts"],"sourcesContent":["import { resolveAddons } from \"../addons/registry.js\";\nimport type { PackageGroups, ProjectType, ScaffoldContext } from \"../core/types.js\";\n\nfunction typePackages(type: ProjectType): PackageGroups {\n const dependencies = [\"@taserjs/router\", \"dotenv\"];\n const devDependencies = [\n \"@taserjs/router-cli\",\n \"npm-run-all2\",\n \"tsdown\",\n \"tsx\",\n \"typescript@^5.9.3\",\n \"@types/node\",\n ];\n const scripts: Record<string, string> = {};\n\n switch (type) {\n case \"express\":\n dependencies.push(\"@taserjs/adapter-express\", \"express\");\n devDependencies.push(\"@types/express\");\n break;\n case \"fastify\":\n dependencies.push(\"@taserjs/adapter-fastify\", \"fastify\");\n break;\n case \"hono\":\n dependencies.push(\"@hono/node-server\", \"hono\");\n break;\n case \"bun\":\n // Bun has native TypeScript and runtime execution\n devDependencies.push(\"@types/bun\");\n scripts[\"dev:server\"] = \"bun --watch src/index.ts\";\n scripts.start = \"bun src/index.ts\";\n scripts.serve = \"bun dist/index.mjs\";\n break;\n case \"deno\":\n scripts[\"dev:server\"] = \"deno run --watch --allow-net --allow-env --allow-read src/index.ts\";\n scripts.start = \"deno run --allow-net --allow-env --allow-read src/index.ts\";\n scripts.serve = \"deno run --allow-net --allow-env --allow-read dist/index.mjs\";\n break;\n case \"aws-lambda\":\n dependencies.push(\"hono\");\n devDependencies.push(\"@types/aws-lambda\");\n break;\n case \"cloudflare-workers\": {\n // Cloudflare workers uses wrangler\n const cfDevDeps = devDependencies.filter((d) => d !== \"tsx\");\n cfDevDeps.push(\"wrangler\", \"@cloudflare/workers-types\");\n devDependencies.length = 0;\n devDependencies.push(...cfDevDeps);\n scripts[\"dev:server\"] = \"wrangler dev\";\n scripts.deploy = \"wrangler deploy\";\n break;\n }\n case \"netlify\":\n dependencies.push(\"hono\", \"@netlify/functions\");\n break;\n case \"vercel\":\n dependencies.push(\"hono\");\n devDependencies.push(\"@vercel/node\");\n break;\n case \"azure-functions\":\n dependencies.push(\"hono\", \"@azure/functions\", \"@marplex/hono-azurefunc-adapter\");\n break;\n case \"google-cloud-run\":\n case \"node\":\n default:\n dependencies.push(\"@hono/node-server\");\n break;\n }\n\n return { dependencies, devDependencies, scripts };\n}\n\nexport function resolvePackages(ctx: ScaffoldContext): PackageGroups {\n const base = typePackages(ctx.type);\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\nexport function getPackageGroups(\n type: ProjectType,\n): Omit<PackageGroups, \"scripts\"> & { scripts?: Record<string, string> } {\n const groups = typePackages(type);\n return groups;\n}\n"],"mappings":";;AAGA,SAAS,aAAa,MAAkC;CACtD,MAAM,eAAe,CAAC,mBAAmB,QAAQ;CACjD,MAAM,kBAAkB;EACtB;EACA;EACA;EACA;EACA;EACA;CACF;CACA,MAAM,UAAkC,CAAC;CAEzC,QAAQ,MAAR;EACE,KAAK;GACH,aAAa,KAAK,4BAA4B,SAAS;GACvD,gBAAgB,KAAK,gBAAgB;GACrC;EACF,KAAK;GACH,aAAa,KAAK,4BAA4B,SAAS;GACvD;EACF,KAAK;GACH,aAAa,KAAK,qBAAqB,MAAM;GAC7C;EACF,KAAK;GAEH,gBAAgB,KAAK,YAAY;GACjC,QAAQ,gBAAgB;GACxB,QAAQ,QAAQ;GAChB,QAAQ,QAAQ;GAChB;EACF,KAAK;GACH,QAAQ,gBAAgB;GACxB,QAAQ,QAAQ;GAChB,QAAQ,QAAQ;GAChB;EACF,KAAK;GACH,aAAa,KAAK,MAAM;GACxB,gBAAgB,KAAK,mBAAmB;GACxC;EACF,KAAK,sBAAsB;GAEzB,MAAM,YAAY,gBAAgB,QAAQ,MAAM,MAAM,KAAK;GAC3D,UAAU,KAAK,YAAY,2BAA2B;GACtD,gBAAgB,SAAS;GACzB,gBAAgB,KAAK,GAAG,SAAS;GACjC,QAAQ,gBAAgB;GACxB,QAAQ,SAAS;GACjB;EACF;EACA,KAAK;GACH,aAAa,KAAK,QAAQ,oBAAoB;GAC9C;EACF,KAAK;GACH,aAAa,KAAK,MAAM;GACxB,gBAAgB,KAAK,cAAc;GACnC;EACF,KAAK;GACH,aAAa,KAAK,QAAQ,oBAAoB,iCAAiC;GAC/E;EAGF,SACE,aAAa,KAAK,mBAAmB;CAEzC;CAEA,OAAO;EAAE;EAAc;EAAiB;CAAQ;AAClD;AAEA,SAAgB,gBAAgB,KAAqC;CACnE,MAAM,OAAO,aAAa,IAAI,IAAI;CAClC,MAAM,SAAS,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"}
|
|
@@ -67,33 +67,13 @@ async function scaffoldProject(options) {
|
|
|
67
67
|
await copyFile(path.join(root, ".env.example"), path.join(root, ".env"));
|
|
68
68
|
} catch {}
|
|
69
69
|
await writeProjectConfig(root, ctx);
|
|
70
|
-
if (options.skipInstall) return
|
|
71
|
-
projectName: ctx.projectName,
|
|
72
|
-
targetDir: root,
|
|
73
|
-
type: ctx.type,
|
|
74
|
-
...ctx.db ? {
|
|
75
|
-
db: ctx.db,
|
|
76
|
-
driver: ctx.driver
|
|
77
|
-
} : {},
|
|
78
|
-
...ctx.logger ? { logger: ctx.logger } : {},
|
|
79
|
-
...ctx.validator ? { validator: ctx.validator } : {}
|
|
80
|
-
};
|
|
70
|
+
if (options.skipInstall) return ctx;
|
|
81
71
|
const agent = options.agent ?? resolveUserAgent();
|
|
82
72
|
await installPackages(agent, root, {
|
|
83
73
|
dependencies: packages.dependencies,
|
|
84
74
|
devDependencies: packages.devDependencies
|
|
85
75
|
});
|
|
86
|
-
return
|
|
87
|
-
projectName: ctx.projectName,
|
|
88
|
-
targetDir: root,
|
|
89
|
-
type: ctx.type,
|
|
90
|
-
...ctx.db ? {
|
|
91
|
-
db: ctx.db,
|
|
92
|
-
driver: ctx.driver
|
|
93
|
-
} : {},
|
|
94
|
-
...ctx.logger ? { logger: ctx.logger } : {},
|
|
95
|
-
...ctx.validator ? { validator: ctx.validator } : {}
|
|
96
|
-
};
|
|
76
|
+
return ctx;
|
|
97
77
|
}
|
|
98
78
|
//#endregion
|
|
99
79
|
export { scaffoldProject };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold-engine.js","names":[],"sources":["../../../src/core/scaffold-engine.ts"],"sourcesContent":["import { copyFile, 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 type: options.type,\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(\n path.join(root, \"package.json\"),\n packageJsonTemplate(options.projectName, packages.scripts),\n );\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.type));\n await write(path.join(root, \"src/index.ts\"), indexTemplate(options.type));\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 if (options.type === \"cloudflare-workers\") {\n await write(\n path.join(root, \"wrangler.jsonc\"),\n JSON.stringify(\n {\n $schema: \"node_modules/wrangler/config-schema.json\",\n name: options.projectName,\n main: \"src/index.ts\",\n compatibility_date: \"2024-11-01\",\n },\n null,\n 2,\n ) + \"\\n\",\n );\n }\n\n if (options.type === \"vercel\") {\n await write(\n path.join(root, \"vercel.json\"),\n JSON.stringify(\n {\n rewrites: [{ source: \"/(.*)\", destination: \"/src/index.ts\" }],\n },\n null,\n 2,\n ) + \"\\n\",\n );\n }\n\n if (options.type === \"azure-functions\") {\n await write(\n path.join(root, \"host.json\"),\n JSON.stringify(\n {\n version: \"2.0\",\n logging: {\n applicationInsights: {\n samplingSettings: {\n isEnabled: true,\n excludedTypes: \"Request\",\n },\n },\n },\n extensionBundle: {\n id: \"Microsoft.Azure.Functions.ExtensionBundle\",\n version: \"[4.*, 5.0.0)\",\n },\n extensions: {\n http: {\n routePrefix: \"\",\n },\n },\n },\n null,\n 2,\n ) + \"\\n\",\n );\n }\n\n await Promise.all(\n addons.map(async (addon) => {\n await addon.apply(ctx, (filePath, contents) => write(path.join(root, filePath), contents));\n }),\n );\n\n try {\n await copyFile(path.join(root, \".env.example\"), path.join(root, \".env\"));\n } catch {\n // .env.example was not created\n }\n\n await writeProjectConfig(root, ctx);\n\n if (options.skipInstall) {\n return
|
|
1
|
+
{"version":3,"file":"scaffold-engine.js","names":[],"sources":["../../../src/core/scaffold-engine.ts"],"sourcesContent":["import { copyFile, 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 type: options.type,\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(\n path.join(root, \"package.json\"),\n packageJsonTemplate(options.projectName, packages.scripts),\n );\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.type));\n await write(path.join(root, \"src/index.ts\"), indexTemplate(options.type));\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 if (options.type === \"cloudflare-workers\") {\n await write(\n path.join(root, \"wrangler.jsonc\"),\n JSON.stringify(\n {\n $schema: \"node_modules/wrangler/config-schema.json\",\n name: options.projectName,\n main: \"src/index.ts\",\n compatibility_date: \"2024-11-01\",\n },\n null,\n 2,\n ) + \"\\n\",\n );\n }\n\n if (options.type === \"vercel\") {\n await write(\n path.join(root, \"vercel.json\"),\n JSON.stringify(\n {\n rewrites: [{ source: \"/(.*)\", destination: \"/src/index.ts\" }],\n },\n null,\n 2,\n ) + \"\\n\",\n );\n }\n\n if (options.type === \"azure-functions\") {\n await write(\n path.join(root, \"host.json\"),\n JSON.stringify(\n {\n version: \"2.0\",\n logging: {\n applicationInsights: {\n samplingSettings: {\n isEnabled: true,\n excludedTypes: \"Request\",\n },\n },\n },\n extensionBundle: {\n id: \"Microsoft.Azure.Functions.ExtensionBundle\",\n version: \"[4.*, 5.0.0)\",\n },\n extensions: {\n http: {\n routePrefix: \"\",\n },\n },\n },\n null,\n 2,\n ) + \"\\n\",\n );\n }\n\n await Promise.all(\n addons.map(async (addon) => {\n await addon.apply(ctx, (filePath, contents) => write(path.join(root, filePath), contents));\n }),\n );\n\n try {\n await copyFile(path.join(root, \".env.example\"), path.join(root, \".env\"));\n } catch {\n // .env.example was not created\n }\n\n await writeProjectConfig(root, ctx);\n\n if (options.skipInstall) {\n return ctx as ScaffoldResult;\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 ctx as ScaffoldResult;\n}\n"],"mappings":";;;;;;;;;AAqBA,eAAe,MAAM,UAAkB,UAAiC;CACtE,MAAM,MAAM,KAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;CACvD,MAAM,UAAU,UAAU,UAAU,MAAM;AAC5C;AAEA,eAAsB,gBAAgB,SAAmD;CACvF,MAAM,OAAO,QAAQ;CACrB,MAAM,MAAM;EACV,aAAa,QAAQ;EACrB,WAAW;EACX,MAAM,QAAQ;EACd,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,cAAc,GAAG;CAChC,MAAM,WAAW,gBAAgB,GAAG;CACpC,MAAM,eAAe,oBAAoB,GAAG;CAE5C,MAAM,MACJ,KAAK,KAAK,MAAM,cAAc,GAC9B,oBAAoB,QAAQ,aAAa,SAAS,OAAO,CAC3D;CACA,MAAM,MAAM,KAAK,KAAK,MAAM,eAAe,GAAG,iBAAiB,CAAC;CAChE,MAAM,MAAM,KAAK,KAAK,MAAM,kBAAkB,GAAG,qBAAqB,CAAC;CACvE,MAAM,MAAM,KAAK,KAAK,MAAM,YAAY,GAAG,kBAAkB,CAAC;CAC9D,MAAM,MAAM,KAAK,KAAK,MAAM,gBAAgB,GAAG,gBAAgB,YAAY,CAAC;CAC5E,MAAM,MAAM,KAAK,KAAK,MAAM,cAAc,GAAG,gBAAgB,QAAQ,IAAI,CAAC;CAC1E,MAAM,MAAM,KAAK,KAAK,MAAM,cAAc,GAAG,cAAc,QAAQ,IAAI,CAAC;CACxE,MAAM,MAAM,KAAK,KAAK,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;CACpE,MAAM,MAAM,KAAK,KAAK,MAAM,yBAAyB,GAAG,mBAAmB,CAAC;CAC5E,MAAM,MAAM,KAAK,KAAK,MAAM,0BAA0B,GAAG,oBAAoB,GAAG,CAAC;CACjF,MAAM,MAAM,KAAK,KAAK,MAAM,0BAA0B,GAAG,wBAAwB,CAAC;CAElF,IAAI,QAAQ,SAAS,sBACnB,MAAM,MACJ,KAAK,KAAK,MAAM,gBAAgB,GAChC,KAAK,UACH;EACE,SAAS;EACT,MAAM,QAAQ;EACd,MAAM;EACN,oBAAoB;CACtB,GACA,MACA,CACF,IAAI,IACN;CAGF,IAAI,QAAQ,SAAS,UACnB,MAAM,MACJ,KAAK,KAAK,MAAM,aAAa,GAC7B,KAAK,UACH,EACE,UAAU,CAAC;EAAE,QAAQ;EAAS,aAAa;CAAgB,CAAC,EAC9D,GACA,MACA,CACF,IAAI,IACN;CAGF,IAAI,QAAQ,SAAS,mBACnB,MAAM,MACJ,KAAK,KAAK,MAAM,WAAW,GAC3B,KAAK,UACH;EACE,SAAS;EACT,SAAS,EACP,qBAAqB,EACnB,kBAAkB;GAChB,WAAW;GACX,eAAe;EACjB,EACF,EACF;EACA,iBAAiB;GACf,IAAI;GACJ,SAAS;EACX;EACA,YAAY,EACV,MAAM,EACJ,aAAa,GACf,EACF;CACF,GACA,MACA,CACF,IAAI,IACN;CAGF,MAAM,QAAQ,IACZ,OAAO,IAAI,OAAO,UAAU;EAC1B,MAAM,MAAM,MAAM,MAAM,UAAU,aAAa,MAAM,KAAK,KAAK,MAAM,QAAQ,GAAG,QAAQ,CAAC;CAC3F,CAAC,CACH;CAEA,IAAI;EACF,MAAM,SAAS,KAAK,KAAK,MAAM,cAAc,GAAG,KAAK,KAAK,MAAM,MAAM,CAAC;CACzE,QAAQ,CAER;CAEA,MAAM,mBAAmB,MAAM,GAAG;CAElC,IAAI,QAAQ,aACV,OAAO;CAGT,MAAM,QAAQ,QAAQ,SAAS,iBAAiB;CAChD,MAAM,gBAAgB,OAAO,MAAM;EACjC,cAAc,SAAS;EACvB,iBAAiB,SAAS;CAC5B,CAAC;CAED,OAAO;AACT"}
|
|
@@ -31,7 +31,7 @@ import { t } from '#src/taser.js'
|
|
|
31
31
|
const router = t.create(routeManifest)
|
|
32
32
|
|
|
33
33
|
const app = new Hono()
|
|
34
|
-
app.all('/*', c => router.
|
|
34
|
+
app.all('/*', c => router.fetch(c.req.raw))
|
|
35
35
|
|
|
36
36
|
const port = Number(process.env.PORT ?? 3000)
|
|
37
37
|
serve({ fetch: app.fetch, port }, () => {
|
|
@@ -93,7 +93,7 @@ import { t } from '#src/taser.js'
|
|
|
93
93
|
const router = t.create(routeManifest)
|
|
94
94
|
|
|
95
95
|
const app = new Hono()
|
|
96
|
-
app.all('/*', c => router.
|
|
96
|
+
app.all('/*', c => router.fetch(c.req.raw))
|
|
97
97
|
|
|
98
98
|
export const handler = handle(app)
|
|
99
99
|
`;
|
|
@@ -121,7 +121,7 @@ import { t } from '#src/taser.js'
|
|
|
121
121
|
const router = t.create(routeManifest)
|
|
122
122
|
|
|
123
123
|
const app = new Hono()
|
|
124
|
-
app.all('/*', c => router.
|
|
124
|
+
app.all('/*', c => router.fetch(c.req.raw))
|
|
125
125
|
|
|
126
126
|
export default handle(app)
|
|
127
127
|
`;
|
|
@@ -136,7 +136,7 @@ import { t } from '#src/taser.js'
|
|
|
136
136
|
const router = t.create(routeManifest)
|
|
137
137
|
|
|
138
138
|
const app = new Hono()
|
|
139
|
-
app.all('/*', c => router.
|
|
139
|
+
app.all('/*', c => router.fetch(c.req.raw))
|
|
140
140
|
|
|
141
141
|
export default handle(app)
|
|
142
142
|
`;
|
|
@@ -152,7 +152,7 @@ import { t } from '#src/taser.js'
|
|
|
152
152
|
const router = t.create(routeManifest)
|
|
153
153
|
|
|
154
154
|
const honoApp = new Hono()
|
|
155
|
-
honoApp.all('/*', c => router.
|
|
155
|
+
honoApp.all('/*', c => router.fetch(c.req.raw))
|
|
156
156
|
|
|
157
157
|
app.http('httpTrigger', {
|
|
158
158
|
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'],
|
|
@@ -191,33 +191,14 @@ serve({ fetch: router.fetch, port }, () => {
|
|
|
191
191
|
`;
|
|
192
192
|
}
|
|
193
193
|
}
|
|
194
|
-
function taserTsTemplate(
|
|
195
|
-
|
|
196
|
-
import { createTaserApp, type InferAppContext } from '@taserjs/router'
|
|
194
|
+
function taserTsTemplate(_type = "node") {
|
|
195
|
+
return `import { createTaserApp } from '@taserjs/router'
|
|
197
196
|
|
|
198
197
|
import { context } from '#src/context.js'
|
|
199
198
|
|
|
200
|
-
declare module '@taserjs/router' {
|
|
201
|
-
interface RouterRegister {
|
|
202
|
-
NativeContext: Context
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
199
|
export const t = createTaserApp({
|
|
207
200
|
response: { validate: true },
|
|
208
201
|
}).context(context)
|
|
209
|
-
|
|
210
|
-
export type AppContext = InferAppContext<typeof context>
|
|
211
|
-
`;
|
|
212
|
-
return `import { createTaserApp, type InferAppContext } from '@taserjs/router'
|
|
213
|
-
|
|
214
|
-
import { context } from '#src/context.js'
|
|
215
|
-
|
|
216
|
-
export const t = createTaserApp({
|
|
217
|
-
response: { validate: true },
|
|
218
|
-
}).context(context)
|
|
219
|
-
|
|
220
|
-
export type AppContext = InferAppContext<typeof context>
|
|
221
202
|
`;
|
|
222
203
|
}
|
|
223
204
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/frameworks/index.ts"],"sourcesContent":["import type { ProjectType } from \"../core/types.js\";\n\nexport function indexTemplate(type: ProjectType): string {\n switch (type) {\n case \"express\":\n return `import 'dotenv/config'\n\nimport express from 'express'\nimport { createExpressHandler } from '@taserjs/adapter-express'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst taser = createExpressHandler(router)\nconst app = express()\ntaser.mount('/{*splat}', app)\n\nconst port = Number(process.env.PORT ?? 3000)\napp.listen(port, () => {\n console.log(\\`Express listening on http://localhost:\\${port}\\`)\n})\n`;\n case \"hono\":\n return `import 'dotenv/config'\n\nimport { serve } from '@hono/node-server'\nimport { Hono } from 'hono'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst app = new Hono()\napp.all('/*', c => router.
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/frameworks/index.ts"],"sourcesContent":["import type { ProjectType } from \"../core/types.js\";\n\nexport function indexTemplate(type: ProjectType): string {\n switch (type) {\n case \"express\":\n return `import 'dotenv/config'\n\nimport express from 'express'\nimport { createExpressHandler } from '@taserjs/adapter-express'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst taser = createExpressHandler(router)\nconst app = express()\ntaser.mount('/{*splat}', app)\n\nconst port = Number(process.env.PORT ?? 3000)\napp.listen(port, () => {\n console.log(\\`Express listening on http://localhost:\\${port}\\`)\n})\n`;\n case \"hono\":\n return `import 'dotenv/config'\n\nimport { serve } from '@hono/node-server'\nimport { Hono } from 'hono'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst app = new Hono()\napp.all('/*', c => router.fetch(c.req.raw))\n\nconst port = Number(process.env.PORT ?? 3000)\nserve({ fetch: app.fetch, port }, () => {\n console.log(\\`Hono listening on http://localhost:\\${port}\\`)\n})\n`;\n case \"fastify\":\n return `import 'dotenv/config'\n\nimport Fastify from 'fastify'\nimport { createFastifyHandler } from '@taserjs/adapter-fastify'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst taser = createFastifyHandler(router)\nconst app = Fastify()\ntaser.mount('/*', app)\n\nconst port = Number(process.env.PORT ?? 3000)\nawait app.listen({ port })\nconsole.log(\\`Fastify listening on http://localhost:\\${port}\\`)\n`;\n case \"bun\":\n return `import 'dotenv/config'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst port = Number(process.env.PORT ?? 3000)\n\nexport default {\n port,\n fetch(request: Request) {\n return router.fetch(request)\n },\n}\n`;\n case \"deno\":\n return `import 'dotenv/config'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst port = Number(process.env.PORT ?? 8000)\nDeno.serve({ port }, (request: Request) => router.fetch(request))\n`;\n case \"aws-lambda\":\n return `import 'dotenv/config'\n\nimport { Hono } from 'hono'\nimport { handle } from 'hono/aws-lambda'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst app = new Hono()\napp.all('/*', c => router.fetch(c.req.raw))\n\nexport const handler = handle(app)\n`;\n case \"cloudflare-workers\":\n return `import 'dotenv/config'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nexport default {\n fetch(request: Request, env: unknown, ctx: unknown) {\n return router.fetch(request, env, ctx)\n },\n}\n`;\n case \"netlify\":\n return `import 'dotenv/config'\n\nimport { Hono } from 'hono'\nimport { handle } from 'hono/netlify'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst app = new Hono()\napp.all('/*', c => router.fetch(c.req.raw))\n\nexport default handle(app)\n`;\n case \"vercel\":\n return `import 'dotenv/config'\n\nimport { Hono } from 'hono'\nimport { handle } from 'hono/vercel'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst app = new Hono()\napp.all('/*', c => router.fetch(c.req.raw))\n\nexport default handle(app)\n`;\n case \"azure-functions\":\n return `import 'dotenv/config'\n\nimport { app } from '@azure/functions'\nimport { Hono } from 'hono'\nimport { azureHonoHandler } from '@marplex/hono-azurefunc-adapter'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst honoApp = new Hono()\nhonoApp.all('/*', c => router.fetch(c.req.raw))\n\napp.http('httpTrigger', {\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'],\n authLevel: 'anonymous',\n route: '{*proxy}',\n handler: azureHonoHandler(honoApp.fetch),\n})\n`;\n case \"google-cloud-run\":\n return `import 'dotenv/config'\n\nimport { serve } from '@hono/node-server'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst port = Number(process.env.PORT ?? 8080)\nserve({ fetch: router.fetch, port }, () => {\n console.log(\\`Cloud Run listening on http://localhost:\\${port}\\`)\n})\n`;\n case \"node\":\n default:\n return `import 'dotenv/config'\n\nimport { serve } from '@hono/node-server'\n\nimport { routeManifest } from '#src/routeManifest.gen.js'\nimport { t } from '#src/taser.js'\n\nconst router = t.create(routeManifest)\n\nconst port = Number(process.env.PORT ?? 3000)\nserve({ fetch: router.fetch, port }, () => {\n console.log(\\`Node listening on http://localhost:\\${port}\\`)\n})\n`;\n }\n}\n\nexport function taserTsTemplate(_type: ProjectType = \"node\"): string {\n return `import { createTaserApp } from '@taserjs/router'\n\nimport { context } from '#src/context.js'\n\nexport const t = createTaserApp({\n response: { validate: true },\n}).context(context)\n`;\n}\n"],"mappings":";AAEA,SAAgB,cAAc,MAA2B;CACvD,QAAQ,MAAR;EACE,KAAK,WACH,OAAO;;;;;;;;;;;;;;;;;;;EAmBT,KAAK,QACH,OAAO;;;;;;;;;;;;;;;;;;EAkBT,KAAK,WACH,OAAO;;;;;;;;;;;;;;;;;;EAkBT,KAAK,OACH,OAAO;;;;;;;;;;;;;;;;EAgBT,KAAK,QACH,OAAO;;;;;;;;;;EAUT,KAAK,cACH,OAAO;;;;;;;;;;;;;;;EAeT,KAAK,sBACH,OAAO;;;;;;;;;;;;;EAaT,KAAK,WACH,OAAO;;;;;;;;;;;;;;;EAeT,KAAK,UACH,OAAO;;;;;;;;;;;;;;;EAeT,KAAK,mBACH,OAAO;;;;;;;;;;;;;;;;;;;;;EAqBT,KAAK,oBACH,OAAO;;;;;;;;;;;;;;EAeT,SACE,OAAO;;;;;;;;;;;;;;CAcX;AACF;AAEA,SAAgB,gBAAgB,QAAqB,QAAgB;CACnE,OAAO;;;;;;;;AAQT"}
|
|
@@ -73,21 +73,22 @@ ${bootBlock}
|
|
|
73
73
|
`;
|
|
74
74
|
}
|
|
75
75
|
function rootLayoutTemplate() {
|
|
76
|
-
return `import {
|
|
77
|
-
import { secureHeaders } from '@taserjs/router/secure-headers'
|
|
76
|
+
return `import { cors } from '@taserjs/router/cors'
|
|
78
77
|
|
|
79
78
|
import { t } from '#src/taser.js'
|
|
80
79
|
|
|
81
80
|
export const Middleware = t.middleware('/$')
|
|
82
|
-
.use(
|
|
83
|
-
.use(bodyLimit({ maxSize: 1_000_000 }))
|
|
81
|
+
.use(cors())
|
|
84
82
|
`;
|
|
85
83
|
}
|
|
86
84
|
function indexRouteTemplate() {
|
|
87
85
|
return `import { reply } from '@taserjs/router'
|
|
88
86
|
import { t } from '#src/taser.js'
|
|
89
87
|
|
|
90
|
-
|
|
88
|
+
const GET = t.get('/')
|
|
89
|
+
|
|
90
|
+
export type RouteContext = typeof GET.$Infer.Context
|
|
91
|
+
export const Route = GET.handler((_ctx) => {
|
|
91
92
|
return reply.json({ message: 'Welcome to Taser' })
|
|
92
93
|
})
|
|
93
94
|
`;
|
|
@@ -100,7 +101,10 @@ function healthRouteTemplate(ctx) {
|
|
|
100
101
|
return `import { reply } from '@taserjs/router'
|
|
101
102
|
import { t } from '#src/taser.js'
|
|
102
103
|
|
|
103
|
-
|
|
104
|
+
const GET = t.get('/health')
|
|
105
|
+
|
|
106
|
+
export type RouteContext = typeof GET.$Infer.Context
|
|
107
|
+
export const Route = GET.handler(${lines.length > 0 ? "(ctx)" : "(_ctx)"} => {
|
|
104
108
|
${body} return reply.json({ ok: true })
|
|
105
109
|
})
|
|
106
110
|
`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","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(\n projectName: string,\n scripts: Record<string, string> = {},\n): 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 {\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 },\n null,\n 2,\n )}\\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 =\n bindings.length > 0\n ? bindings.map((binding) => ` ${binding.key}: ${binding.factoryName}(),`).join(\"\\n\")\n : \"\";\n\n const bootBlock = bindings.length > 0 ? ` boot: () => ({\\n${bootBody}\\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 {
|
|
1
|
+
{"version":3,"file":"base.js","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(\n projectName: string,\n scripts: Record<string, string> = {},\n): 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 {\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 },\n null,\n 2,\n )}\\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 =\n bindings.length > 0\n ? bindings.map((binding) => ` ${binding.key}: ${binding.factoryName}(),`).join(\"\\n\")\n : \"\";\n\n const bootBlock = bindings.length > 0 ? ` boot: () => ({\\n${bootBody}\\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 { cors } from '@taserjs/router/cors'\n\nimport { t } from '#src/taser.js'\n\nexport const Middleware = t.middleware('/$')\n .use(cors())\n`;\n}\n\nexport function indexRouteTemplate(): string {\n return `import { reply } from '@taserjs/router'\nimport { t } from '#src/taser.js'\n\nconst GET = t.get('/')\n\nexport type RouteContext = typeof GET.$Infer.Context\nexport const Route = GET.handler((_ctx) => {\n return 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 const ctxArg = lines.length > 0 ? \"(ctx)\" : \"(_ctx)\";\n\n return `import { reply } from '@taserjs/router'\nimport { t } from '#src/taser.js'\n\nconst GET = t.get('/health')\n\nexport type RouteContext = typeof GET.$Infer.Context\nexport const Route = GET.handler(${ctxArg} => {\n${body} return 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,oBACd,aACA,UAAkC,CAAC,GAC3B;CACR,MAAM,MAAM;EACV,MAAM;EACN,SAAS;EACT,SAAS;EACT,MAAM;EACN,SAAS,EACP,UAAU,UACZ;EACA,SAAS;GACP,KAAK;GACL,cAAc;GACd,aAAa;GACb,OAAO;GACP,UAAU;GACV,OAAO;GACP,OAAO;GACP,WAAW;GACX,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,UACb;EACE,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,GACA,MACA,CACF,EAAE;AACJ;AAEA,SAAgB,oBAA4B;CAC1C,OAAO;;;;;;;;AAQT;AAEA,SAAgB,gBAAgB,UAAiC;CAC/D,MAAM,UAAU,SAAS,KACtB,YAAY,YAAY,QAAQ,YAAY,WAAW,QAAQ,WAAW,EAC7E;CAEA,MAAM,WACJ,SAAS,SAAS,IACd,SAAS,KAAK,YAAY,OAAO,QAAQ,IAAI,IAAI,QAAQ,YAAY,IAAI,CAAC,CAAC,KAAK,IAAI,IACpF;CAEN,MAAM,YAAY,SAAS,SAAS,IAAI,qBAAqB,SAAS,WAAW;CAIjF,OAAO,GAFa,QAAQ,SAAS,IAAI,GAAG,QAAQ,KAAK,IAAI,EAAE,QAAQ,GAEjD;;;EAGtB,UAAU;;;;;;AAMZ;AAEA,SAAgB,qBAA6B;CAC3C,OAAO;;;;;;;AAOT;AAEA,SAAgB,qBAA6B;CAC3C,OAAO;;;;;;;;;;AAUT;AAEA,SAAgB,oBAAoB,KAA8B;CAChE,MAAM,QAAkB,CAAC;CAEzB,IAAI,IAAI,QACN,MAAM,KAAK,mCAAmC;CAGhD,IAAI,IAAI,IACN,MAAM,KAAK,4CAA4C;CAGzD,MAAM,OAAO,MAAM,SAAS,IAAI,GAAG,MAAM,KAAK,IAAI,EAAE,MAAM;CAG1D,OAAO;;;;;;mCAFQ,MAAM,SAAS,IAAI,UAAU,SAQJ;EACxC,KAAK;;;AAGP;;AAGA,SAAgB,0BAAkC;CAChD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DT"}
|
package/package.json
CHANGED
package/src/addons/registry.ts
CHANGED
|
@@ -64,16 +64,6 @@ export function resolveAddons(ctx: ScaffoldContext): AddonDefinition[] {
|
|
|
64
64
|
selected.push(loggerAddon);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
const dbCount = selected.filter((addon) => addon.category === "database").length;
|
|
68
|
-
if (dbCount > 1) {
|
|
69
|
-
throw new Error("Only one database addon can be selected");
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const loggerCount = selected.filter((addon) => addon.category === "logger").length;
|
|
73
|
-
if (loggerCount > 1) {
|
|
74
|
-
throw new Error("Only one logger addon can be selected");
|
|
75
|
-
}
|
|
76
|
-
|
|
77
67
|
if (ctx.validator) {
|
|
78
68
|
const validatorAddon = VALIDATOR_ADDONS.find((addon) => addon.id === ctx.validator);
|
|
79
69
|
if (!validatorAddon) {
|
|
@@ -82,11 +72,6 @@ export function resolveAddons(ctx: ScaffoldContext): AddonDefinition[] {
|
|
|
82
72
|
selected.push(validatorAddon);
|
|
83
73
|
}
|
|
84
74
|
|
|
85
|
-
const validatorCount = selected.filter((addon) => addon.category === "validator").length;
|
|
86
|
-
if (validatorCount > 1) {
|
|
87
|
-
throw new Error("Only one validator addon can be selected");
|
|
88
|
-
}
|
|
89
|
-
|
|
90
75
|
return selected;
|
|
91
76
|
}
|
|
92
77
|
|
package/src/addons/validators.ts
CHANGED
|
@@ -9,13 +9,13 @@ export const IMPORT_LINES: Record<ValidatorId, string> = {
|
|
|
9
9
|
|
|
10
10
|
export const VALIDATION_BLOCK_TEMPLATE: Record<ValidatorId, string> = {
|
|
11
11
|
zod: `, {
|
|
12
|
-
query: z.object({ name: z.string() }),
|
|
12
|
+
query: z.object({ name: z.string().default('Taser') }),
|
|
13
13
|
}`,
|
|
14
14
|
arktype: `, {
|
|
15
|
-
query: type({ name: 'string' }),
|
|
15
|
+
query: type({ 'name?': 'string = "Taser"' }),
|
|
16
16
|
}`,
|
|
17
17
|
valibot: `, {
|
|
18
|
-
query: v.object({ name: v.string() }),
|
|
18
|
+
query: v.object({ name: v.optional(v.string(), 'Taser') }),
|
|
19
19
|
}`,
|
|
20
20
|
};
|
|
21
21
|
|
|
@@ -23,7 +23,10 @@ const ROUTE_TEMPLATE = (validator: ValidatorId) => `import { reply } from '@tase
|
|
|
23
23
|
import { t } from '#src/taser.js'
|
|
24
24
|
${IMPORT_LINES[validator]}
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
const GET = t.get('/'${VALIDATION_BLOCK_TEMPLATE[validator]})
|
|
27
|
+
|
|
28
|
+
export type RouteContext = typeof GET.$Infer.Context
|
|
29
|
+
export const Route = GET.handler((ctx) => {
|
|
27
30
|
return reply.json({ message: \`Hello, \${ctx.query.name}!\` })
|
|
28
31
|
})
|
|
29
32
|
`;
|
|
@@ -128,14 +128,7 @@ export async function scaffoldProject(options: ScaffoldOptions): Promise<Scaffol
|
|
|
128
128
|
await writeProjectConfig(root, ctx);
|
|
129
129
|
|
|
130
130
|
if (options.skipInstall) {
|
|
131
|
-
return
|
|
132
|
-
projectName: ctx.projectName,
|
|
133
|
-
targetDir: root,
|
|
134
|
-
type: ctx.type,
|
|
135
|
-
...(ctx.db ? { db: ctx.db, driver: ctx.driver } : {}),
|
|
136
|
-
...(ctx.logger ? { logger: ctx.logger } : {}),
|
|
137
|
-
...(ctx.validator ? { validator: ctx.validator } : {}),
|
|
138
|
-
};
|
|
131
|
+
return ctx as ScaffoldResult;
|
|
139
132
|
}
|
|
140
133
|
|
|
141
134
|
const agent = options.agent ?? resolveUserAgent();
|
|
@@ -144,12 +137,5 @@ export async function scaffoldProject(options: ScaffoldOptions): Promise<Scaffol
|
|
|
144
137
|
devDependencies: packages.devDependencies,
|
|
145
138
|
});
|
|
146
139
|
|
|
147
|
-
return
|
|
148
|
-
projectName: ctx.projectName,
|
|
149
|
-
targetDir: root,
|
|
150
|
-
type: ctx.type,
|
|
151
|
-
...(ctx.db ? { db: ctx.db, driver: ctx.driver } : {}),
|
|
152
|
-
...(ctx.logger ? { logger: ctx.logger } : {}),
|
|
153
|
-
...(ctx.validator ? { validator: ctx.validator } : {}),
|
|
154
|
-
};
|
|
140
|
+
return ctx as ScaffoldResult;
|
|
155
141
|
}
|
package/src/frameworks/index.ts
CHANGED
|
@@ -34,7 +34,7 @@ import { t } from '#src/taser.js'
|
|
|
34
34
|
const router = t.create(routeManifest)
|
|
35
35
|
|
|
36
36
|
const app = new Hono()
|
|
37
|
-
app.all('/*', c => router.
|
|
37
|
+
app.all('/*', c => router.fetch(c.req.raw))
|
|
38
38
|
|
|
39
39
|
const port = Number(process.env.PORT ?? 3000)
|
|
40
40
|
serve({ fetch: app.fetch, port }, () => {
|
|
@@ -100,7 +100,7 @@ import { t } from '#src/taser.js'
|
|
|
100
100
|
const router = t.create(routeManifest)
|
|
101
101
|
|
|
102
102
|
const app = new Hono()
|
|
103
|
-
app.all('/*', c => router.
|
|
103
|
+
app.all('/*', c => router.fetch(c.req.raw))
|
|
104
104
|
|
|
105
105
|
export const handler = handle(app)
|
|
106
106
|
`;
|
|
@@ -130,7 +130,7 @@ import { t } from '#src/taser.js'
|
|
|
130
130
|
const router = t.create(routeManifest)
|
|
131
131
|
|
|
132
132
|
const app = new Hono()
|
|
133
|
-
app.all('/*', c => router.
|
|
133
|
+
app.all('/*', c => router.fetch(c.req.raw))
|
|
134
134
|
|
|
135
135
|
export default handle(app)
|
|
136
136
|
`;
|
|
@@ -146,7 +146,7 @@ import { t } from '#src/taser.js'
|
|
|
146
146
|
const router = t.create(routeManifest)
|
|
147
147
|
|
|
148
148
|
const app = new Hono()
|
|
149
|
-
app.all('/*', c => router.
|
|
149
|
+
app.all('/*', c => router.fetch(c.req.raw))
|
|
150
150
|
|
|
151
151
|
export default handle(app)
|
|
152
152
|
`;
|
|
@@ -163,7 +163,7 @@ import { t } from '#src/taser.js'
|
|
|
163
163
|
const router = t.create(routeManifest)
|
|
164
164
|
|
|
165
165
|
const honoApp = new Hono()
|
|
166
|
-
honoApp.all('/*', c => router.
|
|
166
|
+
honoApp.all('/*', c => router.fetch(c.req.raw))
|
|
167
167
|
|
|
168
168
|
app.http('httpTrigger', {
|
|
169
169
|
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'],
|
|
@@ -206,41 +206,13 @@ serve({ fetch: router.fetch, port }, () => {
|
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
-
export function taserTsTemplate(
|
|
210
|
-
|
|
211
|
-
type === "hono" ||
|
|
212
|
-
type === "aws-lambda" ||
|
|
213
|
-
type === "netlify" ||
|
|
214
|
-
type === "vercel" ||
|
|
215
|
-
type === "azure-functions"
|
|
216
|
-
) {
|
|
217
|
-
return `import type { Context } from 'hono'
|
|
218
|
-
import { createTaserApp, type InferAppContext } from '@taserjs/router'
|
|
219
|
-
|
|
220
|
-
import { context } from '#src/context.js'
|
|
221
|
-
|
|
222
|
-
declare module '@taserjs/router' {
|
|
223
|
-
interface RouterRegister {
|
|
224
|
-
NativeContext: Context
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
export const t = createTaserApp({
|
|
229
|
-
response: { validate: true },
|
|
230
|
-
}).context(context)
|
|
231
|
-
|
|
232
|
-
export type AppContext = InferAppContext<typeof context>
|
|
233
|
-
`;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
return `import { createTaserApp, type InferAppContext } from '@taserjs/router'
|
|
209
|
+
export function taserTsTemplate(_type: ProjectType = "node"): string {
|
|
210
|
+
return `import { createTaserApp } from '@taserjs/router'
|
|
237
211
|
|
|
238
212
|
import { context } from '#src/context.js'
|
|
239
213
|
|
|
240
214
|
export const t = createTaserApp({
|
|
241
215
|
response: { validate: true },
|
|
242
216
|
}).context(context)
|
|
243
|
-
|
|
244
|
-
export type AppContext = InferAppContext<typeof context>
|
|
245
217
|
`;
|
|
246
218
|
}
|
package/src/templates/base.ts
CHANGED
|
@@ -102,14 +102,12 @@ ${bootBlock}
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
export function rootLayoutTemplate(): string {
|
|
105
|
-
return `import {
|
|
106
|
-
import { secureHeaders } from '@taserjs/router/secure-headers'
|
|
105
|
+
return `import { cors } from '@taserjs/router/cors'
|
|
107
106
|
|
|
108
107
|
import { t } from '#src/taser.js'
|
|
109
108
|
|
|
110
109
|
export const Middleware = t.middleware('/$')
|
|
111
|
-
.use(
|
|
112
|
-
.use(bodyLimit({ maxSize: 1_000_000 }))
|
|
110
|
+
.use(cors())
|
|
113
111
|
`;
|
|
114
112
|
}
|
|
115
113
|
|
|
@@ -117,7 +115,10 @@ export function indexRouteTemplate(): string {
|
|
|
117
115
|
return `import { reply } from '@taserjs/router'
|
|
118
116
|
import { t } from '#src/taser.js'
|
|
119
117
|
|
|
120
|
-
|
|
118
|
+
const GET = t.get('/')
|
|
119
|
+
|
|
120
|
+
export type RouteContext = typeof GET.$Infer.Context
|
|
121
|
+
export const Route = GET.handler((_ctx) => {
|
|
121
122
|
return reply.json({ message: 'Welcome to Taser' })
|
|
122
123
|
})
|
|
123
124
|
`;
|
|
@@ -135,12 +136,15 @@ export function healthRouteTemplate(ctx: ScaffoldContext): string {
|
|
|
135
136
|
}
|
|
136
137
|
|
|
137
138
|
const body = lines.length > 0 ? `${lines.join("\n")}\n` : "";
|
|
138
|
-
const ctxArg = lines.length > 0 ? "(ctx)" : "()";
|
|
139
|
+
const ctxArg = lines.length > 0 ? "(ctx)" : "(_ctx)";
|
|
139
140
|
|
|
140
141
|
return `import { reply } from '@taserjs/router'
|
|
141
142
|
import { t } from '#src/taser.js'
|
|
142
143
|
|
|
143
|
-
|
|
144
|
+
const GET = t.get('/health')
|
|
145
|
+
|
|
146
|
+
export type RouteContext = typeof GET.$Infer.Context
|
|
147
|
+
export const Route = GET.handler(${ctxArg} => {
|
|
144
148
|
${body} return reply.json({ ok: true })
|
|
145
149
|
})
|
|
146
150
|
`;
|