@typokit/cli 0.1.4

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 (64) hide show
  1. package/dist/bin.d.ts +3 -0
  2. package/dist/bin.d.ts.map +1 -0
  3. package/dist/bin.js +13 -0
  4. package/dist/bin.js.map +1 -0
  5. package/dist/commands/build.d.ts +42 -0
  6. package/dist/commands/build.d.ts.map +1 -0
  7. package/dist/commands/build.js +302 -0
  8. package/dist/commands/build.js.map +1 -0
  9. package/dist/commands/dev.d.ts +106 -0
  10. package/dist/commands/dev.d.ts.map +1 -0
  11. package/dist/commands/dev.js +536 -0
  12. package/dist/commands/dev.js.map +1 -0
  13. package/dist/commands/generate.d.ts +65 -0
  14. package/dist/commands/generate.d.ts.map +1 -0
  15. package/dist/commands/generate.js +430 -0
  16. package/dist/commands/generate.js.map +1 -0
  17. package/dist/commands/inspect.d.ts +26 -0
  18. package/dist/commands/inspect.d.ts.map +1 -0
  19. package/dist/commands/inspect.js +579 -0
  20. package/dist/commands/inspect.js.map +1 -0
  21. package/dist/commands/migrate.d.ts +70 -0
  22. package/dist/commands/migrate.d.ts.map +1 -0
  23. package/dist/commands/migrate.js +570 -0
  24. package/dist/commands/migrate.js.map +1 -0
  25. package/dist/commands/scaffold.d.ts +70 -0
  26. package/dist/commands/scaffold.d.ts.map +1 -0
  27. package/dist/commands/scaffold.js +483 -0
  28. package/dist/commands/scaffold.js.map +1 -0
  29. package/dist/commands/test.d.ts +56 -0
  30. package/dist/commands/test.d.ts.map +1 -0
  31. package/dist/commands/test.js +248 -0
  32. package/dist/commands/test.js.map +1 -0
  33. package/dist/config.d.ts +20 -0
  34. package/dist/config.d.ts.map +1 -0
  35. package/dist/config.js +69 -0
  36. package/dist/config.js.map +1 -0
  37. package/dist/index.d.ts +30 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +245 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/logger.d.ts +12 -0
  42. package/dist/logger.d.ts.map +1 -0
  43. package/dist/logger.js +33 -0
  44. package/dist/logger.js.map +1 -0
  45. package/package.json +33 -0
  46. package/src/bin.ts +22 -0
  47. package/src/commands/build.ts +433 -0
  48. package/src/commands/dev.ts +822 -0
  49. package/src/commands/generate.ts +640 -0
  50. package/src/commands/inspect.ts +885 -0
  51. package/src/commands/migrate.ts +800 -0
  52. package/src/commands/scaffold.ts +627 -0
  53. package/src/commands/test.ts +353 -0
  54. package/src/config.ts +93 -0
  55. package/src/dev.test.ts +285 -0
  56. package/src/env.d.ts +86 -0
  57. package/src/generate.test.ts +304 -0
  58. package/src/index.test.ts +217 -0
  59. package/src/index.ts +397 -0
  60. package/src/inspect.test.ts +411 -0
  61. package/src/logger.ts +49 -0
  62. package/src/migrate.test.ts +205 -0
  63. package/src/scaffold.test.ts +256 -0
  64. package/src/test.test.ts +230 -0
@@ -0,0 +1,70 @@
1
+ import type { CliLogger } from "../logger.js";
2
+ export interface ScaffoldCommandOptions {
3
+ /** Project root directory */
4
+ rootDir: string;
5
+ /** Logger instance */
6
+ logger: CliLogger;
7
+ /** Scaffold subcommand: "init", "route", "service" */
8
+ subcommand: string;
9
+ /** Positional arguments (e.g., route/service name) */
10
+ positional: string[];
11
+ /** CLI flags */
12
+ flags: Record<string, string | boolean>;
13
+ /** Whether verbose mode is enabled */
14
+ verbose: boolean;
15
+ }
16
+ export interface ScaffoldResult {
17
+ /** Whether the command succeeded */
18
+ success: boolean;
19
+ /** Files created */
20
+ filesCreated: string[];
21
+ /** Duration in milliseconds */
22
+ duration: number;
23
+ /** Errors encountered */
24
+ errors: string[];
25
+ }
26
+ export interface InitOptions {
27
+ /** Project name */
28
+ name: string;
29
+ /** Server adapter to use */
30
+ server: "native" | "fastify" | "hono" | "express";
31
+ /** Database adapter to use */
32
+ db: "drizzle" | "kysely" | "prisma" | "raw" | "none";
33
+ }
34
+ /** Generate a route contracts.ts template */
35
+ export declare function generateRouteContracts(name: string): string;
36
+ /** Generate a route handlers.ts template */
37
+ export declare function generateRouteHandlers(name: string): string;
38
+ /** Generate a route middleware.ts template */
39
+ export declare function generateRouteMiddleware(name: string): string;
40
+ /** Generate a service template */
41
+ export declare function generateService(name: string): string;
42
+ /** Generate package.json for a new project */
43
+ export declare function generatePackageJson(options: InitOptions): string;
44
+ /** Generate tsconfig.json for a new project */
45
+ export declare function generateTsconfig(): string;
46
+ /** Generate the main app.ts for a new project */
47
+ export declare function generateAppTs(options: InitOptions): string;
48
+ /** Generate the types.ts seed file for a new project */
49
+ export declare function generateTypesTs(): string;
50
+ /** Convert kebab-case or snake_case name to PascalCase */
51
+ export declare function toPascalCase(name: string): string;
52
+ /** Convert kebab-case or snake_case name to camelCase */
53
+ export declare function toCamelCase(name: string): string;
54
+ /**
55
+ * Execute `typokit init` — create a new project from template.
56
+ */
57
+ export declare function scaffoldInit(rootDir: string, options: InitOptions, logger: CliLogger): Promise<ScaffoldResult>;
58
+ /**
59
+ * Execute `typokit add route <name>` — scaffold a route module.
60
+ */
61
+ export declare function scaffoldRoute(rootDir: string, name: string, logger: CliLogger): Promise<ScaffoldResult>;
62
+ /**
63
+ * Execute `typokit add service <name>` — scaffold a service file.
64
+ */
65
+ export declare function scaffoldService(rootDir: string, name: string, logger: CliLogger): Promise<ScaffoldResult>;
66
+ /**
67
+ * Execute scaffold commands dispatcher.
68
+ */
69
+ export declare function executeScaffold(options: ScaffoldCommandOptions): Promise<ScaffoldResult>;
70
+ //# sourceMappingURL=scaffold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../src/commands/scaffold.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,WAAW,sBAAsB;IACrC,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,sBAAsB;IACtB,MAAM,EAAE,SAAS,CAAC;IAClB,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,gBAAgB;IAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;IACxC,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,oBAAoB;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,yBAAyB;IACzB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;IAClD,8BAA8B;IAC9B,EAAE,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;CACtD;AAED,6CAA6C;AAC7C,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA+B3D;AAED,4CAA4C;AAC5C,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAoD1D;AAED,8CAA8C;AAC9C,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAa5D;AAED,kCAAkC;AAClC,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAoBpD;AAED,8CAA8C;AAC9C,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CA2ChE;AAED,+CAA+C;AAC/C,wBAAgB,gBAAgB,IAAI,MAAM,CAyBzC;AAED,iDAAiD;AACjD,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CA6B1D;AAED,wDAAwD;AACxD,wBAAgB,eAAe,IAAI,MAAM,CAcxC;AAED,0DAA0D;AAC1D,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED,yDAAyD;AACzD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGhD;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,SAAS,GAChB,OAAO,CAAC,cAAc,CAAC,CAuFzB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,SAAS,GAChB,OAAO,CAAC,cAAc,CAAC,CAgFzB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,SAAS,GAChB,OAAO,CAAC,cAAc,CAAC,CAoEzB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,cAAc,CAAC,CA+BzB"}
@@ -0,0 +1,483 @@
1
+ // @typokit/cli — Scaffold Commands (init, add route, add service)
2
+ /** Generate a route contracts.ts template */
3
+ export function generateRouteContracts(name) {
4
+ const pascalName = toPascalCase(name);
5
+ return `// Route contracts for ${name}
6
+ import type { RouteContract } from "@typokit/types";
7
+
8
+ /** ${pascalName} item type */
9
+ export interface ${pascalName} {
10
+ id: string;
11
+ createdAt: string;
12
+ updatedAt: string;
13
+ }
14
+
15
+ /** Create ${pascalName} request body */
16
+ export interface Create${pascalName}Body {
17
+ // TODO: Define create fields
18
+ }
19
+
20
+ /** Update ${pascalName} request body */
21
+ export interface Update${pascalName}Body {
22
+ // TODO: Define update fields
23
+ }
24
+
25
+ /** Route contracts for /${name} */
26
+ export interface ${pascalName}Routes {
27
+ "GET /${name}": RouteContract<Record<string, never>, { limit?: number; offset?: number }, never, ${pascalName}[]>;
28
+ "GET /${name}/:id": RouteContract<{ id: string }, never, never, ${pascalName}>;
29
+ "POST /${name}": RouteContract<Record<string, never>, never, Create${pascalName}Body, ${pascalName}>;
30
+ "PUT /${name}/:id": RouteContract<{ id: string }, never, Update${pascalName}Body, ${pascalName}>;
31
+ "DELETE /${name}/:id": RouteContract<{ id: string }, never, never, void>;
32
+ }
33
+ `;
34
+ }
35
+ /** Generate a route handlers.ts template */
36
+ export function generateRouteHandlers(name) {
37
+ const pascalName = toPascalCase(name);
38
+ return `// Route handlers for ${name}
39
+ import type { RouteHandler, RequestContext } from "@typokit/types";
40
+ import type { ${pascalName}, Create${pascalName}Body, Update${pascalName}Body } from "./contracts.ts";
41
+
42
+ /** List all ${name} */
43
+ export const list${pascalName}: RouteHandler = async (ctx: RequestContext) => {
44
+ const _query = ctx.query as { limit?: number; offset?: number };
45
+ // TODO: Implement list logic
46
+ return { status: 200, body: [] as ${pascalName}[] };
47
+ };
48
+
49
+ /** Get a single ${name} by ID */
50
+ export const get${pascalName}: RouteHandler = async (ctx: RequestContext) => {
51
+ const { id } = ctx.params as { id: string };
52
+ // TODO: Implement get logic
53
+ return { status: 200, body: { id } as ${pascalName} };
54
+ };
55
+
56
+ /** Create a new ${name} */
57
+ export const create${pascalName}: RouteHandler = async (ctx: RequestContext) => {
58
+ const _body = ctx.body as Create${pascalName}Body;
59
+ // TODO: Implement create logic
60
+ return { status: 201, body: {} as ${pascalName} };
61
+ };
62
+
63
+ /** Update an existing ${name} */
64
+ export const update${pascalName}: RouteHandler = async (ctx: RequestContext) => {
65
+ const { id } = ctx.params as { id: string };
66
+ const _body = ctx.body as Update${pascalName}Body;
67
+ // TODO: Implement update logic
68
+ return { status: 200, body: { id } as ${pascalName} };
69
+ };
70
+
71
+ /** Delete a ${name} */
72
+ export const delete${pascalName}: RouteHandler = async (ctx: RequestContext) => {
73
+ const { id } = ctx.params as { id: string };
74
+ // TODO: Implement delete logic
75
+ void id;
76
+ return { status: 204, body: undefined };
77
+ };
78
+
79
+ /** Default export: all handlers for registration in app.ts */
80
+ export default {
81
+ "GET /${name}": list${pascalName},
82
+ "GET /${name}/:id": get${pascalName},
83
+ "POST /${name}": create${pascalName},
84
+ "PUT /${name}/:id": update${pascalName},
85
+ "DELETE /${name}/:id": delete${pascalName},
86
+ };
87
+ `;
88
+ }
89
+ /** Generate a route middleware.ts template */
90
+ export function generateRouteMiddleware(name) {
91
+ return `// Route-specific middleware for ${name}
92
+ import type { MiddlewareFn } from "@typokit/types";
93
+
94
+ /**
95
+ * Example middleware for ${name} routes.
96
+ * Add route-specific middleware here (e.g., authorization, rate limiting).
97
+ */
98
+ export const ${toCamelCase(name)}Middleware: MiddlewareFn = async (ctx, next) => {
99
+ // TODO: Implement route-specific middleware
100
+ return next(ctx);
101
+ };
102
+ `;
103
+ }
104
+ /** Generate a service template */
105
+ export function generateService(name) {
106
+ const pascalName = toPascalCase(name);
107
+ return `// ${pascalName} service — business logic layer
108
+
109
+ /**
110
+ * ${pascalName}Service handles business logic for ${name}.
111
+ * Keep handlers thin — put complex logic here.
112
+ */
113
+ export class ${pascalName}Service {
114
+ /**
115
+ * Example method. Replace with actual business logic.
116
+ */
117
+ async execute(): Promise<void> {
118
+ // TODO: Implement ${name} business logic
119
+ }
120
+ }
121
+
122
+ /** Singleton instance for convenience */
123
+ export const ${toCamelCase(name)}Service = new ${pascalName}Service();
124
+ `;
125
+ }
126
+ /** Generate package.json for a new project */
127
+ export function generatePackageJson(options) {
128
+ const deps = {
129
+ "@typokit/core": "^0.1.0",
130
+ "@typokit/types": "^0.1.0",
131
+ "@typokit/errors": "^0.1.0",
132
+ "@typokit/cli": "^0.1.0",
133
+ };
134
+ if (options.server !== "native") {
135
+ deps[`@typokit/server-${options.server}`] = "^0.1.0";
136
+ }
137
+ else {
138
+ deps["@typokit/server-native"] = "^0.1.0";
139
+ }
140
+ if (options.db !== "none") {
141
+ deps[`@typokit/db-${options.db}`] = "^0.1.0";
142
+ }
143
+ return (JSON.stringify({
144
+ name: options.name,
145
+ version: "0.1.0",
146
+ type: "module",
147
+ private: true,
148
+ scripts: {
149
+ build: "typokit build",
150
+ dev: "typokit dev",
151
+ test: "typokit test",
152
+ "generate:db": "typokit generate:db",
153
+ "generate:client": "typokit generate:client",
154
+ typecheck: "tsc --noEmit",
155
+ },
156
+ dependencies: deps,
157
+ devDependencies: {
158
+ typescript: "^5.7.0",
159
+ "@typokit/transform-native": "^0.1.0",
160
+ },
161
+ }, null, 2) + "\n");
162
+ }
163
+ /** Generate tsconfig.json for a new project */
164
+ export function generateTsconfig() {
165
+ return (JSON.stringify({
166
+ compilerOptions: {
167
+ target: "ES2022",
168
+ module: "NodeNext",
169
+ moduleResolution: "NodeNext",
170
+ allowImportingTsExtensions: true,
171
+ rewriteRelativeImportExtensions: true,
172
+ strict: true,
173
+ esModuleInterop: true,
174
+ skipLibCheck: true,
175
+ outDir: "dist",
176
+ rootDir: "src",
177
+ declaration: true,
178
+ declarationMap: true,
179
+ sourceMap: true,
180
+ },
181
+ include: ["src"],
182
+ }, null, 2) + "\n");
183
+ }
184
+ /** Generate the main app.ts for a new project */
185
+ export function generateAppTs(options) {
186
+ const serverImport = options.server === "native"
187
+ ? `import { nativeServer } from "@typokit/server-native";`
188
+ : `import { ${options.server}Server } from "@typokit/server-${options.server}";`;
189
+ const serverValue = options.server === "native"
190
+ ? "nativeServer()"
191
+ : `${options.server}Server()`;
192
+ return `// Application entry point — explicit route registration
193
+ import { createApp } from "@typokit/core";
194
+ ${serverImport}
195
+
196
+ export const app = createApp({
197
+ server: ${serverValue},
198
+ middleware: [],
199
+ routes: [
200
+ // Register route modules here:
201
+ // { prefix: "/users", handlers: usersHandlers },
202
+ ],
203
+ });
204
+
205
+ // Start the server
206
+ app.listen({ port: 3000 }).then(() => {
207
+ console.log("Server running on http://localhost:3000");
208
+ });
209
+ `;
210
+ }
211
+ /** Generate the types.ts seed file for a new project */
212
+ export function generateTypesTs() {
213
+ return `// Schema type definitions — the single source of truth
214
+ // TypoKit generates validation, DB schema, OpenAPI, and client types from these interfaces.
215
+ // See: https://github.com/typokit/typokit#schema-types
216
+
217
+ /** @table */
218
+ export interface Example {
219
+ /** @id @generated */
220
+ id: string;
221
+ name: string;
222
+ createdAt: string;
223
+ updatedAt: string;
224
+ }
225
+ `;
226
+ }
227
+ /** Convert kebab-case or snake_case name to PascalCase */
228
+ export function toPascalCase(name) {
229
+ return name
230
+ .split(/[-_]/)
231
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
232
+ .join("");
233
+ }
234
+ /** Convert kebab-case or snake_case name to camelCase */
235
+ export function toCamelCase(name) {
236
+ const pascal = toPascalCase(name);
237
+ return pascal.charAt(0).toLowerCase() + pascal.slice(1);
238
+ }
239
+ /**
240
+ * Execute `typokit init` — create a new project from template.
241
+ */
242
+ export async function scaffoldInit(rootDir, options, logger) {
243
+ const start = Date.now();
244
+ const { join } = (await import(/* @vite-ignore */ "path"));
245
+ const { mkdirSync, writeFileSync, existsSync } = (await import(
246
+ /* @vite-ignore */ "fs"));
247
+ const projectDir = join(rootDir, options.name);
248
+ const filesCreated = [];
249
+ const errors = [];
250
+ // Check if directory already exists with content
251
+ if (existsSync(projectDir)) {
252
+ errors.push(`Directory "${options.name}" already exists`);
253
+ return {
254
+ success: false,
255
+ filesCreated,
256
+ duration: Date.now() - start,
257
+ errors,
258
+ };
259
+ }
260
+ try {
261
+ // Create directory structure per Section 4.4
262
+ const dirs = [
263
+ projectDir,
264
+ join(projectDir, "src"),
265
+ join(projectDir, "src", "routes"),
266
+ join(projectDir, "src", "middleware"),
267
+ join(projectDir, "src", "services"),
268
+ ];
269
+ for (const dir of dirs) {
270
+ mkdirSync(dir, { recursive: true });
271
+ }
272
+ // Write package.json
273
+ const pkgPath = join(projectDir, "package.json");
274
+ writeFileSync(pkgPath, generatePackageJson(options));
275
+ filesCreated.push(pkgPath);
276
+ logger.info(`Created ${pkgPath}`);
277
+ // Write tsconfig.json
278
+ const tscPath = join(projectDir, "tsconfig.json");
279
+ writeFileSync(tscPath, generateTsconfig());
280
+ filesCreated.push(tscPath);
281
+ logger.info(`Created ${tscPath}`);
282
+ // Write src/app.ts
283
+ const appPath = join(projectDir, "src", "app.ts");
284
+ writeFileSync(appPath, generateAppTs(options));
285
+ filesCreated.push(appPath);
286
+ logger.info(`Created ${appPath}`);
287
+ // Write src/types.ts
288
+ const typesPath = join(projectDir, "src", "types.ts");
289
+ writeFileSync(typesPath, generateTypesTs());
290
+ filesCreated.push(typesPath);
291
+ logger.info(`Created ${typesPath}`);
292
+ logger.info(`\nProject "${options.name}" created successfully!`);
293
+ logger.info(`\n cd ${options.name}`);
294
+ logger.info(" npm install");
295
+ logger.info(" typokit dev\n");
296
+ return {
297
+ success: true,
298
+ filesCreated,
299
+ duration: Date.now() - start,
300
+ errors,
301
+ };
302
+ }
303
+ catch (err) {
304
+ const msg = err instanceof Error ? err.message : String(err);
305
+ errors.push(msg);
306
+ return {
307
+ success: false,
308
+ filesCreated,
309
+ duration: Date.now() - start,
310
+ errors,
311
+ };
312
+ }
313
+ }
314
+ /**
315
+ * Execute `typokit add route <name>` — scaffold a route module.
316
+ */
317
+ export async function scaffoldRoute(rootDir, name, logger) {
318
+ const start = Date.now();
319
+ const { join } = (await import(/* @vite-ignore */ "path"));
320
+ const { mkdirSync, writeFileSync, existsSync } = (await import(
321
+ /* @vite-ignore */ "fs"));
322
+ const filesCreated = [];
323
+ const errors = [];
324
+ if (!name) {
325
+ errors.push("Route name is required. Usage: typokit add route <name>");
326
+ return {
327
+ success: false,
328
+ filesCreated,
329
+ duration: Date.now() - start,
330
+ errors,
331
+ };
332
+ }
333
+ const routeDir = join(rootDir, "src", "routes", name);
334
+ if (existsSync(routeDir)) {
335
+ errors.push(`Route directory "${name}" already exists at src/routes/${name}`);
336
+ return {
337
+ success: false,
338
+ filesCreated,
339
+ duration: Date.now() - start,
340
+ errors,
341
+ };
342
+ }
343
+ try {
344
+ mkdirSync(routeDir, { recursive: true });
345
+ // contracts.ts — route type contracts
346
+ const contractsPath = join(routeDir, "contracts.ts");
347
+ writeFileSync(contractsPath, generateRouteContracts(name));
348
+ filesCreated.push(contractsPath);
349
+ logger.info(`Created ${contractsPath}`);
350
+ // handlers.ts — handler implementations
351
+ const handlersPath = join(routeDir, "handlers.ts");
352
+ writeFileSync(handlersPath, generateRouteHandlers(name));
353
+ filesCreated.push(handlersPath);
354
+ logger.info(`Created ${handlersPath}`);
355
+ // middleware.ts — route-specific middleware
356
+ const middlewarePath = join(routeDir, "middleware.ts");
357
+ writeFileSync(middlewarePath, generateRouteMiddleware(name));
358
+ filesCreated.push(middlewarePath);
359
+ logger.info(`Created ${middlewarePath}`);
360
+ logger.info(`\nRoute "${name}" scaffolded at src/routes/${name}/`);
361
+ logger.info(" Don't forget to register it in src/app.ts!\n");
362
+ return {
363
+ success: true,
364
+ filesCreated,
365
+ duration: Date.now() - start,
366
+ errors,
367
+ };
368
+ }
369
+ catch (err) {
370
+ const msg = err instanceof Error ? err.message : String(err);
371
+ errors.push(msg);
372
+ return {
373
+ success: false,
374
+ filesCreated,
375
+ duration: Date.now() - start,
376
+ errors,
377
+ };
378
+ }
379
+ }
380
+ /**
381
+ * Execute `typokit add service <name>` — scaffold a service file.
382
+ */
383
+ export async function scaffoldService(rootDir, name, logger) {
384
+ const start = Date.now();
385
+ const { join } = (await import(/* @vite-ignore */ "path"));
386
+ const { mkdirSync, writeFileSync, existsSync } = (await import(
387
+ /* @vite-ignore */ "fs"));
388
+ const filesCreated = [];
389
+ const errors = [];
390
+ if (!name) {
391
+ errors.push("Service name is required. Usage: typokit add service <name>");
392
+ return {
393
+ success: false,
394
+ filesCreated,
395
+ duration: Date.now() - start,
396
+ errors,
397
+ };
398
+ }
399
+ const servicesDir = join(rootDir, "src", "services");
400
+ const servicePath = join(servicesDir, `${name}.service.ts`);
401
+ if (existsSync(servicePath)) {
402
+ errors.push(`Service "${name}" already exists at src/services/${name}.service.ts`);
403
+ return {
404
+ success: false,
405
+ filesCreated,
406
+ duration: Date.now() - start,
407
+ errors,
408
+ };
409
+ }
410
+ try {
411
+ mkdirSync(servicesDir, { recursive: true });
412
+ writeFileSync(servicePath, generateService(name));
413
+ filesCreated.push(servicePath);
414
+ logger.info(`Created ${servicePath}`);
415
+ logger.info(`\nService "${name}" scaffolded at src/services/${name}.service.ts\n`);
416
+ return {
417
+ success: true,
418
+ filesCreated,
419
+ duration: Date.now() - start,
420
+ errors,
421
+ };
422
+ }
423
+ catch (err) {
424
+ const msg = err instanceof Error ? err.message : String(err);
425
+ errors.push(msg);
426
+ return {
427
+ success: false,
428
+ filesCreated,
429
+ duration: Date.now() - start,
430
+ errors,
431
+ };
432
+ }
433
+ }
434
+ /**
435
+ * Execute scaffold commands dispatcher.
436
+ */
437
+ export async function executeScaffold(options) {
438
+ const { rootDir, logger, subcommand, positional, flags } = options;
439
+ if (subcommand === "init") {
440
+ const name = positional[0] ??
441
+ (typeof flags["name"] === "string" ? flags["name"] : "my-app");
442
+ const server = parseServerFlag(flags["server"]);
443
+ const db = parseDbFlag(flags["db"]);
444
+ return scaffoldInit(rootDir, { name, server, db }, logger);
445
+ }
446
+ if (subcommand === "route") {
447
+ const name = positional[0] ?? "";
448
+ return scaffoldRoute(rootDir, name, logger);
449
+ }
450
+ if (subcommand === "service") {
451
+ const name = positional[0] ?? "";
452
+ return scaffoldService(rootDir, name, logger);
453
+ }
454
+ return {
455
+ success: false,
456
+ filesCreated: [],
457
+ duration: 0,
458
+ errors: [
459
+ `Unknown scaffold subcommand: "${subcommand}". Use: init, route, service`,
460
+ ],
461
+ };
462
+ }
463
+ /** Parse server adapter flag */
464
+ function parseServerFlag(value) {
465
+ if (typeof value === "string") {
466
+ const valid = ["native", "fastify", "hono", "express"];
467
+ if (valid.includes(value)) {
468
+ return value;
469
+ }
470
+ }
471
+ return "native";
472
+ }
473
+ /** Parse database adapter flag */
474
+ function parseDbFlag(value) {
475
+ if (typeof value === "string") {
476
+ const valid = ["drizzle", "kysely", "prisma", "raw", "none"];
477
+ if (valid.includes(value)) {
478
+ return value;
479
+ }
480
+ }
481
+ return "none";
482
+ }
483
+ //# sourceMappingURL=scaffold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../src/commands/scaffold.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ import type { CliLogger } from "../logger.js";
2
+ import type { TypoKitConfig } from "../config.js";
3
+ export type TestRunner = "jest" | "vitest" | "rstest";
4
+ export interface TestCommandOptions {
5
+ /** Project root directory */
6
+ rootDir: string;
7
+ /** Resolved configuration */
8
+ config: Required<TypoKitConfig>;
9
+ /** Logger instance */
10
+ logger: CliLogger;
11
+ /** Test subcommand: "all" | "contracts" | "integration" */
12
+ subcommand: string;
13
+ /** CLI flags */
14
+ flags: Record<string, string | boolean>;
15
+ /** Whether verbose mode is enabled */
16
+ verbose: boolean;
17
+ }
18
+ export interface TestResult {
19
+ /** Whether all tests passed */
20
+ success: boolean;
21
+ /** Which test runner was used */
22
+ runner: TestRunner;
23
+ /** Duration in milliseconds */
24
+ duration: number;
25
+ /** Errors encountered */
26
+ errors: string[];
27
+ /** Whether contract tests were regenerated before running */
28
+ contractsRegenerated: boolean;
29
+ }
30
+ /**
31
+ * Auto-detect the test runner by checking for config files in the project root.
32
+ * Returns the first match found, or "vitest" as default.
33
+ */
34
+ export declare function detectTestRunner(rootDir: string): Promise<TestRunner>;
35
+ /**
36
+ * Build the command and arguments for each test runner.
37
+ */
38
+ export declare function buildRunnerCommand(runner: TestRunner, subcommand: string, rootDir: string, verbose: boolean): {
39
+ command: string;
40
+ args: string[];
41
+ };
42
+ /**
43
+ * Check whether schemas have changed since last contract test generation.
44
+ * Compares the content hash in .typokit/build-cache.json against current type files.
45
+ */
46
+ export declare function schemasChanged(rootDir: string, config: Required<TypoKitConfig>): Promise<boolean>;
47
+ /**
48
+ * Execute test commands.
49
+ *
50
+ * Subcommands:
51
+ * "all" — runs all tests
52
+ * "contracts" — runs only contract tests from __generated__/
53
+ * "integration" — runs integration tests with in-memory database
54
+ */
55
+ export declare function executeTest(options: TestCommandOptions): Promise<TestResult>;
56
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEtD,MAAM,WAAW,kBAAkB;IACjC,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;IAChC,sBAAsB;IACtB,MAAM,EAAE,SAAS,CAAC;IAClB,2DAA2D;IAC3D,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB;IAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;IACxC,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,+BAA+B;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,iCAAiC;IACjC,MAAM,EAAE,UAAU,CAAC;IACnB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,yBAAyB;IACzB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,6DAA6D;IAC7D,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AA0BD;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAoB3E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,GACf;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CA2CrC;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,GAC9B,OAAO,CAAC,OAAO,CAAC,CAyBlB;AAwCD;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,UAAU,CAAC,CAoIrB"}