create-taserjs 0.0.5 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/addons/registry.cjs +3 -4
  3. package/dist/cjs/addons/registry.cjs.map +1 -1
  4. package/dist/cjs/addons/validators.cjs +10 -13
  5. package/dist/cjs/addons/validators.cjs.map +1 -1
  6. package/dist/cjs/cli.cjs +7 -5
  7. package/dist/cjs/cli.cjs.map +1 -1
  8. package/dist/cjs/commands/create.cjs +68 -48
  9. package/dist/cjs/commands/create.cjs.map +1 -1
  10. package/dist/cjs/commands/create.d.cts +2 -1
  11. package/dist/cjs/core/parse-options.cjs +48 -22
  12. package/dist/cjs/core/parse-options.cjs.map +1 -1
  13. package/dist/cjs/core/parse-options.d.cts +19 -4
  14. package/dist/cjs/core/project-config.cjs +5 -1
  15. package/dist/cjs/core/project-config.cjs.map +1 -1
  16. package/dist/cjs/core/resolve-packages.cjs +28 -66
  17. package/dist/cjs/core/resolve-packages.cjs.map +1 -1
  18. package/dist/cjs/core/resolve-packages.d.cts +1 -4
  19. package/dist/cjs/core/scaffold-engine.cjs +18 -49
  20. package/dist/cjs/core/scaffold-engine.cjs.map +1 -1
  21. package/dist/cjs/core/targets.cjs +162 -0
  22. package/dist/cjs/core/targets.cjs.map +1 -0
  23. package/dist/cjs/core/targets.d.cts +49 -0
  24. package/dist/cjs/core/types.cjs +21 -11
  25. package/dist/cjs/core/types.cjs.map +1 -1
  26. package/dist/cjs/core/types.d.cts +20 -4
  27. package/dist/cjs/frameworks/index.cjs +76 -194
  28. package/dist/cjs/frameworks/index.cjs.map +1 -1
  29. package/dist/cjs/frameworks/index.d.cts +18 -3
  30. package/dist/cjs/scaffold.d.cts +2 -2
  31. package/dist/cjs/templates/base.cjs +15 -99
  32. package/dist/cjs/templates/base.cjs.map +1 -1
  33. package/dist/cjs/templates/base.d.cts +0 -3
  34. package/dist/cjs/types.d.cts +1 -1
  35. package/dist/esm/addons/registry.js +4 -5
  36. package/dist/esm/addons/registry.js.map +1 -1
  37. package/dist/esm/addons/validators.js +10 -13
  38. package/dist/esm/addons/validators.js.map +1 -1
  39. package/dist/esm/cli.js +7 -5
  40. package/dist/esm/cli.js.map +1 -1
  41. package/dist/esm/commands/create.d.ts +2 -1
  42. package/dist/esm/commands/create.js +70 -50
  43. package/dist/esm/commands/create.js.map +1 -1
  44. package/dist/esm/core/parse-options.d.ts +19 -4
  45. package/dist/esm/core/parse-options.js +47 -23
  46. package/dist/esm/core/parse-options.js.map +1 -1
  47. package/dist/esm/core/project-config.js +5 -1
  48. package/dist/esm/core/project-config.js.map +1 -1
  49. package/dist/esm/core/resolve-packages.d.ts +1 -4
  50. package/dist/esm/core/resolve-packages.js +28 -66
  51. package/dist/esm/core/resolve-packages.js.map +1 -1
  52. package/dist/esm/core/scaffold-engine.js +20 -51
  53. package/dist/esm/core/scaffold-engine.js.map +1 -1
  54. package/dist/esm/core/targets.d.ts +49 -0
  55. package/dist/esm/core/targets.js +157 -0
  56. package/dist/esm/core/targets.js.map +1 -0
  57. package/dist/esm/core/types.d.ts +20 -4
  58. package/dist/esm/core/types.js +19 -11
  59. package/dist/esm/core/types.js.map +1 -1
  60. package/dist/esm/frameworks/index.d.ts +18 -3
  61. package/dist/esm/frameworks/index.js +73 -194
  62. package/dist/esm/frameworks/index.js.map +1 -1
  63. package/dist/esm/scaffold.d.ts +2 -2
  64. package/dist/esm/templates/base.d.ts +0 -3
  65. package/dist/esm/templates/base.js +16 -98
  66. package/dist/esm/templates/base.js.map +1 -1
  67. package/dist/esm/types.d.ts +1 -1
  68. package/package.json +3 -2
  69. package/src/addons/registry.ts +6 -17
  70. package/src/addons/validators.ts +10 -13
  71. package/src/cli.ts +6 -4
  72. package/src/commands/create.ts +82 -26
  73. package/src/core/parse-options.ts +84 -35
  74. package/src/core/project-config.ts +6 -1
  75. package/src/core/resolve-packages.ts +38 -76
  76. package/src/core/scaffold-engine.ts +43 -81
  77. package/src/core/targets.ts +202 -0
  78. package/src/core/types.ts +38 -24
  79. package/src/frameworks/index.ts +75 -211
  80. package/src/scaffold.ts +2 -2
  81. package/src/templates/base.ts +14 -98
  82. package/src/types.ts +3 -1
@@ -1,246 +1,110 @@
1
- import type { ProjectType } from "../core/types.js";
1
+ import type { Framework } from "../core/types.js";
2
2
 
3
- export function indexTemplate(type: ProjectType): string {
4
- switch (type) {
5
- case "express":
6
- return `import 'dotenv/config'
3
+ export function serverEntryTemplate(
4
+ framework: Framework,
5
+ ): { fileName: string; content: string } | null {
6
+ switch (framework) {
7
+ case "hono":
8
+ return {
9
+ fileName: "src/server.ts",
10
+ content: `import { Hono } from 'hono'
7
11
 
8
- import express from 'express'
9
- import { createExpressHandler } from '@taserjs/adapter-express'
12
+ const app = new Hono()
10
13
 
11
- import { routeManifest } from '#src/routeManifest.gen.js'
12
- import { t } from '#src/taser.js'
14
+ app.get('/host', (c) => {
15
+ return c.text('Hello from Hono host!')
16
+ })
13
17
 
14
- const router = t.create(routeManifest)
18
+ export default app
19
+ `,
20
+ };
21
+ case "express":
22
+ return {
23
+ fileName: "src/server.node.ts",
24
+ content: `import express from 'express'
15
25
 
16
- const taser = createExpressHandler(router)
17
26
  const app = express()
18
- taser.mount('/{*splat}', app)
19
27
 
20
- const port = Number(process.env.PORT ?? 3000)
21
- app.listen(port, () => {
22
- console.log(\`Express listening on http://localhost:\${port}\`)
28
+ app.get('/host', (_req, res) => {
29
+ res.json({ message: 'Hello from Express host!' })
23
30
  })
24
- `;
25
- case "hono":
26
- return `import 'dotenv/config'
27
-
28
- import { serve } from '@hono/node-server'
29
- import { Hono } from 'hono'
30
-
31
- import { routeManifest } from '#src/routeManifest.gen.js'
32
- import { t } from '#src/taser.js'
33
-
34
- const router = t.create(routeManifest)
35
31
 
36
- const app = new Hono()
37
- app.all('/*', c => router.native(c).fetch(c.req.raw))
38
-
39
- const port = Number(process.env.PORT ?? 3000)
40
- serve({ fetch: app.fetch, port }, () => {
41
- console.log(\`Hono listening on http://localhost:\${port}\`)
42
- })
43
- `;
32
+ export default app
33
+ `,
34
+ };
44
35
  case "fastify":
45
- return `import 'dotenv/config'
46
-
47
- import Fastify from 'fastify'
48
- import { createFastifyHandler } from '@taserjs/adapter-fastify'
36
+ return {
37
+ fileName: "src/server.node.ts",
38
+ content: `import Fastify from 'fastify'
49
39
 
50
- import { routeManifest } from '#src/routeManifest.gen.js'
51
- import { t } from '#src/taser.js'
52
-
53
- const router = t.create(routeManifest)
54
-
55
- const taser = createFastifyHandler(router)
56
40
  const app = Fastify()
57
- taser.mount('/*', app)
58
-
59
- const port = Number(process.env.PORT ?? 3000)
60
- await app.listen({ port })
61
- console.log(\`Fastify listening on http://localhost:\${port}\`)
62
- `;
63
- case "bun":
64
- return `import 'dotenv/config'
65
-
66
- import { routeManifest } from '#src/routeManifest.gen.js'
67
- import { t } from '#src/taser.js'
68
41
 
69
- const router = t.create(routeManifest)
42
+ app.get('/host', async () => {
43
+ return { message: 'Hello from Fastify host!' }
44
+ })
70
45
 
71
- const port = Number(process.env.PORT ?? 3000)
46
+ await app.ready()
72
47
 
73
- export default {
74
- port,
75
- fetch(request: Request) {
76
- return router.fetch(request)
77
- },
48
+ export default app.routing
49
+ `,
50
+ };
51
+ default:
52
+ return null;
53
+ }
78
54
  }
79
- `;
80
- case "deno":
81
- return `import 'dotenv/config'
82
-
83
- import { routeManifest } from '#src/routeManifest.gen.js'
84
- import { t } from '#src/taser.js'
85
-
86
- const router = t.create(routeManifest)
87
-
88
- const port = Number(process.env.PORT ?? 8000)
89
- Deno.serve({ port }, (request: Request) => router.fetch(request))
90
- `;
91
- case "aws-lambda":
92
- return `import 'dotenv/config'
93
-
94
- import { Hono } from 'hono'
95
- import { handle } from 'hono/aws-lambda'
96
55
 
97
- import { routeManifest } from '#src/routeManifest.gen.js'
98
- import { t } from '#src/taser.js'
99
-
100
- const router = t.create(routeManifest)
101
-
102
- const app = new Hono()
103
- app.all('/*', c => router.native(c).fetch(c.req.raw))
104
-
105
- export const handler = handle(app)
106
- `;
107
- case "cloudflare-workers":
108
- return `import 'dotenv/config'
109
-
110
- import { routeManifest } from '#src/routeManifest.gen.js'
111
- import { t } from '#src/taser.js'
112
-
113
- const router = t.create(routeManifest)
114
-
115
- export default {
116
- fetch(request: Request, env: unknown, ctx: unknown) {
117
- return router.fetch(request, env, ctx)
56
+ export type FrameworkEntry = {
57
+ id: Framework;
58
+ serverEntry: { fileName: string; content: string } | null;
59
+ deps: string[];
60
+ devDeps: string[];
61
+ };
62
+
63
+ export const FRAMEWORK_ENTRIES: Record<Framework, FrameworkEntry> = {
64
+ none: { id: "none", serverEntry: null, deps: [], devDeps: [] },
65
+ hono: { id: "hono", serverEntry: serverEntryTemplate("hono"), deps: ["hono"], devDeps: [] },
66
+ express: {
67
+ id: "express",
68
+ serverEntry: serverEntryTemplate("express"),
69
+ deps: ["express", "srvx"],
70
+ devDeps: ["@types/express"],
118
71
  },
119
- }
120
- `;
121
- case "netlify":
122
- return `import 'dotenv/config'
123
-
124
- import { Hono } from 'hono'
125
- import { handle } from 'hono/netlify'
126
-
127
- import { routeManifest } from '#src/routeManifest.gen.js'
128
- import { t } from '#src/taser.js'
129
-
130
- const router = t.create(routeManifest)
131
-
132
- const app = new Hono()
133
- app.all('/*', c => router.native(c).fetch(c.req.raw))
134
-
135
- export default handle(app)
136
- `;
137
- case "vercel":
138
- return `import 'dotenv/config'
139
-
140
- import { Hono } from 'hono'
141
- import { handle } from 'hono/vercel'
142
-
143
- import { routeManifest } from '#src/routeManifest.gen.js'
144
- import { t } from '#src/taser.js'
145
-
146
- const router = t.create(routeManifest)
147
-
148
- const app = new Hono()
149
- app.all('/*', c => router.native(c).fetch(c.req.raw))
150
-
151
- export default handle(app)
152
- `;
153
- case "azure-functions":
154
- return `import 'dotenv/config'
155
-
156
- import { app } from '@azure/functions'
157
- import { Hono } from 'hono'
158
- import { azureHonoHandler } from '@marplex/hono-azurefunc-adapter'
159
-
160
- import { routeManifest } from '#src/routeManifest.gen.js'
161
- import { t } from '#src/taser.js'
162
-
163
- const router = t.create(routeManifest)
164
-
165
- const honoApp = new Hono()
166
- honoApp.all('/*', c => router.native(c).fetch(c.req.raw))
167
-
168
- app.http('httpTrigger', {
169
- methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'],
170
- authLevel: 'anonymous',
171
- route: '{*proxy}',
172
- handler: azureHonoHandler(honoApp.fetch),
173
- })
174
- `;
175
- case "google-cloud-run":
176
- return `import 'dotenv/config'
177
-
178
- import { serve } from '@hono/node-server'
179
-
180
- import { routeManifest } from '#src/routeManifest.gen.js'
181
- import { t } from '#src/taser.js'
72
+ fastify: {
73
+ id: "fastify",
74
+ // srvx bridges the Fastify Node handler to fetch (see compose codegen).
75
+ serverEntry: serverEntryTemplate("fastify"),
76
+ deps: ["fastify", "srvx"],
77
+ devDeps: [],
78
+ },
79
+ };
182
80
 
183
- const router = t.create(routeManifest)
81
+ export function nitroConfigTemplate(nitroPreset: string): string {
82
+ return `import { defineConfig } from 'nitro/config'
184
83
 
185
- const port = Number(process.env.PORT ?? 8080)
186
- serve({ fetch: router.fetch, port }, () => {
187
- console.log(\`Cloud Run listening on http://localhost:\${port}\`)
84
+ export default defineConfig({
85
+ preset: '${nitroPreset}',
188
86
  })
189
87
  `;
190
- case "node":
191
- default:
192
- return `import 'dotenv/config'
193
-
194
- import { serve } from '@hono/node-server'
195
-
196
- import { routeManifest } from '#src/routeManifest.gen.js'
197
- import { t } from '#src/taser.js'
88
+ }
198
89
 
199
- const router = t.create(routeManifest)
90
+ export function viteConfigTemplate(): string {
91
+ return `import { defineConfig } from 'vite'
92
+ import { nitro } from 'nitro/vite'
93
+ import { taser } from '@taserjs/router-plugin/vite'
200
94
 
201
- const port = Number(process.env.PORT ?? 3000)
202
- serve({ fetch: router.fetch, port }, () => {
203
- console.log(\`Node listening on http://localhost:\${port}\`)
95
+ export default defineConfig({
96
+ plugins: [taser(), nitro()],
204
97
  })
205
98
  `;
206
- }
207
- }
208
-
209
- export function taserTsTemplate(type: ProjectType = "node"): string {
210
- if (
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
99
  }
227
100
 
228
- export const t = createTaserApp({
229
- response: { validate: true },
230
- }).context(context)
231
-
232
- export type AppContext = InferAppContext<typeof context>
233
- `;
234
- }
101
+ export function taserTsTemplate(): string {
102
+ return `import { createTaserApp } from '@taserjs/router'
235
103
 
236
- return `import { createTaserApp, type InferAppContext } from '@taserjs/router'
237
-
238
- import { context } from '#src/context.js'
104
+ import { context } from './context.js'
239
105
 
240
106
  export const t = createTaserApp({
241
107
  response: { validate: true },
242
108
  }).context(context)
243
-
244
- export type AppContext = InferAppContext<typeof context>
245
109
  `;
246
110
  }
package/src/scaffold.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { scaffoldProject } from "./core/scaffold-engine.js";
2
- export { getPackageGroups, resolvePackages } from "./core/resolve-packages.js";
3
- export type { PackageGroups, ProjectType, ScaffoldOptions, ScaffoldResult } from "./core/types.js";
2
+ export { resolvePackages } from "./core/resolve-packages.js";
3
+ export type { PackageGroups, ScaffoldOptions, ScaffoldResult } from "./core/types.js";
@@ -11,16 +11,11 @@ export function packageJsonTemplate(
11
11
  private: true,
12
12
  type: "module",
13
13
  imports: {
14
- "#src/*": "./src/*",
14
+ "#taserjs/router": "./src/taser.ts",
15
15
  },
16
16
  scripts: {
17
- dev: "run-p dev:server dev:taser",
18
- "dev:server": "tsx watch src/index.ts",
19
- "dev:taser": "taser watch",
20
- start: "tsx src/index.ts",
21
- generate: "taser generate",
22
- build: "taser generate && tsdown",
23
- serve: "node dist/index.mjs",
17
+ dev: "vite",
18
+ build: "vite build",
24
19
  typecheck: "tsc --noEmit -p tsconfig.json",
25
20
  ...scripts,
26
21
  },
@@ -29,19 +24,6 @@ export function packageJsonTemplate(
29
24
  return `${JSON.stringify(pkg, null, 2)}\n`;
30
25
  }
31
26
 
32
- export function tsdownConfigTemplate(): string {
33
- return `import { defineConfig } from 'tsdown'
34
-
35
- export default defineConfig({
36
- entry: ['./src/index.ts'],
37
- platform: 'node',
38
- outDir: 'dist',
39
- clean: true,
40
- sourcemap: true,
41
- })
42
- `;
43
- }
44
-
45
27
  export function tsconfigTemplate(): string {
46
28
  return `${JSON.stringify(
47
29
  {
@@ -49,16 +31,15 @@ export function tsconfigTemplate(): string {
49
31
  target: "ES2022",
50
32
  module: "NodeNext",
51
33
  paths: {
52
- "#src/*": ["./src/*"],
34
+ "#taserjs/router": ["./src/taser.ts"],
53
35
  },
54
36
  strict: true,
55
37
  skipLibCheck: true,
56
38
  verbatimModuleSyntax: true,
57
39
  isolatedModules: true,
58
40
  noEmit: true,
59
- types: ["node"],
60
41
  },
61
- include: ["src"],
42
+ include: ["src", ".taser/types/**/*.d.ts"],
62
43
  },
63
44
  null,
64
45
  2,
@@ -68,6 +49,8 @@ export function tsconfigTemplate(): string {
68
49
  export function gitignoreTemplate(): string {
69
50
  return `node_modules
70
51
  dist
52
+ .output
53
+ .taser
71
54
  .DS_Store
72
55
  *.log
73
56
  .env
@@ -104,7 +87,7 @@ ${bootBlock}
104
87
  export function rootLayoutTemplate(): string {
105
88
  return `import { cors } from '@taserjs/router/cors'
106
89
 
107
- import { t } from '#src/taser.js'
90
+ import { t } from '#taserjs/router'
108
91
 
109
92
  export const Middleware = t.middleware('/$')
110
93
  .use(cors())
@@ -112,14 +95,14 @@ export const Middleware = t.middleware('/$')
112
95
  }
113
96
 
114
97
  export function indexRouteTemplate(): string {
115
- return `import { reply } from '@taserjs/router'
116
- import { t } from '#src/taser.js'
98
+ return `import { json } from '@taserjs/router/reply'
99
+ import { t } from '#taserjs/router'
117
100
 
118
101
  const GET = t.get('/')
119
102
 
120
103
  export type RouteContext = typeof GET.$Infer.Context
121
104
  export const Route = GET.handler((_ctx) => {
122
- return reply.json({ message: 'Welcome to Taser' })
105
+ return json({ message: 'Welcome to Taser' })
123
106
  })
124
107
  `;
125
108
  }
@@ -138,81 +121,14 @@ export function healthRouteTemplate(ctx: ScaffoldContext): string {
138
121
  const body = lines.length > 0 ? `${lines.join("\n")}\n` : "";
139
122
  const ctxArg = lines.length > 0 ? "(ctx)" : "(_ctx)";
140
123
 
141
- return `import { reply } from '@taserjs/router'
142
- import { t } from '#src/taser.js'
124
+ return `import { json } from '@taserjs/router/reply'
125
+ import { t } from '#taserjs/router'
143
126
 
144
127
  const GET = t.get('/health')
145
128
 
146
129
  export type RouteContext = typeof GET.$Infer.Context
147
130
  export const Route = GET.handler(${ctxArg} => {
148
- ${body} return reply.json({ ok: true })
131
+ ${body} return json({ ok: true })
149
132
  })
150
133
  `;
151
134
  }
152
-
153
- /** Minimal placeholder until `taser generate` runs. */
154
- export function starterManifestTemplate(): string {
155
- return `/* eslint-disable */
156
- // Run \`pnpm generate\` (taser generate) to replace this file.
157
- import { Middleware as RootSplatLayoutImport } from './routes/$.js'
158
- import { Route as RootIndexGetRouteImport } from './routes/index.get.js'
159
- import { Route as HealthGetRouteImport } from './routes/health.get.js'
160
-
161
- export const routeManifest = {
162
- layouts: {
163
- '/$': {
164
- middlewares: RootSplatLayoutImport,
165
- },
166
- },
167
- routes: {
168
- '/': {
169
- GET: {
170
- layoutChain: ['/$'],
171
- route: RootIndexGetRouteImport,
172
- },
173
- },
174
- '/health': {
175
- GET: {
176
- layoutChain: ['/$'],
177
- route: HealthGetRouteImport,
178
- },
179
- },
180
- },
181
- } as const
182
-
183
- export type RoutePathGen = '/' | '/health'
184
- export type LayoutIdGen = '/$'
185
- export type LayoutTreeGen = {
186
- '/$': {
187
- parent: null
188
- middlewares: typeof RootSplatLayoutImport
189
- }
190
- }
191
- export type RouteByPathMethodGen = {
192
- '/': {
193
- GET: {
194
- parent: '/$'
195
- layoutChain: ['/$']
196
- route: typeof RootIndexGetRouteImport
197
- }
198
- }
199
- '/health': {
200
- GET: {
201
- parent: '/$'
202
- layoutChain: ['/$']
203
- route: typeof HealthGetRouteImport
204
- }
205
- }
206
- }
207
- export type RouteManifest = typeof routeManifest
208
-
209
- declare module '@taserjs/router' {
210
- interface RouterRegister {
211
- RoutePath: RoutePathGen
212
- LayoutId: LayoutIdGen
213
- LayoutTree: LayoutTreeGen
214
- RouteByPathMethod: RouteByPathMethodGen
215
- }
216
- }
217
- `;
218
- }
package/src/types.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  export type {
2
2
  DbDriver,
3
3
  DbOdm,
4
+ DeployTarget,
5
+ Framework,
4
6
  LoggerId,
5
7
  PackageGroups,
6
- ProjectType,
8
+ Runtime,
7
9
  ScaffoldOptions,
8
10
  ScaffoldResult,
9
11
  ValidatorId,