create-taserjs 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/README.md +2 -0
  2. package/dist/cjs/addons/arktype/index.cjs.map +1 -1
  3. package/dist/cjs/addons/drizzle/index.cjs.map +1 -1
  4. package/dist/cjs/addons/kysely/index.cjs.map +1 -1
  5. package/dist/cjs/addons/pino/index.cjs.map +1 -1
  6. package/dist/cjs/addons/prisma/index.cjs +84 -24
  7. package/dist/cjs/addons/prisma/index.cjs.map +1 -1
  8. package/dist/cjs/addons/registry.cjs +1 -1
  9. package/dist/cjs/addons/registry.cjs.map +1 -1
  10. package/dist/cjs/addons/types.d.cts +1 -1
  11. package/dist/cjs/addons/valibot/index.cjs.map +1 -1
  12. package/dist/cjs/addons/validators.cjs.map +1 -1
  13. package/dist/cjs/addons/winston/index.cjs.map +1 -1
  14. package/dist/cjs/addons/zod/index.cjs.map +1 -1
  15. package/dist/cjs/cli.cjs +5 -0
  16. package/dist/cjs/cli.cjs.map +1 -1
  17. package/dist/cjs/commands/create.cjs +44 -11
  18. package/dist/cjs/commands/create.cjs.map +1 -1
  19. package/dist/cjs/commands/create.d.cts +1 -0
  20. package/dist/cjs/core/json-output.cjs.map +1 -1
  21. package/dist/cjs/core/package-manager.cjs.map +1 -1
  22. package/dist/cjs/core/package-manager.d.cts +1 -1
  23. package/dist/cjs/core/parse-options.cjs +7 -7
  24. package/dist/cjs/core/parse-options.cjs.map +1 -1
  25. package/dist/cjs/core/parse-options.d.cts +3 -3
  26. package/dist/cjs/core/project-config.cjs +1 -1
  27. package/dist/cjs/core/project-config.cjs.map +1 -1
  28. package/dist/cjs/core/resolve-packages.cjs +41 -7
  29. package/dist/cjs/core/resolve-packages.cjs.map +1 -1
  30. package/dist/cjs/core/resolve-packages.d.cts +2 -2
  31. package/dist/cjs/core/scaffold-engine.cjs +33 -6
  32. package/dist/cjs/core/scaffold-engine.cjs.map +1 -1
  33. package/dist/cjs/core/types.cjs +11 -3
  34. package/dist/cjs/core/types.cjs.map +1 -1
  35. package/dist/cjs/core/types.d.cts +8 -8
  36. package/dist/cjs/core/validate-project-name.cjs.map +1 -1
  37. package/dist/cjs/frameworks/index.cjs +138 -17
  38. package/dist/cjs/frameworks/index.cjs.map +1 -1
  39. package/dist/cjs/frameworks/index.d.cts +3 -3
  40. package/dist/cjs/scaffold.d.cts +1 -1
  41. package/dist/cjs/templates/base.cjs +6 -6
  42. package/dist/cjs/templates/base.cjs.map +1 -1
  43. package/dist/cjs/types.d.cts +1 -1
  44. package/dist/esm/addons/arktype/index.js.map +1 -1
  45. package/dist/esm/addons/drizzle/index.js.map +1 -1
  46. package/dist/esm/addons/kysely/index.js.map +1 -1
  47. package/dist/esm/addons/pino/index.js.map +1 -1
  48. package/dist/esm/addons/prisma/index.js +84 -24
  49. package/dist/esm/addons/prisma/index.js.map +1 -1
  50. package/dist/esm/addons/registry.js +2 -2
  51. package/dist/esm/addons/registry.js.map +1 -1
  52. package/dist/esm/addons/types.d.ts +1 -1
  53. package/dist/esm/addons/valibot/index.js.map +1 -1
  54. package/dist/esm/addons/validators.js.map +1 -1
  55. package/dist/esm/addons/winston/index.js.map +1 -1
  56. package/dist/esm/addons/zod/index.js.map +1 -1
  57. package/dist/esm/cli.js +5 -0
  58. package/dist/esm/cli.js.map +1 -1
  59. package/dist/esm/commands/create.d.ts +1 -0
  60. package/dist/esm/commands/create.js +46 -13
  61. package/dist/esm/commands/create.js.map +1 -1
  62. package/dist/esm/core/json-output.js.map +1 -1
  63. package/dist/esm/core/package-manager.d.ts +1 -1
  64. package/dist/esm/core/package-manager.js.map +1 -1
  65. package/dist/esm/core/parse-options.d.ts +3 -3
  66. package/dist/esm/core/parse-options.js +8 -8
  67. package/dist/esm/core/parse-options.js.map +1 -1
  68. package/dist/esm/core/project-config.js +1 -1
  69. package/dist/esm/core/project-config.js.map +1 -1
  70. package/dist/esm/core/resolve-packages.d.ts +2 -2
  71. package/dist/esm/core/resolve-packages.js +41 -7
  72. package/dist/esm/core/resolve-packages.js.map +1 -1
  73. package/dist/esm/core/scaffold-engine.js +34 -7
  74. package/dist/esm/core/scaffold-engine.js.map +1 -1
  75. package/dist/esm/core/types.d.ts +8 -8
  76. package/dist/esm/core/types.js +11 -3
  77. package/dist/esm/core/types.js.map +1 -1
  78. package/dist/esm/core/validate-project-name.js.map +1 -1
  79. package/dist/esm/frameworks/index.d.ts +3 -3
  80. package/dist/esm/frameworks/index.js +138 -17
  81. package/dist/esm/frameworks/index.js.map +1 -1
  82. package/dist/esm/scaffold.d.ts +1 -1
  83. package/dist/esm/templates/base.js +6 -6
  84. package/dist/esm/templates/base.js.map +1 -1
  85. package/dist/esm/types.d.ts +1 -1
  86. package/package.json +13 -13
  87. package/src/addons/arktype/index.ts +2 -2
  88. package/src/addons/drizzle/index.ts +53 -53
  89. package/src/addons/kysely/index.ts +42 -42
  90. package/src/addons/pino/index.ts +12 -12
  91. package/src/addons/prisma/index.ts +128 -55
  92. package/src/addons/registry.ts +37 -37
  93. package/src/addons/types.ts +14 -14
  94. package/src/addons/valibot/index.ts +2 -2
  95. package/src/addons/validators.ts +9 -9
  96. package/src/addons/winston/index.ts +12 -12
  97. package/src/addons/zod/index.ts +2 -2
  98. package/src/cli.ts +27 -26
  99. package/src/commands/create.ts +181 -152
  100. package/src/core/json-output.ts +4 -4
  101. package/src/core/package-manager.ts +38 -31
  102. package/src/core/parse-options.ts +50 -48
  103. package/src/core/project-config.ts +10 -14
  104. package/src/core/resolve-packages.ts +79 -41
  105. package/src/core/scaffold-engine.ts +106 -36
  106. package/src/core/types.ts +61 -36
  107. package/src/core/validate-project-name.ts +40 -40
  108. package/src/frameworks/index.ts +164 -29
  109. package/src/scaffold.ts +3 -3
  110. package/src/templates/base.ts +57 -51
  111. package/src/types.ts +5 -4
@@ -2,115 +2,117 @@ import {
2
2
  DB_DRIVERS,
3
3
  DB_ODMS,
4
4
  DEFAULT_DB_DRIVER,
5
- FRAMEWORKS,
6
5
  LOGGERS,
6
+ PROJECT_TYPES,
7
7
  VALIDATORS,
8
8
  type DbDriver,
9
9
  type DbOdm,
10
- type Framework,
11
10
  type LoggerId,
11
+ type ProjectType,
12
12
  type ScaffoldContext,
13
13
  type ValidatorId,
14
- } from './types.js'
14
+ } from "./types.js";
15
15
 
16
16
  export type ParsedCreateArgs = {
17
- projectName?: string
18
- framework?: Framework
19
- db?: DbOdm
20
- driver?: DbDriver
21
- logger?: LoggerId
22
- validator?: ValidatorId
23
- yes: boolean
24
- noInstall: boolean
25
- json: boolean
26
- }
27
-
28
- function isFramework(value: string): value is Framework {
29
- return (FRAMEWORKS as readonly string[]).includes(value)
17
+ projectName?: string;
18
+ type?: ProjectType;
19
+ db?: DbOdm;
20
+ driver?: DbDriver;
21
+ logger?: LoggerId;
22
+ validator?: ValidatorId;
23
+ yes: boolean;
24
+ noInstall: boolean;
25
+ json: boolean;
26
+ };
27
+
28
+ function isProjectType(value: string): value is ProjectType {
29
+ return (PROJECT_TYPES as readonly string[]).includes(value);
30
30
  }
31
31
 
32
32
  function isDbOdm(value: string): value is DbOdm {
33
- return (DB_ODMS as readonly string[]).includes(value)
33
+ return (DB_ODMS as readonly string[]).includes(value);
34
34
  }
35
35
 
36
36
  function isDbDriver(value: string): value is DbDriver {
37
- return (DB_DRIVERS as readonly string[]).includes(value)
37
+ return (DB_DRIVERS as readonly string[]).includes(value);
38
38
  }
39
39
 
40
40
  function isLoggerId(value: string): value is LoggerId {
41
- return (LOGGERS as readonly string[]).includes(value)
41
+ return (LOGGERS as readonly string[]).includes(value);
42
42
  }
43
43
 
44
44
  function isValidatorId(value: string): value is ValidatorId {
45
- return (VALIDATORS as readonly string[]).includes(value)
45
+ return (VALIDATORS as readonly string[]).includes(value);
46
46
  }
47
47
 
48
- export function parseDbFlag(value: string): { db: DbOdm, driver: DbDriver } {
49
- const [odm, driver] = value.split(':')
48
+ export function parseDbFlag(value: string): { db: DbOdm; driver: DbDriver } {
49
+ const [odm, driver] = value.split(":");
50
50
  if (!odm || !isDbOdm(odm)) {
51
- throw new Error(`Invalid --db value "${value}". Use drizzle, prisma, or kysely (optionally with :postgres, :sqlite, or :mysql).`)
51
+ throw new Error(
52
+ `Invalid --db value "${value}". Use drizzle, prisma, or kysely (optionally with :postgres, :sqlite, or :mysql).`,
53
+ );
52
54
  }
53
55
 
54
- if (driver === undefined || driver === '') {
55
- return { db: odm, driver: DEFAULT_DB_DRIVER }
56
+ if (driver === undefined || driver === "") {
57
+ return { db: odm, driver: DEFAULT_DB_DRIVER };
56
58
  }
57
59
 
58
60
  if (!isDbDriver(driver)) {
59
- throw new Error(`Invalid database driver "${driver}". Use postgres, sqlite, or mysql.`)
61
+ throw new Error(`Invalid database driver "${driver}". Use postgres, sqlite, or mysql.`);
60
62
  }
61
63
 
62
- return { db: odm, driver }
64
+ return { db: odm, driver };
63
65
  }
64
66
 
65
67
  export function resolveScaffoldDefaults(args: ParsedCreateArgs): ScaffoldContext {
66
- const framework = args.framework ?? 'node'
67
- const db = args.db
68
- const logger = args.logger
69
- const validator = args.validator
68
+ const type = args.type ?? "node";
69
+ const db = args.db;
70
+ const logger = args.logger;
71
+ const validator = args.validator;
70
72
 
71
73
  if (!args.projectName) {
72
- throw new Error('Project name is required')
74
+ throw new Error("Project name is required");
73
75
  }
74
76
 
75
77
  const result: ScaffoldContext = {
76
78
  projectName: args.projectName.trim(),
77
- targetDir: '',
78
- framework,
79
- }
79
+ targetDir: "",
80
+ type,
81
+ };
80
82
 
81
83
  if (db) {
82
- result.db = db
83
- result.driver = args.driver ?? DEFAULT_DB_DRIVER
84
+ result.db = db;
85
+ result.driver = args.driver ?? DEFAULT_DB_DRIVER;
84
86
  }
85
87
 
86
88
  if (logger) {
87
- result.logger = logger
89
+ result.logger = logger;
88
90
  }
89
91
 
90
92
  if (validator) {
91
- result.validator = validator
93
+ result.validator = validator;
92
94
  }
93
95
 
94
- return result
96
+ return result;
95
97
  }
96
98
 
97
- export function parseFrameworkFlag(value: string): Framework {
98
- if (!isFramework(value)) {
99
- throw new Error(`Invalid --framework "${value}". Use node, express, hono, or fastify.`)
99
+ export function parseTypeFlag(value: string): ProjectType {
100
+ if (!isProjectType(value)) {
101
+ throw new Error(`Invalid --type "${value}". Use ${PROJECT_TYPES.join(", ")}.`);
100
102
  }
101
- return value
103
+ return value;
102
104
  }
103
105
 
104
106
  export function parseLoggerFlag(value: string): LoggerId {
105
107
  if (!isLoggerId(value)) {
106
- throw new Error(`Invalid --logger "${value}". Use pino or winston.`)
108
+ throw new Error(`Invalid --logger "${value}". Use pino or winston.`);
107
109
  }
108
- return value
110
+ return value;
109
111
  }
110
112
 
111
113
  export function parseValidatorFlag(value: string): ValidatorId {
112
114
  if (!isValidatorId(value)) {
113
- throw new Error(`Invalid --validator "${value}". Use zod, arktype, or valibot.`)
115
+ throw new Error(`Invalid --validator "${value}". Use zod, arktype, or valibot.`);
114
116
  }
115
- return value
117
+ return value;
116
118
  }
@@ -1,31 +1,27 @@
1
- import { writeFile } from 'node:fs/promises'
2
- import path from 'node:path'
1
+ import { writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
3
 
4
- import type { ScaffoldContext } from './types.js'
4
+ import type { ScaffoldContext } from "./types.js";
5
5
 
6
6
  export async function writeProjectConfig(root: string, ctx: ScaffoldContext): Promise<void> {
7
7
  const config: Record<string, string> = {
8
- framework: ctx.framework,
9
- }
8
+ type: ctx.type,
9
+ };
10
10
 
11
11
  if (ctx.db) {
12
- config.db = ctx.db
12
+ config.db = ctx.db;
13
13
  if (ctx.driver) {
14
- config.driver = ctx.driver
14
+ config.driver = ctx.driver;
15
15
  }
16
16
  }
17
17
 
18
18
  if (ctx.logger) {
19
- config.logger = ctx.logger
19
+ config.logger = ctx.logger;
20
20
  }
21
21
 
22
22
  if (ctx.validator) {
23
- config.validator = ctx.validator
23
+ config.validator = ctx.validator;
24
24
  }
25
25
 
26
- await writeFile(
27
- path.join(root, '.taser.json'),
28
- `${JSON.stringify(config, null, 2)}\n`,
29
- 'utf8',
30
- )
26
+ await writeFile(path.join(root, ".taser.json"), `${JSON.stringify(config, null, 2)}\n`, "utf8");
31
27
  }
@@ -1,51 +1,88 @@
1
- import { resolveAddons } from '../addons/registry.js'
2
- import type { PackageGroups, ScaffoldContext, Framework } from '../core/types.js'
1
+ import { resolveAddons } from "../addons/registry.js";
2
+ import type { PackageGroups, ProjectType, ScaffoldContext } from "../core/types.js";
3
3
 
4
- function frameworkPackages(framework: Framework): PackageGroups {
5
- const dependencies = ['@taserjs/router']
4
+ function typePackages(type: ProjectType): PackageGroups {
5
+ const dependencies = ["@taserjs/router", "dotenv"];
6
6
  const devDependencies = [
7
- '@taserjs/router-cli',
8
- 'npm-run-all2',
9
- 'tsdown',
10
- 'tsx',
11
- 'typescript',
12
- '@types/node',
13
- ]
14
- const scripts: Record<string, string> = {}
15
-
16
- switch (framework) {
17
- case 'express':
18
- dependencies.push('@taserjs/adapter-express', 'express')
19
- devDependencies.push('@types/express')
20
- break
21
- case 'hono':
22
- dependencies.push('@hono/node-server', 'hono')
23
- break
24
- case 'fastify':
25
- dependencies.push('@taserjs/adapter-fastify', 'fastify')
26
- break
27
- case 'node':
7
+ "@taserjs/router-cli",
8
+ "npm-run-all2",
9
+ "tsdown",
10
+ "tsx",
11
+ "typescript",
12
+ "@types/node",
13
+ ];
14
+ const scripts: Record<string, string> = {};
15
+
16
+ switch (type) {
17
+ case "express":
18
+ dependencies.push("@taserjs/adapter-express", "express");
19
+ devDependencies.push("@types/express");
20
+ break;
21
+ case "fastify":
22
+ dependencies.push("@taserjs/adapter-fastify", "fastify");
23
+ break;
24
+ case "hono":
25
+ dependencies.push("@hono/node-server", "hono");
26
+ break;
27
+ case "bun":
28
+ // Bun has native TypeScript and runtime execution
29
+ devDependencies.push("@types/bun");
30
+ scripts["dev:server"] = "bun --watch src/index.ts";
31
+ scripts.start = "bun src/index.ts";
32
+ scripts.serve = "bun dist/index.mjs";
33
+ break;
34
+ case "deno":
35
+ scripts["dev:server"] = "deno run --watch --allow-net --allow-env --allow-read src/index.ts";
36
+ scripts.start = "deno run --allow-net --allow-env --allow-read src/index.ts";
37
+ scripts.serve = "deno run --allow-net --allow-env --allow-read dist/index.mjs";
38
+ break;
39
+ case "aws-lambda":
40
+ dependencies.push("hono");
41
+ devDependencies.push("@types/aws-lambda");
42
+ break;
43
+ case "cloudflare-workers": {
44
+ // Cloudflare workers uses wrangler
45
+ const cfDevDeps = devDependencies.filter((d) => d !== "tsx");
46
+ cfDevDeps.push("wrangler", "@cloudflare/workers-types");
47
+ devDependencies.length = 0;
48
+ devDependencies.push(...cfDevDeps);
49
+ scripts["dev:server"] = "wrangler dev";
50
+ scripts.deploy = "wrangler deploy";
51
+ break;
52
+ }
53
+ case "netlify":
54
+ dependencies.push("hono", "@netlify/functions");
55
+ break;
56
+ case "vercel":
57
+ dependencies.push("hono");
58
+ devDependencies.push("@vercel/node");
59
+ break;
60
+ case "azure-functions":
61
+ dependencies.push("hono", "@azure/functions", "@marplex/hono-azurefunc-adapter");
62
+ break;
63
+ case "google-cloud-run":
64
+ case "node":
28
65
  default:
29
- dependencies.push('@taserjs/adapter-node')
30
- break
66
+ dependencies.push("@hono/node-server");
67
+ break;
31
68
  }
32
69
 
33
- return { dependencies, devDependencies, scripts }
70
+ return { dependencies, devDependencies, scripts };
34
71
  }
35
72
 
36
73
  export function resolvePackages(ctx: ScaffoldContext): PackageGroups {
37
- const base = frameworkPackages(ctx.framework)
38
- const addons = resolveAddons(ctx)
74
+ const base = typePackages(ctx.type);
75
+ const addons = resolveAddons(ctx);
39
76
 
40
- const dependencies = [...base.dependencies]
41
- const devDependencies = [...base.devDependencies]
42
- const scripts = { ...base.scripts }
77
+ const dependencies = [...base.dependencies];
78
+ const devDependencies = [...base.devDependencies];
79
+ const scripts = { ...base.scripts };
43
80
 
44
81
  for (const addon of addons) {
45
- dependencies.push(...addon.dependencies(ctx))
46
- devDependencies.push(...addon.devDependencies(ctx))
82
+ dependencies.push(...addon.dependencies(ctx));
83
+ devDependencies.push(...addon.devDependencies(ctx));
47
84
  if (addon.scripts) {
48
- Object.assign(scripts, addon.scripts(ctx))
85
+ Object.assign(scripts, addon.scripts(ctx));
49
86
  }
50
87
  }
51
88
 
@@ -53,11 +90,12 @@ export function resolvePackages(ctx: ScaffoldContext): PackageGroups {
53
90
  dependencies: [...new Set(dependencies)],
54
91
  devDependencies: [...new Set(devDependencies)],
55
92
  scripts,
56
- }
93
+ };
57
94
  }
58
95
 
59
- // Backward-compatible export for tests during migration
60
- export function getPackageGroups(framework: Framework): Omit<PackageGroups, 'scripts'> & { scripts?: Record<string, string> } {
61
- const groups = frameworkPackages(framework)
62
- return groups
96
+ export function getPackageGroups(
97
+ type: ProjectType,
98
+ ): Omit<PackageGroups, "scripts"> & { scripts?: Record<string, string> } {
99
+ const groups = typePackages(type);
100
+ return groups;
63
101
  }
@@ -1,12 +1,12 @@
1
- import { mkdir, writeFile } from 'node:fs/promises'
2
- import path from 'node:path'
1
+ import { copyFile, mkdir, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
3
 
4
- import { collectBootBindings, resolveAddons } from '../addons/registry.js'
5
- import { indexTemplate, taserTsTemplate } from '../frameworks/index.js'
6
- import { installPackages, resolveUserAgent } from './package-manager.js'
7
- import { writeProjectConfig } from './project-config.js'
8
- import { resolvePackages } from './resolve-packages.js'
9
- import type { ScaffoldOptions, ScaffoldResult } from './types.js'
4
+ import { collectBootBindings, resolveAddons } from "../addons/registry.js";
5
+ import { indexTemplate, taserTsTemplate } from "../frameworks/index.js";
6
+ import { installPackages, resolveUserAgent } from "./package-manager.js";
7
+ import { writeProjectConfig } from "./project-config.js";
8
+ import { resolvePackages } from "./resolve-packages.js";
9
+ import type { ScaffoldOptions, ScaffoldResult } from "./types.js";
10
10
  import {
11
11
  contextTemplate,
12
12
  gitignoreTemplate,
@@ -17,69 +17,139 @@ import {
17
17
  starterManifestTemplate,
18
18
  tsconfigTemplate,
19
19
  tsdownConfigTemplate,
20
- } from '../templates/base.js'
20
+ } from "../templates/base.js";
21
21
 
22
22
  async function write(filePath: string, contents: string): Promise<void> {
23
- await mkdir(path.dirname(filePath), { recursive: true })
24
- await writeFile(filePath, contents, 'utf8')
23
+ await mkdir(path.dirname(filePath), { recursive: true });
24
+ await writeFile(filePath, contents, "utf8");
25
25
  }
26
26
 
27
27
  export async function scaffoldProject(options: ScaffoldOptions): Promise<ScaffoldResult> {
28
- const root = options.targetDir
28
+ const root = options.targetDir;
29
29
  const ctx = {
30
30
  projectName: options.projectName,
31
31
  targetDir: root,
32
- framework: options.framework,
32
+ type: options.type,
33
33
  ...(options.db ? { db: options.db, driver: options.driver } : {}),
34
34
  ...(options.logger ? { logger: options.logger } : {}),
35
35
  ...(options.validator ? { validator: options.validator } : {}),
36
+ };
37
+
38
+ const addons = resolveAddons(ctx);
39
+ const packages = resolvePackages(ctx);
40
+ const bootBindings = collectBootBindings(ctx);
41
+
42
+ await write(
43
+ path.join(root, "package.json"),
44
+ packageJsonTemplate(options.projectName, packages.scripts),
45
+ );
46
+ await write(path.join(root, "tsconfig.json"), tsconfigTemplate());
47
+ await write(path.join(root, "tsdown.config.ts"), tsdownConfigTemplate());
48
+ await write(path.join(root, ".gitignore"), gitignoreTemplate());
49
+ await write(path.join(root, "src/context.ts"), contextTemplate(bootBindings));
50
+ await write(path.join(root, "src/taser.ts"), taserTsTemplate(options.type));
51
+ await write(path.join(root, "src/index.ts"), indexTemplate(options.type));
52
+ await write(path.join(root, "src/routes/$.ts"), rootLayoutTemplate());
53
+ await write(path.join(root, "src/routes/index.get.ts"), indexRouteTemplate());
54
+ await write(path.join(root, "src/routes/health.get.ts"), healthRouteTemplate(ctx));
55
+ await write(path.join(root, "src/routeManifest.gen.ts"), starterManifestTemplate());
56
+
57
+ if (options.type === "cloudflare-workers") {
58
+ await write(
59
+ path.join(root, "wrangler.jsonc"),
60
+ JSON.stringify(
61
+ {
62
+ $schema: "node_modules/wrangler/config-schema.json",
63
+ name: options.projectName,
64
+ main: "src/index.ts",
65
+ compatibility_date: "2024-11-01",
66
+ },
67
+ null,
68
+ 2,
69
+ ) + "\n",
70
+ );
36
71
  }
37
72
 
38
- const addons = resolveAddons(ctx)
39
- const packages = resolvePackages(ctx)
40
- const bootBindings = collectBootBindings(ctx)
73
+ if (options.type === "vercel") {
74
+ await write(
75
+ path.join(root, "vercel.json"),
76
+ JSON.stringify(
77
+ {
78
+ rewrites: [{ source: "/(.*)", destination: "/src/index.ts" }],
79
+ },
80
+ null,
81
+ 2,
82
+ ) + "\n",
83
+ );
84
+ }
41
85
 
42
- await write(path.join(root, 'package.json'), packageJsonTemplate(options.projectName, packages.scripts))
43
- await write(path.join(root, 'tsconfig.json'), tsconfigTemplate())
44
- await write(path.join(root, 'tsdown.config.ts'), tsdownConfigTemplate())
45
- await write(path.join(root, '.gitignore'), gitignoreTemplate())
46
- await write(path.join(root, 'src/context.ts'), contextTemplate(bootBindings))
47
- await write(path.join(root, 'src/taser.ts'), taserTsTemplate(options.framework))
48
- await write(path.join(root, 'src/index.ts'), indexTemplate(options.framework))
49
- await write(path.join(root, 'src/routes/$.ts'), rootLayoutTemplate())
50
- await write(path.join(root, 'src/routes/index.get.ts'), indexRouteTemplate())
51
- await write(path.join(root, 'src/routes/health.get.ts'), healthRouteTemplate(ctx))
52
- await write(path.join(root, 'src/routeManifest.gen.ts'), starterManifestTemplate())
86
+ if (options.type === "azure-functions") {
87
+ await write(
88
+ path.join(root, "host.json"),
89
+ JSON.stringify(
90
+ {
91
+ version: "2.0",
92
+ logging: {
93
+ applicationInsights: {
94
+ samplingSettings: {
95
+ isEnabled: true,
96
+ excludedTypes: "Request",
97
+ },
98
+ },
99
+ },
100
+ extensionBundle: {
101
+ id: "Microsoft.Azure.Functions.ExtensionBundle",
102
+ version: "[4.*, 5.0.0)",
103
+ },
104
+ extensions: {
105
+ http: {
106
+ routePrefix: "",
107
+ },
108
+ },
109
+ },
110
+ null,
111
+ 2,
112
+ ) + "\n",
113
+ );
114
+ }
115
+
116
+ await Promise.all(
117
+ addons.map(async (addon) => {
118
+ await addon.apply(ctx, (filePath, contents) => write(path.join(root, filePath), contents));
119
+ }),
120
+ );
53
121
 
54
- for (const addon of addons) {
55
- await addon.apply(ctx, (filePath, contents) => write(path.join(root, filePath), contents))
122
+ try {
123
+ await copyFile(path.join(root, ".env.example"), path.join(root, ".env"));
124
+ } catch {
125
+ // .env.example was not created
56
126
  }
57
127
 
58
- await writeProjectConfig(root, ctx)
128
+ await writeProjectConfig(root, ctx);
59
129
 
60
130
  if (options.skipInstall) {
61
131
  return {
62
132
  projectName: ctx.projectName,
63
133
  targetDir: root,
64
- framework: ctx.framework,
134
+ type: ctx.type,
65
135
  ...(ctx.db ? { db: ctx.db, driver: ctx.driver } : {}),
66
136
  ...(ctx.logger ? { logger: ctx.logger } : {}),
67
137
  ...(ctx.validator ? { validator: ctx.validator } : {}),
68
- }
138
+ };
69
139
  }
70
140
 
71
- const agent = options.agent ?? resolveUserAgent()
141
+ const agent = options.agent ?? resolveUserAgent();
72
142
  await installPackages(agent, root, {
73
143
  dependencies: packages.dependencies,
74
144
  devDependencies: packages.devDependencies,
75
- })
145
+ });
76
146
 
77
147
  return {
78
148
  projectName: ctx.projectName,
79
149
  targetDir: root,
80
- framework: ctx.framework,
150
+ type: ctx.type,
81
151
  ...(ctx.db ? { db: ctx.db, driver: ctx.driver } : {}),
82
152
  ...(ctx.logger ? { logger: ctx.logger } : {}),
83
153
  ...(ctx.validator ? { validator: ctx.validator } : {}),
84
- }
154
+ };
85
155
  }
package/src/core/types.ts CHANGED
@@ -1,57 +1,82 @@
1
- import type { Agent } from 'package-manager-detector'
1
+ import type { Agent } from "package-manager-detector";
2
2
 
3
- export type Framework = 'node' | 'express' | 'hono' | 'fastify'
3
+ export type ProjectType =
4
+ | "node"
5
+ | "express"
6
+ | "fastify"
7
+ | "hono"
8
+ | "bun"
9
+ | "deno"
10
+ | "aws-lambda"
11
+ | "cloudflare-workers"
12
+ | "netlify"
13
+ | "vercel"
14
+ | "azure-functions"
15
+ | "google-cloud-run";
4
16
 
5
- export const FRAMEWORKS: readonly Framework[] = ['node', 'express', 'hono', 'fastify']
17
+ export const PROJECT_TYPES: readonly ProjectType[] = [
18
+ "node",
19
+ "express",
20
+ "fastify",
21
+ "hono",
22
+ "bun",
23
+ "deno",
24
+ "aws-lambda",
25
+ "cloudflare-workers",
26
+ "netlify",
27
+ "vercel",
28
+ "azure-functions",
29
+ "google-cloud-run",
30
+ ];
6
31
 
7
- export type DbOdm = 'drizzle' | 'prisma' | 'kysely'
32
+ export type DbOdm = "drizzle" | "prisma" | "kysely";
8
33
 
9
- export const DB_ODMS: readonly DbOdm[] = ['drizzle', 'prisma', 'kysely']
34
+ export const DB_ODMS: readonly DbOdm[] = ["drizzle", "prisma", "kysely"];
10
35
 
11
- export type DbDriver = 'postgres' | 'sqlite' | 'mysql'
36
+ export type DbDriver = "postgres" | "sqlite" | "mysql";
12
37
 
13
- export const DB_DRIVERS: readonly DbDriver[] = ['postgres', 'sqlite', 'mysql']
38
+ export const DB_DRIVERS: readonly DbDriver[] = ["postgres", "sqlite", "mysql"];
14
39
 
15
- export const DEFAULT_DB_DRIVER: DbDriver = 'sqlite'
40
+ export const DEFAULT_DB_DRIVER: DbDriver = "sqlite";
16
41
 
17
- export type LoggerId = 'pino' | 'winston'
42
+ export type LoggerId = "pino" | "winston";
18
43
 
19
- export const LOGGERS: readonly LoggerId[] = ['pino', 'winston']
44
+ export const LOGGERS: readonly LoggerId[] = ["pino", "winston"];
20
45
 
21
- export type ValidatorId = 'zod' | 'arktype' | 'valibot'
46
+ export type ValidatorId = "zod" | "arktype" | "valibot";
22
47
 
23
- export const VALIDATORS: readonly ValidatorId[] = ['zod', 'arktype', 'valibot']
48
+ export const VALIDATORS: readonly ValidatorId[] = ["zod", "arktype", "valibot"];
24
49
 
25
50
  export type PackageGroups = {
26
- dependencies: string[]
27
- devDependencies: string[]
28
- scripts: Record<string, string>
29
- }
51
+ dependencies: string[];
52
+ devDependencies: string[];
53
+ scripts: Record<string, string>;
54
+ };
30
55
 
31
56
  export type ScaffoldContext = {
32
- projectName: string
33
- targetDir: string
34
- framework: Framework
35
- db?: DbOdm
36
- driver?: DbDriver
37
- logger?: LoggerId
38
- validator?: ValidatorId
39
- }
57
+ projectName: string;
58
+ targetDir: string;
59
+ type: ProjectType;
60
+ db?: DbOdm;
61
+ driver?: DbDriver;
62
+ logger?: LoggerId;
63
+ validator?: ValidatorId;
64
+ };
40
65
 
41
66
  export type ScaffoldOptions = ScaffoldContext & {
42
- skipInstall?: boolean
43
- agent?: Agent
44
- }
67
+ skipInstall?: boolean;
68
+ agent?: Agent;
69
+ };
45
70
 
46
- export type ScaffoldResult = ScaffoldContext
71
+ export type ScaffoldResult = ScaffoldContext;
47
72
 
48
73
  export type CapabilitiesCatalog = {
49
- frameworks: Framework[]
74
+ types: ProjectType[];
50
75
  db: {
51
- odms: DbOdm[]
52
- drivers: DbDriver[]
53
- defaultDriver: DbDriver
54
- }
55
- loggers: LoggerId[]
56
- validators: ValidatorId[]
57
- }
76
+ odms: DbOdm[];
77
+ drivers: DbDriver[];
78
+ defaultDriver: DbDriver;
79
+ };
80
+ loggers: LoggerId[];
81
+ validators: ValidatorId[];
82
+ };