@veloxts/cli 0.4.13 → 0.6.23
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/README.md +2 -48
- package/dist/cli.d.ts +5 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +7 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +71 -7
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/introspect.d.ts +16 -0
- package/dist/commands/introspect.d.ts.map +1 -0
- package/dist/commands/introspect.js +559 -0
- package/dist/commands/introspect.js.map +1 -0
- package/dist/commands/make.d.ts.map +1 -1
- package/dist/commands/make.js +18 -8
- package/dist/commands/make.js.map +1 -1
- package/dist/commands/procedures.d.ts.map +1 -1
- package/dist/commands/procedures.js +16 -0
- package/dist/commands/procedures.js.map +1 -1
- package/dist/dev/error-parser.d.ts.map +1 -1
- package/dist/dev/error-parser.js +24 -8
- package/dist/dev/error-parser.js.map +1 -1
- package/dist/dev/hmr-runner.d.ts.map +1 -1
- package/dist/dev/hmr-runner.js +6 -1
- package/dist/dev/hmr-runner.js.map +1 -1
- package/dist/dev/index.d.ts +3 -3
- package/dist/dev/index.d.ts.map +1 -1
- package/dist/dev/index.js +3 -3
- package/dist/dev/index.js.map +1 -1
- package/dist/dev/reload-reporter.d.ts +2 -2
- package/dist/dev/reload-reporter.d.ts.map +1 -1
- package/dist/dev/reload-reporter.js +2 -2
- package/dist/dev/reload-reporter.js.map +1 -1
- package/dist/errors/catalog.d.ts +48 -0
- package/dist/errors/catalog.d.ts.map +1 -0
- package/dist/errors/catalog.js +421 -0
- package/dist/errors/catalog.js.map +1 -0
- package/dist/errors/index.d.ts +26 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +28 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/velox-error.d.ts +122 -0
- package/dist/errors/velox-error.d.ts.map +1 -0
- package/dist/errors/velox-error.js +216 -0
- package/dist/errors/velox-error.js.map +1 -0
- package/dist/generators/base.d.ts.map +1 -1
- package/dist/generators/base.js +26 -0
- package/dist/generators/base.js.map +1 -1
- package/dist/generators/fields/__tests__/helpers.d.ts +66 -0
- package/dist/generators/fields/__tests__/helpers.d.ts.map +1 -0
- package/dist/generators/fields/__tests__/helpers.js +142 -0
- package/dist/generators/fields/__tests__/helpers.js.map +1 -0
- package/dist/generators/fields/actions.d.ts +58 -0
- package/dist/generators/fields/actions.d.ts.map +1 -0
- package/dist/generators/fields/actions.js +230 -0
- package/dist/generators/fields/actions.js.map +1 -0
- package/dist/generators/fields/display.d.ts +28 -0
- package/dist/generators/fields/display.d.ts.map +1 -0
- package/dist/generators/fields/display.js +214 -0
- package/dist/generators/fields/display.js.map +1 -0
- package/dist/generators/fields/index.d.ts +12 -0
- package/dist/generators/fields/index.d.ts.map +1 -0
- package/dist/generators/fields/index.js +12 -0
- package/dist/generators/fields/index.js.map +1 -0
- package/dist/generators/fields/prompts.d.ts +31 -0
- package/dist/generators/fields/prompts.d.ts.map +1 -0
- package/dist/generators/fields/prompts.js +366 -0
- package/dist/generators/fields/prompts.js.map +1 -0
- package/dist/generators/fields/templates.d.ts +49 -0
- package/dist/generators/fields/templates.d.ts.map +1 -0
- package/dist/generators/fields/templates.js +230 -0
- package/dist/generators/fields/templates.js.map +1 -0
- package/dist/generators/fields/types.d.ts +95 -0
- package/dist/generators/fields/types.d.ts.map +1 -0
- package/dist/generators/fields/types.js +150 -0
- package/dist/generators/fields/types.js.map +1 -0
- package/dist/generators/generators/action.d.ts +37 -0
- package/dist/generators/generators/action.d.ts.map +1 -0
- package/dist/generators/generators/action.js +109 -0
- package/dist/generators/generators/action.js.map +1 -0
- package/dist/generators/generators/exception.d.ts +38 -0
- package/dist/generators/generators/exception.d.ts.map +1 -0
- package/dist/generators/generators/exception.js +109 -0
- package/dist/generators/generators/exception.js.map +1 -0
- package/dist/generators/generators/guard.d.ts +38 -0
- package/dist/generators/generators/guard.d.ts.map +1 -0
- package/dist/generators/generators/guard.js +109 -0
- package/dist/generators/generators/guard.js.map +1 -0
- package/dist/generators/generators/index.d.ts +8 -0
- package/dist/generators/generators/index.d.ts.map +1 -1
- package/dist/generators/generators/index.js +27 -0
- package/dist/generators/generators/index.js.map +1 -1
- package/dist/generators/generators/layout.d.ts +36 -0
- package/dist/generators/generators/layout.d.ts.map +1 -0
- package/dist/generators/generators/layout.js +111 -0
- package/dist/generators/generators/layout.js.map +1 -0
- package/dist/generators/generators/middleware.d.ts +38 -0
- package/dist/generators/generators/middleware.d.ts.map +1 -0
- package/dist/generators/generators/middleware.js +109 -0
- package/dist/generators/generators/middleware.js.map +1 -0
- package/dist/generators/generators/model.d.ts +16 -4
- package/dist/generators/generators/model.d.ts.map +1 -1
- package/dist/generators/generators/model.js +88 -7
- package/dist/generators/generators/model.js.map +1 -1
- package/dist/generators/generators/page.d.ts +36 -0
- package/dist/generators/generators/page.d.ts.map +1 -0
- package/dist/generators/generators/page.js +112 -0
- package/dist/generators/generators/page.js.map +1 -0
- package/dist/generators/generators/policy.d.ts +37 -0
- package/dist/generators/generators/policy.d.ts.map +1 -0
- package/dist/generators/generators/policy.js +100 -0
- package/dist/generators/generators/policy.js.map +1 -0
- package/dist/generators/generators/resource.d.ts +42 -4
- package/dist/generators/generators/resource.d.ts.map +1 -1
- package/dist/generators/generators/resource.js +450 -9
- package/dist/generators/generators/resource.js.map +1 -1
- package/dist/generators/generators/service.d.ts +38 -0
- package/dist/generators/generators/service.d.ts.map +1 -0
- package/dist/generators/generators/service.js +109 -0
- package/dist/generators/generators/service.js.map +1 -0
- package/dist/generators/registry.d.ts.map +1 -1
- package/dist/generators/registry.js +10 -1
- package/dist/generators/registry.js.map +1 -1
- package/dist/generators/templates/action.d.ts +28 -0
- package/dist/generators/templates/action.d.ts.map +1 -0
- package/dist/generators/templates/action.js +359 -0
- package/dist/generators/templates/action.js.map +1 -0
- package/dist/generators/templates/exception.d.ts +26 -0
- package/dist/generators/templates/exception.d.ts.map +1 -0
- package/dist/generators/templates/exception.js +671 -0
- package/dist/generators/templates/exception.js.map +1 -0
- package/dist/generators/templates/guard.d.ts +26 -0
- package/dist/generators/templates/guard.d.ts.map +1 -0
- package/dist/generators/templates/guard.js +555 -0
- package/dist/generators/templates/guard.js.map +1 -0
- package/dist/generators/templates/layout.d.ts +28 -0
- package/dist/generators/templates/layout.d.ts.map +1 -0
- package/dist/generators/templates/layout.js +147 -0
- package/dist/generators/templates/layout.js.map +1 -0
- package/dist/generators/templates/middleware.d.ts +26 -0
- package/dist/generators/templates/middleware.d.ts.map +1 -0
- package/dist/generators/templates/middleware.js +411 -0
- package/dist/generators/templates/middleware.js.map +1 -0
- package/dist/generators/templates/model.d.ts +3 -0
- package/dist/generators/templates/model.d.ts.map +1 -1
- package/dist/generators/templates/model.js +183 -28
- package/dist/generators/templates/model.js.map +1 -1
- package/dist/generators/templates/page.d.ts +36 -0
- package/dist/generators/templates/page.d.ts.map +1 -0
- package/dist/generators/templates/page.js +147 -0
- package/dist/generators/templates/page.js.map +1 -0
- package/dist/generators/templates/policy.d.ts +24 -0
- package/dist/generators/templates/policy.d.ts.map +1 -0
- package/dist/generators/templates/policy.js +499 -0
- package/dist/generators/templates/policy.js.map +1 -0
- package/dist/generators/templates/resource.d.ts +65 -0
- package/dist/generators/templates/resource.d.ts.map +1 -1
- package/dist/generators/templates/resource.js +228 -43
- package/dist/generators/templates/resource.js.map +1 -1
- package/dist/generators/templates/service.d.ts +26 -0
- package/dist/generators/templates/service.d.ts.map +1 -0
- package/dist/generators/templates/service.js +511 -0
- package/dist/generators/templates/service.js.map +1 -0
- package/dist/generators/types.d.ts +26 -14
- package/dist/generators/types.d.ts.map +1 -1
- package/dist/generators/types.js +8 -25
- package/dist/generators/types.js.map +1 -1
- package/dist/generators/utils/ast-helpers.d.ts +147 -0
- package/dist/generators/utils/ast-helpers.d.ts.map +1 -0
- package/dist/generators/utils/ast-helpers.js +350 -0
- package/dist/generators/utils/ast-helpers.js.map +1 -0
- package/dist/generators/utils/prisma-migration.d.ts +59 -0
- package/dist/generators/utils/prisma-migration.d.ts.map +1 -0
- package/dist/generators/utils/prisma-migration.js +161 -0
- package/dist/generators/utils/prisma-migration.js.map +1 -0
- package/dist/generators/utils/prisma-schema.d.ts +97 -0
- package/dist/generators/utils/prisma-schema.d.ts.map +1 -0
- package/dist/generators/utils/prisma-schema.js +235 -0
- package/dist/generators/utils/prisma-schema.js.map +1 -0
- package/dist/generators/utils/router-integration.d.ts +70 -0
- package/dist/generators/utils/router-integration.d.ts.map +1 -0
- package/dist/generators/utils/router-integration.js +305 -0
- package/dist/generators/utils/router-integration.js.map +1 -0
- package/dist/generators/utils/snapshot.d.ts +93 -0
- package/dist/generators/utils/snapshot.d.ts.map +1 -0
- package/dist/generators/utils/snapshot.js +178 -0
- package/dist/generators/utils/snapshot.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/seeding/errors.d.ts +11 -24
- package/dist/seeding/errors.d.ts.map +1 -1
- package/dist/seeding/errors.js +11 -50
- package/dist/seeding/errors.js.map +1 -1
- package/dist/utils/paths.d.ts +19 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +45 -0
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/schema-patterns.d.ts +26 -0
- package/dist/utils/schema-patterns.d.ts.map +1 -0
- package/dist/utils/schema-patterns.js +40 -0
- package/dist/utils/schema-patterns.js.map +1 -0
- package/package.json +12 -10
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layout Template
|
|
3
|
+
*
|
|
4
|
+
* Generates RSC layout files for VeloxTS full-stack applications.
|
|
5
|
+
*/
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// Path Helpers
|
|
8
|
+
// ============================================================================
|
|
9
|
+
/**
|
|
10
|
+
* Get the path for a layout file
|
|
11
|
+
*/
|
|
12
|
+
export function getLayoutPath(entityName, project) {
|
|
13
|
+
const layoutsDir = project.layoutsDir ?? 'app/layouts';
|
|
14
|
+
// Root layout goes in app/layouts/_layout.tsx
|
|
15
|
+
if (entityName.toLowerCase() === 'root') {
|
|
16
|
+
return `${layoutsDir}/_layout.tsx`;
|
|
17
|
+
}
|
|
18
|
+
// Named layouts go in app/layouts/<name>/_layout.tsx
|
|
19
|
+
return `${layoutsDir}/${entityName.toLowerCase()}/_layout.tsx`;
|
|
20
|
+
}
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// Templates
|
|
23
|
+
// ============================================================================
|
|
24
|
+
/**
|
|
25
|
+
* Generate a root layout with html/body
|
|
26
|
+
*/
|
|
27
|
+
function generateRootLayout(ctx) {
|
|
28
|
+
const { entity, options } = ctx;
|
|
29
|
+
const header = options.header
|
|
30
|
+
? `
|
|
31
|
+
<header className="app-header">
|
|
32
|
+
<nav>
|
|
33
|
+
<a href="/">Home</a>
|
|
34
|
+
<a href="/about">About</a>
|
|
35
|
+
</nav>
|
|
36
|
+
</header>`
|
|
37
|
+
: '';
|
|
38
|
+
const footer = options.footer
|
|
39
|
+
? `
|
|
40
|
+
<footer className="app-footer">
|
|
41
|
+
<p>© {new Date().getFullYear()} ${entity.pascal}</p>
|
|
42
|
+
</footer>`
|
|
43
|
+
: '';
|
|
44
|
+
return `/**
|
|
45
|
+
* Root Layout
|
|
46
|
+
*
|
|
47
|
+
* Wraps all pages with shared UI elements.
|
|
48
|
+
* This is a Server Component by default.
|
|
49
|
+
*/
|
|
50
|
+
export default function ${entity.pascal}Layout({
|
|
51
|
+
children,
|
|
52
|
+
}: {
|
|
53
|
+
children: React.ReactNode;
|
|
54
|
+
}) {
|
|
55
|
+
return (
|
|
56
|
+
<html lang="en">
|
|
57
|
+
<head>
|
|
58
|
+
<meta charSet="utf-8" />
|
|
59
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
60
|
+
<title>VeloxTS App</title>
|
|
61
|
+
</head>
|
|
62
|
+
<body>${header}
|
|
63
|
+
<main className="app-main">
|
|
64
|
+
{children}
|
|
65
|
+
</main>${footer}
|
|
66
|
+
</body>
|
|
67
|
+
</html>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
`;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Generate a nested layout (segment or group)
|
|
74
|
+
*/
|
|
75
|
+
function generateNestedLayout(ctx) {
|
|
76
|
+
const { entity, options } = ctx;
|
|
77
|
+
const sidebar = options.sidebar
|
|
78
|
+
? `
|
|
79
|
+
<aside className="${entity.kebab}-sidebar">
|
|
80
|
+
<nav>
|
|
81
|
+
{/* Add navigation links */}
|
|
82
|
+
</nav>
|
|
83
|
+
</aside>`
|
|
84
|
+
: '';
|
|
85
|
+
const header = options.header
|
|
86
|
+
? `
|
|
87
|
+
<header className="${entity.kebab}-header">
|
|
88
|
+
<h2>${entity.humanReadable}</h2>
|
|
89
|
+
</header>`
|
|
90
|
+
: '';
|
|
91
|
+
return `/**
|
|
92
|
+
* ${entity.pascal} Layout
|
|
93
|
+
*
|
|
94
|
+
* Wraps pages in the ${entity.humanReadable} section.
|
|
95
|
+
* This is a Server Component by default.
|
|
96
|
+
*/
|
|
97
|
+
export default function ${entity.pascal}Layout({
|
|
98
|
+
children,
|
|
99
|
+
}: {
|
|
100
|
+
children: React.ReactNode;
|
|
101
|
+
}) {
|
|
102
|
+
return (
|
|
103
|
+
<div className="${entity.kebab}-layout">${header}
|
|
104
|
+
<div className="${entity.kebab}-content">${sidebar}
|
|
105
|
+
<div className="${entity.kebab}-main">
|
|
106
|
+
{children}
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
`;
|
|
113
|
+
}
|
|
114
|
+
// ============================================================================
|
|
115
|
+
// Main Template
|
|
116
|
+
// ============================================================================
|
|
117
|
+
/**
|
|
118
|
+
* Layout template function
|
|
119
|
+
*/
|
|
120
|
+
export const layoutTemplate = (ctx) => {
|
|
121
|
+
if (ctx.options.root) {
|
|
122
|
+
return generateRootLayout(ctx);
|
|
123
|
+
}
|
|
124
|
+
return generateNestedLayout(ctx);
|
|
125
|
+
};
|
|
126
|
+
// ============================================================================
|
|
127
|
+
// Post-generation Instructions
|
|
128
|
+
// ============================================================================
|
|
129
|
+
export function getLayoutInstructions(entityName, options) {
|
|
130
|
+
const lines = [`Your ${entityName} layout has been created.`, '', 'Next steps:'];
|
|
131
|
+
if (options.root) {
|
|
132
|
+
lines.push(' 1. Customize the <head> metadata');
|
|
133
|
+
lines.push(' 2. Add global styles to the root layout');
|
|
134
|
+
if (options.header) {
|
|
135
|
+
lines.push(' 3. Update navigation links in the header');
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
lines.push(` 1. Customize the ${entityName} layout structure`);
|
|
140
|
+
if (options.sidebar) {
|
|
141
|
+
lines.push(' 2. Add navigation items to the sidebar');
|
|
142
|
+
}
|
|
143
|
+
lines.push(" 3. Place pages inside this layout's directory");
|
|
144
|
+
}
|
|
145
|
+
return lines.join('\n');
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../../../src/generators/templates/layout.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Middleware Template
|
|
3
|
+
*
|
|
4
|
+
* Generates middleware files for VeloxTS applications.
|
|
5
|
+
*/
|
|
6
|
+
import type { ProjectContext, TemplateFunction } from '../types.js';
|
|
7
|
+
export interface MiddlewareOptions {
|
|
8
|
+
/** Generate request timing middleware */
|
|
9
|
+
timing: boolean;
|
|
10
|
+
/** Generate logging middleware */
|
|
11
|
+
logging: boolean;
|
|
12
|
+
/** Generate rate limiting middleware */
|
|
13
|
+
rateLimit: boolean;
|
|
14
|
+
/** Generate CORS middleware */
|
|
15
|
+
cors: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Get the path for a middleware file
|
|
19
|
+
*/
|
|
20
|
+
export declare function getMiddlewarePath(entityName: string, _project: ProjectContext): string;
|
|
21
|
+
/**
|
|
22
|
+
* Middleware template function
|
|
23
|
+
*/
|
|
24
|
+
export declare const middlewareTemplate: TemplateFunction<MiddlewareOptions>;
|
|
25
|
+
export declare function getMiddlewareInstructions(entityName: string, options: MiddlewareOptions): string;
|
|
26
|
+
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../../src/generators/templates/middleware.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAmB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAMrF,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,MAAM,EAAE,OAAO,CAAC;IAChB,kCAAkC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,wCAAwC;IACxC,SAAS,EAAE,OAAO,CAAC;IACnB,+BAA+B;IAC/B,IAAI,EAAE,OAAO,CAAC;CACf;AAMD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,MAAM,CAEtF;AA+WD;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,gBAAgB,CAAC,iBAAiB,CAclE,CAAC;AAMF,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAoBhG"}
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Middleware Template
|
|
3
|
+
*
|
|
4
|
+
* Generates middleware files for VeloxTS applications.
|
|
5
|
+
*/
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// Path Helpers
|
|
8
|
+
// ============================================================================
|
|
9
|
+
/**
|
|
10
|
+
* Get the path for a middleware file
|
|
11
|
+
*/
|
|
12
|
+
export function getMiddlewarePath(entityName, _project) {
|
|
13
|
+
return `src/middleware/${entityName.toLowerCase()}.ts`;
|
|
14
|
+
}
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Templates
|
|
17
|
+
// ============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* Generate timing middleware
|
|
20
|
+
*/
|
|
21
|
+
function generateTimingMiddleware(ctx) {
|
|
22
|
+
const { entity } = ctx;
|
|
23
|
+
return `/**
|
|
24
|
+
* ${entity.pascal} Timing Middleware
|
|
25
|
+
*
|
|
26
|
+
* Tracks request duration and adds timing headers.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';
|
|
30
|
+
import fp from 'fastify-plugin';
|
|
31
|
+
|
|
32
|
+
declare module 'fastify' {
|
|
33
|
+
interface FastifyRequest {
|
|
34
|
+
startTime: number;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Request timing middleware
|
|
40
|
+
*
|
|
41
|
+
* Adds X-Response-Time header with request duration in milliseconds.
|
|
42
|
+
*/
|
|
43
|
+
async function ${entity.camel}Middleware(fastify: FastifyInstance): Promise<void> {
|
|
44
|
+
fastify.addHook('onRequest', async (request: FastifyRequest) => {
|
|
45
|
+
request.startTime = performance.now();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
fastify.addHook('onSend', async (request: FastifyRequest, reply: FastifyReply) => {
|
|
49
|
+
const duration = performance.now() - request.startTime;
|
|
50
|
+
reply.header('X-Response-Time', \`\${duration.toFixed(2)}ms\`);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export default fp(${entity.camel}Middleware, {
|
|
55
|
+
name: '${entity.kebab}-middleware',
|
|
56
|
+
fastify: '5.x',
|
|
57
|
+
});
|
|
58
|
+
`;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Generate logging middleware
|
|
62
|
+
*/
|
|
63
|
+
function generateLoggingMiddleware(ctx) {
|
|
64
|
+
const { entity } = ctx;
|
|
65
|
+
return `/**
|
|
66
|
+
* ${entity.pascal} Logging Middleware
|
|
67
|
+
*
|
|
68
|
+
* Structured request/response logging with context.
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';
|
|
72
|
+
import fp from 'fastify-plugin';
|
|
73
|
+
|
|
74
|
+
interface LogContext {
|
|
75
|
+
requestId: string;
|
|
76
|
+
method: string;
|
|
77
|
+
url: string;
|
|
78
|
+
userAgent?: string;
|
|
79
|
+
ip?: string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Structured logging middleware
|
|
84
|
+
*/
|
|
85
|
+
async function ${entity.camel}Middleware(fastify: FastifyInstance): Promise<void> {
|
|
86
|
+
fastify.addHook('onRequest', async (request: FastifyRequest) => {
|
|
87
|
+
const ctx: LogContext = {
|
|
88
|
+
requestId: request.id,
|
|
89
|
+
method: request.method,
|
|
90
|
+
url: request.url,
|
|
91
|
+
userAgent: request.headers['user-agent'],
|
|
92
|
+
ip: request.ip,
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
request.log.info(ctx, 'Incoming request');
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
fastify.addHook('onResponse', async (request: FastifyRequest, reply: FastifyReply) => {
|
|
99
|
+
request.log.info(
|
|
100
|
+
{
|
|
101
|
+
requestId: request.id,
|
|
102
|
+
statusCode: reply.statusCode,
|
|
103
|
+
responseTime: reply.elapsedTime,
|
|
104
|
+
},
|
|
105
|
+
'Request completed'
|
|
106
|
+
);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
fastify.addHook('onError', async (request: FastifyRequest, reply: FastifyReply, error: Error) => {
|
|
110
|
+
request.log.error(
|
|
111
|
+
{
|
|
112
|
+
requestId: request.id,
|
|
113
|
+
error: error.message,
|
|
114
|
+
stack: error.stack,
|
|
115
|
+
},
|
|
116
|
+
'Request error'
|
|
117
|
+
);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export default fp(${entity.camel}Middleware, {
|
|
122
|
+
name: '${entity.kebab}-middleware',
|
|
123
|
+
fastify: '5.x',
|
|
124
|
+
});
|
|
125
|
+
`;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Generate rate limiting middleware
|
|
129
|
+
*/
|
|
130
|
+
function generateRateLimitMiddleware(ctx) {
|
|
131
|
+
const { entity } = ctx;
|
|
132
|
+
return `/**
|
|
133
|
+
* ${entity.pascal} Rate Limiting Middleware
|
|
134
|
+
*
|
|
135
|
+
* Token bucket rate limiting with configurable limits.
|
|
136
|
+
*/
|
|
137
|
+
|
|
138
|
+
import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';
|
|
139
|
+
import fp from 'fastify-plugin';
|
|
140
|
+
|
|
141
|
+
interface RateLimitOptions {
|
|
142
|
+
/** Maximum requests per window */
|
|
143
|
+
max: number;
|
|
144
|
+
/** Time window in milliseconds */
|
|
145
|
+
window: number;
|
|
146
|
+
/** Custom key generator (default: IP address) */
|
|
147
|
+
keyGenerator?: (request: FastifyRequest) => string;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const DEFAULT_OPTIONS: RateLimitOptions = {
|
|
151
|
+
max: 100,
|
|
152
|
+
window: 60 * 1000, // 1 minute
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
// In-memory store (use Redis in production)
|
|
156
|
+
const requestCounts = new Map<string, { count: number; resetAt: number }>();
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Rate limiting middleware
|
|
160
|
+
*/
|
|
161
|
+
async function ${entity.camel}Middleware(
|
|
162
|
+
fastify: FastifyInstance,
|
|
163
|
+
options: Partial<RateLimitOptions> = {}
|
|
164
|
+
): Promise<void> {
|
|
165
|
+
const config = { ...DEFAULT_OPTIONS, ...options };
|
|
166
|
+
const keyGenerator = config.keyGenerator ?? ((req) => req.ip);
|
|
167
|
+
|
|
168
|
+
fastify.addHook('onRequest', async (request: FastifyRequest, reply: FastifyReply) => {
|
|
169
|
+
const key = keyGenerator(request);
|
|
170
|
+
const now = Date.now();
|
|
171
|
+
|
|
172
|
+
let record = requestCounts.get(key);
|
|
173
|
+
|
|
174
|
+
// Reset if window expired
|
|
175
|
+
if (!record || now >= record.resetAt) {
|
|
176
|
+
record = { count: 0, resetAt: now + config.window };
|
|
177
|
+
requestCounts.set(key, record);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
record.count++;
|
|
181
|
+
|
|
182
|
+
// Add rate limit headers
|
|
183
|
+
reply.header('X-RateLimit-Limit', config.max);
|
|
184
|
+
reply.header('X-RateLimit-Remaining', Math.max(0, config.max - record.count));
|
|
185
|
+
reply.header('X-RateLimit-Reset', Math.ceil(record.resetAt / 1000));
|
|
186
|
+
|
|
187
|
+
if (record.count > config.max) {
|
|
188
|
+
reply.header('Retry-After', Math.ceil((record.resetAt - now) / 1000));
|
|
189
|
+
reply.status(429).send({
|
|
190
|
+
error: 'Too Many Requests',
|
|
191
|
+
message: 'Rate limit exceeded. Please try again later.',
|
|
192
|
+
retryAfter: Math.ceil((record.resetAt - now) / 1000),
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
// Cleanup expired entries periodically
|
|
198
|
+
const cleanup = setInterval(() => {
|
|
199
|
+
const now = Date.now();
|
|
200
|
+
for (const [key, record] of requestCounts) {
|
|
201
|
+
if (now >= record.resetAt) {
|
|
202
|
+
requestCounts.delete(key);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}, config.window);
|
|
206
|
+
|
|
207
|
+
fastify.addHook('onClose', async () => {
|
|
208
|
+
clearInterval(cleanup);
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export default fp(${entity.camel}Middleware, {
|
|
213
|
+
name: '${entity.kebab}-middleware',
|
|
214
|
+
fastify: '5.x',
|
|
215
|
+
});
|
|
216
|
+
`;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Generate CORS middleware
|
|
220
|
+
*/
|
|
221
|
+
function generateCorsMiddleware(ctx) {
|
|
222
|
+
const { entity } = ctx;
|
|
223
|
+
return `/**
|
|
224
|
+
* ${entity.pascal} CORS Middleware
|
|
225
|
+
*
|
|
226
|
+
* Cross-Origin Resource Sharing configuration.
|
|
227
|
+
*/
|
|
228
|
+
|
|
229
|
+
import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';
|
|
230
|
+
import fp from 'fastify-plugin';
|
|
231
|
+
|
|
232
|
+
interface CorsOptions {
|
|
233
|
+
/** Allowed origins (string, array, or function) */
|
|
234
|
+
origin: string | string[] | ((origin: string) => boolean);
|
|
235
|
+
/** Allowed HTTP methods */
|
|
236
|
+
methods: string[];
|
|
237
|
+
/** Allowed headers */
|
|
238
|
+
allowedHeaders: string[];
|
|
239
|
+
/** Exposed headers */
|
|
240
|
+
exposedHeaders: string[];
|
|
241
|
+
/** Allow credentials */
|
|
242
|
+
credentials: boolean;
|
|
243
|
+
/** Preflight cache duration in seconds */
|
|
244
|
+
maxAge: number;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const DEFAULT_OPTIONS: CorsOptions = {
|
|
248
|
+
origin: '*',
|
|
249
|
+
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
|
250
|
+
allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],
|
|
251
|
+
exposedHeaders: ['X-Request-Id', 'X-Response-Time'],
|
|
252
|
+
credentials: false,
|
|
253
|
+
maxAge: 86400, // 24 hours
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Check if origin is allowed
|
|
258
|
+
*/
|
|
259
|
+
function isOriginAllowed(origin: string, allowed: CorsOptions['origin']): boolean {
|
|
260
|
+
if (allowed === '*') return true;
|
|
261
|
+
if (typeof allowed === 'string') return origin === allowed;
|
|
262
|
+
if (Array.isArray(allowed)) return allowed.includes(origin);
|
|
263
|
+
if (typeof allowed === 'function') return allowed(origin);
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* CORS middleware
|
|
269
|
+
*/
|
|
270
|
+
async function ${entity.camel}Middleware(
|
|
271
|
+
fastify: FastifyInstance,
|
|
272
|
+
options: Partial<CorsOptions> = {}
|
|
273
|
+
): Promise<void> {
|
|
274
|
+
const config = { ...DEFAULT_OPTIONS, ...options };
|
|
275
|
+
|
|
276
|
+
fastify.addHook('onRequest', async (request: FastifyRequest, reply: FastifyReply) => {
|
|
277
|
+
const origin = request.headers.origin ?? '';
|
|
278
|
+
|
|
279
|
+
if (origin && isOriginAllowed(origin, config.origin)) {
|
|
280
|
+
reply.header('Access-Control-Allow-Origin', origin);
|
|
281
|
+
} else if (config.origin === '*') {
|
|
282
|
+
reply.header('Access-Control-Allow-Origin', '*');
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (config.credentials) {
|
|
286
|
+
reply.header('Access-Control-Allow-Credentials', 'true');
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
reply.header('Access-Control-Expose-Headers', config.exposedHeaders.join(', '));
|
|
290
|
+
|
|
291
|
+
// Handle preflight
|
|
292
|
+
if (request.method === 'OPTIONS') {
|
|
293
|
+
reply.header('Access-Control-Allow-Methods', config.methods.join(', '));
|
|
294
|
+
reply.header('Access-Control-Allow-Headers', config.allowedHeaders.join(', '));
|
|
295
|
+
reply.header('Access-Control-Max-Age', config.maxAge.toString());
|
|
296
|
+
reply.status(204).send();
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export default fp(${entity.camel}Middleware, {
|
|
302
|
+
name: '${entity.kebab}-middleware',
|
|
303
|
+
fastify: '5.x',
|
|
304
|
+
});
|
|
305
|
+
`;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Generate simple middleware template
|
|
309
|
+
*/
|
|
310
|
+
function generateSimpleMiddleware(ctx) {
|
|
311
|
+
const { entity } = ctx;
|
|
312
|
+
return `/**
|
|
313
|
+
* ${entity.pascal} Middleware
|
|
314
|
+
*
|
|
315
|
+
* Custom middleware for VeloxTS application.
|
|
316
|
+
*/
|
|
317
|
+
|
|
318
|
+
import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';
|
|
319
|
+
import fp from 'fastify-plugin';
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* ${entity.pascal} middleware options
|
|
323
|
+
*/
|
|
324
|
+
interface ${entity.pascal}MiddlewareOptions {
|
|
325
|
+
// TODO: Add configuration options
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* ${entity.pascal} middleware
|
|
330
|
+
*
|
|
331
|
+
* Add your custom middleware logic here.
|
|
332
|
+
*/
|
|
333
|
+
async function ${entity.camel}Middleware(
|
|
334
|
+
fastify: FastifyInstance,
|
|
335
|
+
_options: ${entity.pascal}MiddlewareOptions = {}
|
|
336
|
+
): Promise<void> {
|
|
337
|
+
// Run before each request
|
|
338
|
+
fastify.addHook('onRequest', async (request: FastifyRequest, reply: FastifyReply) => {
|
|
339
|
+
// TODO: Add pre-request logic
|
|
340
|
+
// Example: request.customProperty = 'value';
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
// Run after response is sent
|
|
344
|
+
fastify.addHook('onResponse', async (request: FastifyRequest, reply: FastifyReply) => {
|
|
345
|
+
// TODO: Add post-response logic
|
|
346
|
+
// Example: Log response metrics
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
// Run when an error occurs
|
|
350
|
+
fastify.addHook('onError', async (request: FastifyRequest, reply: FastifyReply, error: Error) => {
|
|
351
|
+
// TODO: Add error handling logic
|
|
352
|
+
// Example: Report to error tracking service
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// Decorate fastify instance if needed
|
|
356
|
+
// fastify.decorate('${entity.camel}', { /* ... */ });
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export default fp(${entity.camel}Middleware, {
|
|
360
|
+
name: '${entity.kebab}-middleware',
|
|
361
|
+
fastify: '5.x',
|
|
362
|
+
});
|
|
363
|
+
`;
|
|
364
|
+
}
|
|
365
|
+
// ============================================================================
|
|
366
|
+
// Main Template
|
|
367
|
+
// ============================================================================
|
|
368
|
+
/**
|
|
369
|
+
* Middleware template function
|
|
370
|
+
*/
|
|
371
|
+
export const middlewareTemplate = (ctx) => {
|
|
372
|
+
if (ctx.options.timing) {
|
|
373
|
+
return generateTimingMiddleware(ctx);
|
|
374
|
+
}
|
|
375
|
+
if (ctx.options.logging) {
|
|
376
|
+
return generateLoggingMiddleware(ctx);
|
|
377
|
+
}
|
|
378
|
+
if (ctx.options.rateLimit) {
|
|
379
|
+
return generateRateLimitMiddleware(ctx);
|
|
380
|
+
}
|
|
381
|
+
if (ctx.options.cors) {
|
|
382
|
+
return generateCorsMiddleware(ctx);
|
|
383
|
+
}
|
|
384
|
+
return generateSimpleMiddleware(ctx);
|
|
385
|
+
};
|
|
386
|
+
// ============================================================================
|
|
387
|
+
// Post-generation Instructions
|
|
388
|
+
// ============================================================================
|
|
389
|
+
export function getMiddlewareInstructions(entityName, options) {
|
|
390
|
+
const lines = [`Your ${entityName} middleware has been created.`, '', 'Next steps:'];
|
|
391
|
+
lines.push(' 1. Register the middleware in your app:');
|
|
392
|
+
lines.push(` await app.register(import('./middleware/${entityName.toLowerCase()}.js'));`);
|
|
393
|
+
if (options.timing) {
|
|
394
|
+
lines.push(' 2. Access timing via X-Response-Time header');
|
|
395
|
+
}
|
|
396
|
+
else if (options.logging) {
|
|
397
|
+
lines.push(' 2. Configure your logger for structured output');
|
|
398
|
+
}
|
|
399
|
+
else if (options.rateLimit) {
|
|
400
|
+
lines.push(' 2. Adjust rate limits for your use case');
|
|
401
|
+
lines.push(' 3. Consider using Redis for distributed rate limiting');
|
|
402
|
+
}
|
|
403
|
+
else if (options.cors) {
|
|
404
|
+
lines.push(' 2. Configure allowed origins for your environment');
|
|
405
|
+
}
|
|
406
|
+
else {
|
|
407
|
+
lines.push(' 2. Implement your middleware logic in the hooks');
|
|
408
|
+
}
|
|
409
|
+
return lines.join('\n');
|
|
410
|
+
}
|
|
411
|
+
//# sourceMappingURL=middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../../src/generators/templates/middleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Generates Prisma model, Zod schema, and optionally procedures.
|
|
5
5
|
*/
|
|
6
|
+
import type { FieldDefinition } from '../fields/types.js';
|
|
6
7
|
import type { GeneratedFile, TemplateContext, TemplateFunction } from '../types.js';
|
|
7
8
|
export interface ModelOptions {
|
|
8
9
|
/** Generate CRUD procedures alongside the model */
|
|
@@ -13,6 +14,8 @@ export interface ModelOptions {
|
|
|
13
14
|
softDelete: boolean;
|
|
14
15
|
/** Include timestamps (createdAt, updatedAt) */
|
|
15
16
|
timestamps: boolean;
|
|
17
|
+
/** Custom field definitions */
|
|
18
|
+
fields?: FieldDefinition[];
|
|
16
19
|
}
|
|
17
20
|
/**
|
|
18
21
|
* Model template - generates Prisma model definition
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/generators/templates/model.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAMpF,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,IAAI,EAAE,OAAO,CAAC;IACd,4CAA4C;IAC5C,SAAS,EAAE,OAAO,CAAC;IACnB,4CAA4C;IAC5C,UAAU,EAAE,OAAO,CAAC;IACpB,gDAAgD;IAChD,UAAU,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/generators/templates/model.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAMpF,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,IAAI,EAAE,OAAO,CAAC;IACd,4CAA4C;IAC5C,SAAS,EAAE,OAAO,CAAC;IACnB,4CAA4C;IAC5C,UAAU,EAAE,OAAO,CAAC;IACpB,gDAAgD;IAChD,UAAU,EAAE,OAAO,CAAC;IACpB,+BAA+B;IAC/B,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;CAC5B;AAkfD;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,gBAAgB,CAAC,YAAY,CAE9D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,gBAAgB,CAAC,YAAY,CAEzD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,gBAAgB,CAAC,YAAY,CAE7D,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,eAAe,CAAC,YAAY,CAAC,GAAG,aAAa,EAAE,CAyBtF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,eAAe,CAAC,YAAY,CAAC,GAAG,MAAM,CAkC/E"}
|