@veloxts/cli 0.4.14 → 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 @@
|
|
|
1
|
+
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../../src/generators/templates/guard.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAmB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAMrF,MAAM,WAAW,YAAY;IAC3B,gCAAgC;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,sCAAsC;IACtC,UAAU,EAAE,OAAO,CAAC;IACpB,+BAA+B;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,+BAA+B;IAC/B,SAAS,EAAE,OAAO,CAAC;CACpB;AAMD;;GAEG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,MAAM,CAEjF;AAigBD;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,gBAAgB,CAAC,YAAY,CAcxD,CAAC;AAMF,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,MAAM,CAmBtF"}
|
|
@@ -0,0 +1,555 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Guard Template
|
|
3
|
+
*
|
|
4
|
+
* Generates auth guard files for VeloxTS applications.
|
|
5
|
+
*/
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// Path Helpers
|
|
8
|
+
// ============================================================================
|
|
9
|
+
/**
|
|
10
|
+
* Get the path for a guard file
|
|
11
|
+
*/
|
|
12
|
+
export function getGuardPath(entityName, _project) {
|
|
13
|
+
return `src/guards/${entityName.toLowerCase()}.ts`;
|
|
14
|
+
}
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Templates
|
|
17
|
+
// ============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* Generate role-based guard
|
|
20
|
+
*/
|
|
21
|
+
function generateRoleGuard(ctx) {
|
|
22
|
+
const { entity } = ctx;
|
|
23
|
+
return `/**
|
|
24
|
+
* ${entity.pascal} Role Guard
|
|
25
|
+
*
|
|
26
|
+
* Guards routes based on user roles.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import { hasRole, allOf, anyOf, authenticated } from '@veloxts/auth';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Require ${entity.humanReadable} role
|
|
33
|
+
*/
|
|
34
|
+
export const is${entity.pascal} = hasRole('${entity.snake}');
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Require admin role
|
|
38
|
+
*/
|
|
39
|
+
export const isAdmin = hasRole('admin');
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Require either ${entity.humanReadable} or admin role
|
|
43
|
+
*/
|
|
44
|
+
export const is${entity.pascal}OrAdmin = anyOf(
|
|
45
|
+
is${entity.pascal},
|
|
46
|
+
isAdmin
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Require authentication AND ${entity.humanReadable} role
|
|
51
|
+
*/
|
|
52
|
+
export const authenticated${entity.pascal} = allOf(
|
|
53
|
+
authenticated,
|
|
54
|
+
is${entity.pascal}
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Guard factory for dynamic role checking
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* const isModerator = requireRole('moderator');
|
|
62
|
+
* procedure.guard(isModerator).query(...)
|
|
63
|
+
*/
|
|
64
|
+
export function requireRole(role: string) {
|
|
65
|
+
return hasRole(role);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Guard factory for multiple roles (any match)
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* const isStaff = requireAnyRole('admin', 'moderator', 'support');
|
|
73
|
+
*/
|
|
74
|
+
export function requireAnyRole(...roles: string[]) {
|
|
75
|
+
return anyOf(...roles.map(hasRole));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Guard factory for multiple roles (all required)
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* const isSuperAdmin = requireAllRoles('admin', 'verified');
|
|
83
|
+
*/
|
|
84
|
+
export function requireAllRoles(...roles: string[]) {
|
|
85
|
+
return allOf(...roles.map(hasRole));
|
|
86
|
+
}
|
|
87
|
+
`;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Generate permission-based guard
|
|
91
|
+
*/
|
|
92
|
+
function generatePermissionGuard(ctx) {
|
|
93
|
+
const { entity } = ctx;
|
|
94
|
+
return `/**
|
|
95
|
+
* ${entity.pascal} Permission Guard
|
|
96
|
+
*
|
|
97
|
+
* Fine-grained permission-based access control.
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
import { hasPermission, allOf, anyOf, authenticated } from '@veloxts/auth';
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* ${entity.pascal} permissions
|
|
104
|
+
*/
|
|
105
|
+
export const ${entity.pascal}Permissions = {
|
|
106
|
+
READ: '${entity.snake}:read',
|
|
107
|
+
CREATE: '${entity.snake}:create',
|
|
108
|
+
UPDATE: '${entity.snake}:update',
|
|
109
|
+
DELETE: '${entity.snake}:delete',
|
|
110
|
+
MANAGE: '${entity.snake}:manage',
|
|
111
|
+
} as const;
|
|
112
|
+
|
|
113
|
+
type ${entity.pascal}Permission = (typeof ${entity.pascal}Permissions)[keyof typeof ${entity.pascal}Permissions];
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Can read ${entity.humanReadable}
|
|
117
|
+
*/
|
|
118
|
+
export const canRead${entity.pascal} = hasPermission(${entity.pascal}Permissions.READ);
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Can create ${entity.humanReadable}
|
|
122
|
+
*/
|
|
123
|
+
export const canCreate${entity.pascal} = hasPermission(${entity.pascal}Permissions.CREATE);
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Can update ${entity.humanReadable}
|
|
127
|
+
*/
|
|
128
|
+
export const canUpdate${entity.pascal} = hasPermission(${entity.pascal}Permissions.UPDATE);
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Can delete ${entity.humanReadable}
|
|
132
|
+
*/
|
|
133
|
+
export const canDelete${entity.pascal} = hasPermission(${entity.pascal}Permissions.DELETE);
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Full ${entity.humanReadable} management (all permissions)
|
|
137
|
+
*/
|
|
138
|
+
export const canManage${entity.pascal} = anyOf(
|
|
139
|
+
hasPermission(${entity.pascal}Permissions.MANAGE),
|
|
140
|
+
allOf(
|
|
141
|
+
canRead${entity.pascal},
|
|
142
|
+
canCreate${entity.pascal},
|
|
143
|
+
canUpdate${entity.pascal},
|
|
144
|
+
canDelete${entity.pascal}
|
|
145
|
+
)
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Guard factory for permission checking
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* procedure.guard(require${entity.pascal}Permission('read')).query(...)
|
|
153
|
+
*/
|
|
154
|
+
export function require${entity.pascal}Permission(action: keyof typeof ${entity.pascal}Permissions) {
|
|
155
|
+
return hasPermission(${entity.pascal}Permissions[action]);
|
|
156
|
+
}
|
|
157
|
+
`;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Generate ownership guard
|
|
161
|
+
*/
|
|
162
|
+
function generateOwnershipGuard(ctx) {
|
|
163
|
+
const { entity } = ctx;
|
|
164
|
+
return `/**
|
|
165
|
+
* ${entity.pascal} Ownership Guard
|
|
166
|
+
*
|
|
167
|
+
* Guards based on resource ownership.
|
|
168
|
+
*/
|
|
169
|
+
|
|
170
|
+
import type { BaseContext, Guard } from '@veloxts/router';
|
|
171
|
+
import { allOf, authenticated } from '@veloxts/auth';
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Create an ownership guard for ${entity.humanReadable}
|
|
175
|
+
*
|
|
176
|
+
* Checks if the authenticated user owns the requested resource.
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* const owns${entity.pascal} = createOwnershipGuard(
|
|
180
|
+
* async (ctx, input) => {
|
|
181
|
+
* const ${entity.camel} = await ctx.db.${entity.camel}.findUnique({
|
|
182
|
+
* where: { id: input.id }
|
|
183
|
+
* });
|
|
184
|
+
* return ${entity.camel}?.userId === ctx.user?.id;
|
|
185
|
+
* }
|
|
186
|
+
* );
|
|
187
|
+
*
|
|
188
|
+
* procedure.guard(owns${entity.pascal}).mutation(...)
|
|
189
|
+
*/
|
|
190
|
+
export function createOwnershipGuard<TInput = unknown>(
|
|
191
|
+
checkOwnership: (ctx: BaseContext, input: TInput) => Promise<boolean> | boolean
|
|
192
|
+
): Guard {
|
|
193
|
+
return async (ctx: BaseContext, input: unknown) => {
|
|
194
|
+
if (!ctx.user) {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
return checkOwnership(ctx, input as TInput);
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* ${entity.pascal} ownership guard
|
|
203
|
+
*
|
|
204
|
+
* Checks if user owns the ${entity.humanReadable} by matching userId field.
|
|
205
|
+
*/
|
|
206
|
+
export const owns${entity.pascal} = createOwnershipGuard<{ id: string }>(
|
|
207
|
+
async (ctx, input) => {
|
|
208
|
+
// TODO: Implement ownership check
|
|
209
|
+
// Example:
|
|
210
|
+
// const ${entity.camel} = await ctx.db.${entity.camel}.findUnique({
|
|
211
|
+
// where: { id: input.id },
|
|
212
|
+
// select: { userId: true },
|
|
213
|
+
// });
|
|
214
|
+
// return ${entity.camel}?.userId === ctx.user?.id;
|
|
215
|
+
|
|
216
|
+
throw new Error('Ownership check not implemented');
|
|
217
|
+
}
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Require authentication AND ownership
|
|
222
|
+
*/
|
|
223
|
+
export const authenticatedOwner = allOf(authenticated, owns${entity.pascal});
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Create a guard that allows owners OR admins
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* procedure.guard(ownerOrAdmin).mutation(...)
|
|
230
|
+
*/
|
|
231
|
+
export function ownerOrRole<TInput = unknown>(
|
|
232
|
+
role: string,
|
|
233
|
+
checkOwnership: (ctx: BaseContext, input: TInput) => Promise<boolean> | boolean
|
|
234
|
+
): Guard {
|
|
235
|
+
return async (ctx: BaseContext, input: unknown) => {
|
|
236
|
+
if (!ctx.user) {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Admin bypass
|
|
241
|
+
if (ctx.user.role === role) {
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Check ownership
|
|
246
|
+
return checkOwnership(ctx, input as TInput);
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
`;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Generate composite guard
|
|
253
|
+
*/
|
|
254
|
+
function generateCompositeGuard(ctx) {
|
|
255
|
+
const { entity } = ctx;
|
|
256
|
+
return `/**
|
|
257
|
+
* ${entity.pascal} Composite Guards
|
|
258
|
+
*
|
|
259
|
+
* Complex guard compositions for sophisticated access control.
|
|
260
|
+
*/
|
|
261
|
+
|
|
262
|
+
import type { BaseContext, Guard } from '@veloxts/router';
|
|
263
|
+
import { allOf, anyOf, not, authenticated, hasRole, hasPermission } from '@veloxts/auth';
|
|
264
|
+
|
|
265
|
+
// ============================================================================
|
|
266
|
+
// Guard Composition Utilities
|
|
267
|
+
// ============================================================================
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Create a conditional guard
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* const conditionalGuard = when(
|
|
274
|
+
* ctx => ctx.user?.tier === 'premium',
|
|
275
|
+
* premiumOnlyGuard,
|
|
276
|
+
* freeUserGuard
|
|
277
|
+
* );
|
|
278
|
+
*/
|
|
279
|
+
export function when(
|
|
280
|
+
condition: (ctx: BaseContext) => boolean | Promise<boolean>,
|
|
281
|
+
thenGuard: Guard,
|
|
282
|
+
elseGuard?: Guard
|
|
283
|
+
): Guard {
|
|
284
|
+
return async (ctx: BaseContext, input: unknown) => {
|
|
285
|
+
const result = await condition(ctx);
|
|
286
|
+
if (result) {
|
|
287
|
+
return thenGuard(ctx, input);
|
|
288
|
+
}
|
|
289
|
+
return elseGuard ? elseGuard(ctx, input) : true;
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Create a guard that requires N of M conditions
|
|
295
|
+
*
|
|
296
|
+
* @example
|
|
297
|
+
* const twoFactorAuth = requireN(2, [
|
|
298
|
+
* hasPassword,
|
|
299
|
+
* hasEmailVerified,
|
|
300
|
+
* has2FAEnabled,
|
|
301
|
+
* ]);
|
|
302
|
+
*/
|
|
303
|
+
export function requireN(n: number, guards: Guard[]): Guard {
|
|
304
|
+
return async (ctx: BaseContext, input: unknown) => {
|
|
305
|
+
let passed = 0;
|
|
306
|
+
for (const guard of guards) {
|
|
307
|
+
if (await guard(ctx, input)) {
|
|
308
|
+
passed++;
|
|
309
|
+
if (passed >= n) return true;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return false;
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// ============================================================================
|
|
317
|
+
// ${entity.pascal} Guards
|
|
318
|
+
// ============================================================================
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* ${entity.pascal} access levels
|
|
322
|
+
*/
|
|
323
|
+
export const ${entity.pascal}Guards = {
|
|
324
|
+
/** Basic authenticated access */
|
|
325
|
+
basic: authenticated,
|
|
326
|
+
|
|
327
|
+
/** ${entity.pascal} role required */
|
|
328
|
+
${entity.camel}: allOf(authenticated, hasRole('${entity.snake}')),
|
|
329
|
+
|
|
330
|
+
/** Admin access */
|
|
331
|
+
admin: allOf(authenticated, hasRole('admin')),
|
|
332
|
+
|
|
333
|
+
/** ${entity.pascal} or admin */
|
|
334
|
+
${entity.camel}OrAdmin: allOf(
|
|
335
|
+
authenticated,
|
|
336
|
+
anyOf(hasRole('${entity.snake}'), hasRole('admin'))
|
|
337
|
+
),
|
|
338
|
+
|
|
339
|
+
/** Not banned users only */
|
|
340
|
+
notBanned: allOf(authenticated, not(hasRole('banned'))),
|
|
341
|
+
|
|
342
|
+
/** Premium tier access */
|
|
343
|
+
premium: allOf(
|
|
344
|
+
authenticated,
|
|
345
|
+
anyOf(hasRole('premium'), hasRole('admin'))
|
|
346
|
+
),
|
|
347
|
+
} as const;
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Time-based guard
|
|
351
|
+
*
|
|
352
|
+
* Only allows access during specified hours (server time).
|
|
353
|
+
*/
|
|
354
|
+
export function duringHours(startHour: number, endHour: number): Guard {
|
|
355
|
+
return async () => {
|
|
356
|
+
const hour = new Date().getHours();
|
|
357
|
+
return hour >= startHour && hour < endHour;
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Rate-aware guard
|
|
363
|
+
*
|
|
364
|
+
* Denies access if user has exceeded rate limit.
|
|
365
|
+
*/
|
|
366
|
+
export function underRateLimit(
|
|
367
|
+
limit: number,
|
|
368
|
+
getCount: (ctx: BaseContext) => Promise<number>
|
|
369
|
+
): Guard {
|
|
370
|
+
return async (ctx: BaseContext) => {
|
|
371
|
+
const count = await getCount(ctx);
|
|
372
|
+
return count < limit;
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Feature flag guard
|
|
378
|
+
*
|
|
379
|
+
* Only allows access when feature is enabled.
|
|
380
|
+
*/
|
|
381
|
+
export function featureEnabled(
|
|
382
|
+
featureName: string,
|
|
383
|
+
checkFeature: (name: string, ctx: BaseContext) => Promise<boolean>
|
|
384
|
+
): Guard {
|
|
385
|
+
return async (ctx: BaseContext) => {
|
|
386
|
+
return checkFeature(featureName, ctx);
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
`;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Generate simple guard template
|
|
393
|
+
*/
|
|
394
|
+
function generateSimpleGuard(ctx) {
|
|
395
|
+
const { entity } = ctx;
|
|
396
|
+
return `/**
|
|
397
|
+
* ${entity.pascal} Guard
|
|
398
|
+
*
|
|
399
|
+
* Custom authentication guard for VeloxTS procedures.
|
|
400
|
+
*/
|
|
401
|
+
|
|
402
|
+
import type { BaseContext, Guard } from '@veloxts/router';
|
|
403
|
+
import { allOf, anyOf, not, authenticated, hasRole, hasPermission } from '@veloxts/auth';
|
|
404
|
+
|
|
405
|
+
// ============================================================================
|
|
406
|
+
// Guard Definitions
|
|
407
|
+
// ============================================================================
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* ${entity.pascal} guard - checks if user has ${entity.humanReadable} access
|
|
411
|
+
*
|
|
412
|
+
* @example
|
|
413
|
+
* procedure.guard(${entity.camel}Guard).query(...)
|
|
414
|
+
*/
|
|
415
|
+
export const ${entity.camel}Guard: Guard = async (ctx: BaseContext, _input: unknown) => {
|
|
416
|
+
// Require authentication first
|
|
417
|
+
if (!ctx.user) {
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// TODO: Add your guard logic here
|
|
422
|
+
// Examples:
|
|
423
|
+
// - Check user role: return ctx.user.role === '${entity.snake}';
|
|
424
|
+
// - Check permission: return ctx.user.permissions.includes('${entity.snake}:access');
|
|
425
|
+
// - Check subscription: return ctx.user.subscriptionTier === 'premium';
|
|
426
|
+
|
|
427
|
+
return true;
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Authenticated ${entity.pascal} guard
|
|
432
|
+
*
|
|
433
|
+
* Combines authentication check with ${entity.humanReadable} specific logic.
|
|
434
|
+
*/
|
|
435
|
+
export const authenticated${entity.pascal} = allOf(authenticated, ${entity.camel}Guard);
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* ${entity.pascal} or admin guard
|
|
439
|
+
*
|
|
440
|
+
* Allows access if user is ${entity.humanReadable} OR admin.
|
|
441
|
+
*/
|
|
442
|
+
export const ${entity.camel}OrAdmin = allOf(
|
|
443
|
+
authenticated,
|
|
444
|
+
anyOf(${entity.camel}Guard, hasRole('admin'))
|
|
445
|
+
);
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Not ${entity.pascal} guard
|
|
449
|
+
*
|
|
450
|
+
* Denies access to ${entity.humanReadable} users (inverted guard).
|
|
451
|
+
*/
|
|
452
|
+
export const not${entity.pascal} = not(${entity.camel}Guard);
|
|
453
|
+
|
|
454
|
+
// ============================================================================
|
|
455
|
+
// Guard Factory
|
|
456
|
+
// ============================================================================
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Create a custom guard with specific requirements
|
|
460
|
+
*
|
|
461
|
+
* @example
|
|
462
|
+
* const premiumOnly = create${entity.pascal}Guard({
|
|
463
|
+
* minLevel: 10,
|
|
464
|
+
* requiredBadges: ['verified'],
|
|
465
|
+
* });
|
|
466
|
+
*/
|
|
467
|
+
export interface ${entity.pascal}GuardOptions {
|
|
468
|
+
/** Minimum user level required */
|
|
469
|
+
minLevel?: number;
|
|
470
|
+
/** Required badges/achievements */
|
|
471
|
+
requiredBadges?: string[];
|
|
472
|
+
/** Custom check function */
|
|
473
|
+
customCheck?: (ctx: BaseContext) => boolean | Promise<boolean>;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
export function create${entity.pascal}Guard(options: ${entity.pascal}GuardOptions = {}): Guard {
|
|
477
|
+
return async (ctx: BaseContext, _input: unknown) => {
|
|
478
|
+
if (!ctx.user) {
|
|
479
|
+
return false;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// Check minimum level
|
|
483
|
+
if (options.minLevel !== undefined) {
|
|
484
|
+
const userLevel = (ctx.user as { level?: number }).level ?? 0;
|
|
485
|
+
if (userLevel < options.minLevel) {
|
|
486
|
+
return false;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// Check required badges
|
|
491
|
+
if (options.requiredBadges?.length) {
|
|
492
|
+
const userBadges = (ctx.user as { badges?: string[] }).badges ?? [];
|
|
493
|
+
const hasAllBadges = options.requiredBadges.every((badge) =>
|
|
494
|
+
userBadges.includes(badge)
|
|
495
|
+
);
|
|
496
|
+
if (!hasAllBadges) {
|
|
497
|
+
return false;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// Custom check
|
|
502
|
+
if (options.customCheck) {
|
|
503
|
+
return options.customCheck(ctx);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
return true;
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
`;
|
|
510
|
+
}
|
|
511
|
+
// ============================================================================
|
|
512
|
+
// Main Template
|
|
513
|
+
// ============================================================================
|
|
514
|
+
/**
|
|
515
|
+
* Guard template function
|
|
516
|
+
*/
|
|
517
|
+
export const guardTemplate = (ctx) => {
|
|
518
|
+
if (ctx.options.role) {
|
|
519
|
+
return generateRoleGuard(ctx);
|
|
520
|
+
}
|
|
521
|
+
if (ctx.options.permission) {
|
|
522
|
+
return generatePermissionGuard(ctx);
|
|
523
|
+
}
|
|
524
|
+
if (ctx.options.ownership) {
|
|
525
|
+
return generateOwnershipGuard(ctx);
|
|
526
|
+
}
|
|
527
|
+
if (ctx.options.composite) {
|
|
528
|
+
return generateCompositeGuard(ctx);
|
|
529
|
+
}
|
|
530
|
+
return generateSimpleGuard(ctx);
|
|
531
|
+
};
|
|
532
|
+
// ============================================================================
|
|
533
|
+
// Post-generation Instructions
|
|
534
|
+
// ============================================================================
|
|
535
|
+
export function getGuardInstructions(entityName, options) {
|
|
536
|
+
const lines = [`Your ${entityName} guard has been created.`, '', 'Next steps:'];
|
|
537
|
+
lines.push(' 1. Import the guard in your procedures:');
|
|
538
|
+
lines.push(` import { ${entityName}Guard } from '@/guards/${entityName.toLowerCase()}';`);
|
|
539
|
+
lines.push(' 2. Apply to procedures:');
|
|
540
|
+
lines.push(` procedure.guard(${entityName}Guard).query(...)`);
|
|
541
|
+
if (options.role) {
|
|
542
|
+
lines.push(' 3. Ensure user roles are set in your auth flow');
|
|
543
|
+
}
|
|
544
|
+
else if (options.permission) {
|
|
545
|
+
lines.push(' 3. Set up permission storage in your user model');
|
|
546
|
+
}
|
|
547
|
+
else if (options.ownership) {
|
|
548
|
+
lines.push(' 3. Implement the ownership check logic');
|
|
549
|
+
}
|
|
550
|
+
else if (options.composite) {
|
|
551
|
+
lines.push(' 3. Customize the guard compositions for your needs');
|
|
552
|
+
}
|
|
553
|
+
return lines.join('\n');
|
|
554
|
+
}
|
|
555
|
+
//# sourceMappingURL=guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../../../src/generators/templates/guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layout Template
|
|
3
|
+
*
|
|
4
|
+
* Generates RSC layout files for VeloxTS full-stack applications.
|
|
5
|
+
*/
|
|
6
|
+
import type { TemplateFunction } from '../types.js';
|
|
7
|
+
export interface LayoutOptions {
|
|
8
|
+
/** Include header navigation */
|
|
9
|
+
header: boolean;
|
|
10
|
+
/** Include footer */
|
|
11
|
+
footer: boolean;
|
|
12
|
+
/** Include sidebar navigation */
|
|
13
|
+
sidebar: boolean;
|
|
14
|
+
/** Root layout with html/body tags */
|
|
15
|
+
root: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Get the path for a layout file
|
|
19
|
+
*/
|
|
20
|
+
export declare function getLayoutPath(entityName: string, project: {
|
|
21
|
+
layoutsDir?: string;
|
|
22
|
+
}): string;
|
|
23
|
+
/**
|
|
24
|
+
* Layout template function
|
|
25
|
+
*/
|
|
26
|
+
export declare const layoutTemplate: TemplateFunction<LayoutOptions>;
|
|
27
|
+
export declare function getLayoutInstructions(entityName: string, options: LayoutOptions): string;
|
|
28
|
+
//# sourceMappingURL=layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/generators/templates/layout.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAMrE,MAAM,WAAW,aAAa;IAC5B,gCAAgC;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,qBAAqB;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,iCAAiC;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,sCAAsC;IACtC,IAAI,EAAE,OAAO,CAAC;CACf;AAMD;;GAEG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAU1F;AA4GD;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,gBAAgB,CAAC,aAAa,CAK1D,CAAC;AAMF,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAkBxF"}
|