@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,499 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy Template
|
|
3
|
+
*
|
|
4
|
+
* Generates authorization policy files for VeloxTS applications.
|
|
5
|
+
*/
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// Path Helpers
|
|
8
|
+
// ============================================================================
|
|
9
|
+
/**
|
|
10
|
+
* Get the path for a policy file
|
|
11
|
+
*/
|
|
12
|
+
export function getPolicyPath(entityName, _project) {
|
|
13
|
+
return `src/policies/${entityName.toLowerCase()}.ts`;
|
|
14
|
+
}
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Templates
|
|
17
|
+
// ============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* Generate CRUD policy
|
|
20
|
+
*/
|
|
21
|
+
function generateCrudPolicy(ctx) {
|
|
22
|
+
const { entity, options } = ctx;
|
|
23
|
+
const softDeleteMethods = options.softDelete
|
|
24
|
+
? `
|
|
25
|
+
/**
|
|
26
|
+
* Can user restore this ${entity.humanReadable}?
|
|
27
|
+
*/
|
|
28
|
+
async restore(user: User, ${entity.camel}: ${entity.pascal}): Promise<boolean> {
|
|
29
|
+
// Only admins can restore
|
|
30
|
+
return user.role === 'admin';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Can user force delete this ${entity.humanReadable}?
|
|
35
|
+
*/
|
|
36
|
+
async forceDelete(user: User, ${entity.camel}: ${entity.pascal}): Promise<boolean> {
|
|
37
|
+
// Only admins can force delete
|
|
38
|
+
return user.role === 'admin';
|
|
39
|
+
}
|
|
40
|
+
`
|
|
41
|
+
: '';
|
|
42
|
+
return `/**
|
|
43
|
+
* ${entity.pascal} Policy
|
|
44
|
+
*
|
|
45
|
+
* Authorization rules for ${entity.humanReadable} operations.
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
import type { BaseContext } from '@veloxts/core';
|
|
49
|
+
|
|
50
|
+
// ============================================================================
|
|
51
|
+
// Types
|
|
52
|
+
// ============================================================================
|
|
53
|
+
|
|
54
|
+
interface User {
|
|
55
|
+
id: string;
|
|
56
|
+
role: string;
|
|
57
|
+
permissions?: string[];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
interface ${entity.pascal} {
|
|
61
|
+
id: string;
|
|
62
|
+
userId: string;
|
|
63
|
+
// TODO: Add more fields
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ============================================================================
|
|
67
|
+
// Policy Class
|
|
68
|
+
// ============================================================================
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* ${entity.pascal} authorization policy
|
|
72
|
+
*
|
|
73
|
+
* Centralizes authorization logic for ${entity.humanReadable} resources.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* const policy = new ${entity.pascal}Policy();
|
|
77
|
+
* if (await policy.update(user, ${entity.camel})) {
|
|
78
|
+
* // Allow update
|
|
79
|
+
* }
|
|
80
|
+
*/
|
|
81
|
+
export class ${entity.pascal}Policy {
|
|
82
|
+
/**
|
|
83
|
+
* Can user view any ${entity.humanReadable}?
|
|
84
|
+
*/
|
|
85
|
+
async viewAny(user: User): Promise<boolean> {
|
|
86
|
+
// All authenticated users can list
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Can user view this ${entity.humanReadable}?
|
|
92
|
+
*/
|
|
93
|
+
async view(user: User, ${entity.camel}: ${entity.pascal}): Promise<boolean> {
|
|
94
|
+
// Owner or admin can view
|
|
95
|
+
return ${entity.camel}.userId === user.id || user.role === 'admin';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Can user create ${entity.humanReadable}?
|
|
100
|
+
*/
|
|
101
|
+
async create(user: User): Promise<boolean> {
|
|
102
|
+
// All authenticated users can create
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Can user update this ${entity.humanReadable}?
|
|
108
|
+
*/
|
|
109
|
+
async update(user: User, ${entity.camel}: ${entity.pascal}): Promise<boolean> {
|
|
110
|
+
// Only owner or admin can update
|
|
111
|
+
return ${entity.camel}.userId === user.id || user.role === 'admin';
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Can user delete this ${entity.humanReadable}?
|
|
116
|
+
*/
|
|
117
|
+
async delete(user: User, ${entity.camel}: ${entity.pascal}): Promise<boolean> {
|
|
118
|
+
// Only owner or admin can delete
|
|
119
|
+
return ${entity.camel}.userId === user.id || user.role === 'admin';
|
|
120
|
+
}
|
|
121
|
+
${softDeleteMethods}}
|
|
122
|
+
|
|
123
|
+
// ============================================================================
|
|
124
|
+
// Policy Instance
|
|
125
|
+
// ============================================================================
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Singleton policy instance
|
|
129
|
+
*/
|
|
130
|
+
export const ${entity.camel}Policy = new ${entity.pascal}Policy();
|
|
131
|
+
|
|
132
|
+
// ============================================================================
|
|
133
|
+
// Guard Integration
|
|
134
|
+
// ============================================================================
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Create a guard from a policy method
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* procedure.guard(policyGuard('update')).mutation(...)
|
|
141
|
+
*/
|
|
142
|
+
export function ${entity.camel}PolicyGuard(
|
|
143
|
+
action: keyof ${entity.pascal}Policy
|
|
144
|
+
) {
|
|
145
|
+
return async (ctx: BaseContext, input: unknown) => {
|
|
146
|
+
if (!ctx.user) return false;
|
|
147
|
+
|
|
148
|
+
const policy = new ${entity.pascal}Policy();
|
|
149
|
+
const method = policy[action] as (user: User, resource?: ${entity.pascal}) => Promise<boolean>;
|
|
150
|
+
|
|
151
|
+
// For methods that require a resource
|
|
152
|
+
if (action === 'view' || action === 'update' || action === 'delete') {
|
|
153
|
+
// TODO: Fetch the resource
|
|
154
|
+
// const ${entity.camel} = await ctx.db.${entity.camel}.findUnique({ where: { id: (input as { id: string }).id } });
|
|
155
|
+
// return method.call(policy, ctx.user as User, ${entity.camel});
|
|
156
|
+
throw new Error('Resource fetch not implemented');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// For methods that don't require a resource
|
|
160
|
+
return method.call(policy, ctx.user as User);
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
`;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Generate resource-based policy
|
|
167
|
+
*/
|
|
168
|
+
function generateResourcePolicy(ctx) {
|
|
169
|
+
const { entity } = ctx;
|
|
170
|
+
return `/**
|
|
171
|
+
* ${entity.pascal} Resource Policy
|
|
172
|
+
*
|
|
173
|
+
* Attribute-based access control for ${entity.humanReadable} resources.
|
|
174
|
+
*/
|
|
175
|
+
|
|
176
|
+
import type { BaseContext } from '@veloxts/core';
|
|
177
|
+
|
|
178
|
+
// ============================================================================
|
|
179
|
+
// Types
|
|
180
|
+
// ============================================================================
|
|
181
|
+
|
|
182
|
+
interface User {
|
|
183
|
+
id: string;
|
|
184
|
+
role: string;
|
|
185
|
+
teamId?: string;
|
|
186
|
+
permissions?: string[];
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
interface ${entity.pascal} {
|
|
190
|
+
id: string;
|
|
191
|
+
userId: string;
|
|
192
|
+
teamId?: string;
|
|
193
|
+
visibility: 'public' | 'private' | 'team';
|
|
194
|
+
status: 'draft' | 'published' | 'archived';
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
type Action = 'view' | 'create' | 'update' | 'delete' | 'publish' | 'archive';
|
|
198
|
+
|
|
199
|
+
// ============================================================================
|
|
200
|
+
// Policy Definition
|
|
201
|
+
// ============================================================================
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Policy rules for ${entity.humanReadable}
|
|
205
|
+
*/
|
|
206
|
+
interface PolicyRule {
|
|
207
|
+
/** Actions this rule applies to */
|
|
208
|
+
actions: Action[];
|
|
209
|
+
/** Condition that must be true */
|
|
210
|
+
condition: (user: User, resource?: ${entity.pascal}) => boolean;
|
|
211
|
+
/** Description for debugging */
|
|
212
|
+
description: string;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const ${entity.camel}Rules: PolicyRule[] = [
|
|
216
|
+
// Admin can do anything
|
|
217
|
+
{
|
|
218
|
+
actions: ['view', 'create', 'update', 'delete', 'publish', 'archive'],
|
|
219
|
+
condition: (user) => user.role === 'admin',
|
|
220
|
+
description: 'Admins have full access',
|
|
221
|
+
},
|
|
222
|
+
|
|
223
|
+
// Owners can manage their own resources
|
|
224
|
+
{
|
|
225
|
+
actions: ['view', 'update', 'delete'],
|
|
226
|
+
condition: (user, resource) => resource?.userId === user.id,
|
|
227
|
+
description: 'Owners can manage their resources',
|
|
228
|
+
},
|
|
229
|
+
|
|
230
|
+
// Team members can view team resources
|
|
231
|
+
{
|
|
232
|
+
actions: ['view'],
|
|
233
|
+
condition: (user, resource) =>
|
|
234
|
+
resource?.visibility === 'team' && resource?.teamId === user.teamId,
|
|
235
|
+
description: 'Team members can view team resources',
|
|
236
|
+
},
|
|
237
|
+
|
|
238
|
+
// Anyone can view public resources
|
|
239
|
+
{
|
|
240
|
+
actions: ['view'],
|
|
241
|
+
condition: (_, resource) =>
|
|
242
|
+
resource?.visibility === 'public' && resource?.status === 'published',
|
|
243
|
+
description: 'Public published resources are viewable by all',
|
|
244
|
+
},
|
|
245
|
+
|
|
246
|
+
// Authenticated users can create
|
|
247
|
+
{
|
|
248
|
+
actions: ['create'],
|
|
249
|
+
condition: (user) => !!user.id,
|
|
250
|
+
description: 'Authenticated users can create resources',
|
|
251
|
+
},
|
|
252
|
+
|
|
253
|
+
// Only owners can publish
|
|
254
|
+
{
|
|
255
|
+
actions: ['publish'],
|
|
256
|
+
condition: (user, resource) =>
|
|
257
|
+
resource?.userId === user.id && resource?.status === 'draft',
|
|
258
|
+
description: 'Owners can publish draft resources',
|
|
259
|
+
},
|
|
260
|
+
];
|
|
261
|
+
|
|
262
|
+
// ============================================================================
|
|
263
|
+
// Policy Evaluation
|
|
264
|
+
// ============================================================================
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Check if user can perform action on ${entity.humanReadable}
|
|
268
|
+
*/
|
|
269
|
+
export function can${entity.pascal}(
|
|
270
|
+
user: User,
|
|
271
|
+
action: Action,
|
|
272
|
+
resource?: ${entity.pascal}
|
|
273
|
+
): boolean {
|
|
274
|
+
for (const rule of ${entity.camel}Rules) {
|
|
275
|
+
if (rule.actions.includes(action) && rule.condition(user, resource)) {
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Get all allowed actions for user on ${entity.humanReadable}
|
|
284
|
+
*/
|
|
285
|
+
export function allowed${entity.pascal}Actions(
|
|
286
|
+
user: User,
|
|
287
|
+
resource?: ${entity.pascal}
|
|
288
|
+
): Action[] {
|
|
289
|
+
const allActions: Action[] = ['view', 'create', 'update', 'delete', 'publish', 'archive'];
|
|
290
|
+
return allActions.filter((action) => can${entity.pascal}(user, action, resource));
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Policy guard for procedures
|
|
295
|
+
*/
|
|
296
|
+
export function ${entity.camel}PolicyGuard(action: Action) {
|
|
297
|
+
return async (ctx: BaseContext, input: unknown) => {
|
|
298
|
+
if (!ctx.user) return false;
|
|
299
|
+
|
|
300
|
+
// For resource-specific actions, fetch the resource
|
|
301
|
+
if (action !== 'create') {
|
|
302
|
+
// TODO: Fetch resource and check
|
|
303
|
+
// const ${entity.camel} = await ctx.db.${entity.camel}.findUnique({ where: { id: (input as { id: string }).id } });
|
|
304
|
+
// return can${entity.pascal}(ctx.user as User, action, ${entity.camel});
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return can${entity.pascal}(ctx.user as User, action);
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Assert user can perform action, throw if not
|
|
313
|
+
*/
|
|
314
|
+
export function assert${entity.pascal}(
|
|
315
|
+
user: User,
|
|
316
|
+
action: Action,
|
|
317
|
+
resource?: ${entity.pascal}
|
|
318
|
+
): void {
|
|
319
|
+
if (!can${entity.pascal}(user, action, resource)) {
|
|
320
|
+
throw new Error(\`Unauthorized: cannot \${action} ${entity.humanReadable}\`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
`;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Generate simple policy template
|
|
327
|
+
*/
|
|
328
|
+
function generateSimplePolicy(ctx) {
|
|
329
|
+
const { entity } = ctx;
|
|
330
|
+
return `/**
|
|
331
|
+
* ${entity.pascal} Policy
|
|
332
|
+
*
|
|
333
|
+
* Authorization rules for ${entity.humanReadable} operations.
|
|
334
|
+
*/
|
|
335
|
+
|
|
336
|
+
import type { BaseContext } from '@veloxts/core';
|
|
337
|
+
|
|
338
|
+
// ============================================================================
|
|
339
|
+
// Types
|
|
340
|
+
// ============================================================================
|
|
341
|
+
|
|
342
|
+
interface User {
|
|
343
|
+
id: string;
|
|
344
|
+
role: string;
|
|
345
|
+
permissions?: string[];
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
interface ${entity.pascal} {
|
|
349
|
+
id: string;
|
|
350
|
+
userId: string;
|
|
351
|
+
// TODO: Add your ${entity.humanReadable} fields
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// ============================================================================
|
|
355
|
+
// Policy Functions
|
|
356
|
+
// ============================================================================
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Can user view ${entity.humanReadable}?
|
|
360
|
+
*/
|
|
361
|
+
export function canView${entity.pascal}(user: User, ${entity.camel}: ${entity.pascal}): boolean {
|
|
362
|
+
// TODO: Implement view authorization
|
|
363
|
+
return ${entity.camel}.userId === user.id || user.role === 'admin';
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Can user create ${entity.humanReadable}?
|
|
368
|
+
*/
|
|
369
|
+
export function canCreate${entity.pascal}(user: User): boolean {
|
|
370
|
+
// TODO: Implement create authorization
|
|
371
|
+
return true;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Can user update ${entity.humanReadable}?
|
|
376
|
+
*/
|
|
377
|
+
export function canUpdate${entity.pascal}(user: User, ${entity.camel}: ${entity.pascal}): boolean {
|
|
378
|
+
// TODO: Implement update authorization
|
|
379
|
+
return ${entity.camel}.userId === user.id || user.role === 'admin';
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Can user delete ${entity.humanReadable}?
|
|
384
|
+
*/
|
|
385
|
+
export function canDelete${entity.pascal}(user: User, ${entity.camel}: ${entity.pascal}): boolean {
|
|
386
|
+
// TODO: Implement delete authorization
|
|
387
|
+
return ${entity.camel}.userId === user.id || user.role === 'admin';
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// ============================================================================
|
|
391
|
+
// Guard Integration
|
|
392
|
+
// ============================================================================
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Policy guard factory
|
|
396
|
+
*
|
|
397
|
+
* Creates guards from policy functions for use with procedures.
|
|
398
|
+
*
|
|
399
|
+
* @example
|
|
400
|
+
* procedure.guard(${entity.camel}Guard('update')).mutation(...)
|
|
401
|
+
*/
|
|
402
|
+
export function ${entity.camel}Guard(action: 'view' | 'create' | 'update' | 'delete') {
|
|
403
|
+
return async (ctx: BaseContext, input: unknown) => {
|
|
404
|
+
if (!ctx.user) return false;
|
|
405
|
+
|
|
406
|
+
const user = ctx.user as User;
|
|
407
|
+
|
|
408
|
+
switch (action) {
|
|
409
|
+
case 'create':
|
|
410
|
+
return canCreate${entity.pascal}(user);
|
|
411
|
+
|
|
412
|
+
case 'view':
|
|
413
|
+
case 'update':
|
|
414
|
+
case 'delete': {
|
|
415
|
+
// TODO: Fetch the ${entity.humanReadable} from database
|
|
416
|
+
// const ${entity.camel} = await ctx.db.${entity.camel}.findUnique({
|
|
417
|
+
// where: { id: (input as { id: string }).id }
|
|
418
|
+
// });
|
|
419
|
+
// if (!${entity.camel}) return false;
|
|
420
|
+
|
|
421
|
+
// Placeholder - implement resource fetching
|
|
422
|
+
const ${entity.camel} = input as ${entity.pascal};
|
|
423
|
+
|
|
424
|
+
if (action === 'view') return canView${entity.pascal}(user, ${entity.camel});
|
|
425
|
+
if (action === 'update') return canUpdate${entity.pascal}(user, ${entity.camel});
|
|
426
|
+
if (action === 'delete') return canDelete${entity.pascal}(user, ${entity.camel});
|
|
427
|
+
return false;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
default:
|
|
431
|
+
return false;
|
|
432
|
+
}
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Assert policy, throw if unauthorized
|
|
438
|
+
*/
|
|
439
|
+
export function authorize${entity.pascal}(
|
|
440
|
+
action: 'view' | 'create' | 'update' | 'delete',
|
|
441
|
+
user: User,
|
|
442
|
+
${entity.camel}?: ${entity.pascal}
|
|
443
|
+
): void {
|
|
444
|
+
let allowed = false;
|
|
445
|
+
|
|
446
|
+
switch (action) {
|
|
447
|
+
case 'create':
|
|
448
|
+
allowed = canCreate${entity.pascal}(user);
|
|
449
|
+
break;
|
|
450
|
+
case 'view':
|
|
451
|
+
allowed = ${entity.camel} ? canView${entity.pascal}(user, ${entity.camel}) : false;
|
|
452
|
+
break;
|
|
453
|
+
case 'update':
|
|
454
|
+
allowed = ${entity.camel} ? canUpdate${entity.pascal}(user, ${entity.camel}) : false;
|
|
455
|
+
break;
|
|
456
|
+
case 'delete':
|
|
457
|
+
allowed = ${entity.camel} ? canDelete${entity.pascal}(user, ${entity.camel}) : false;
|
|
458
|
+
break;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
if (!allowed) {
|
|
462
|
+
throw new Error(\`Unauthorized: cannot \${action} ${entity.humanReadable}\`);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
`;
|
|
466
|
+
}
|
|
467
|
+
// ============================================================================
|
|
468
|
+
// Main Template
|
|
469
|
+
// ============================================================================
|
|
470
|
+
/**
|
|
471
|
+
* Policy template function
|
|
472
|
+
*/
|
|
473
|
+
export const policyTemplate = (ctx) => {
|
|
474
|
+
if (ctx.options.crud) {
|
|
475
|
+
return generateCrudPolicy(ctx);
|
|
476
|
+
}
|
|
477
|
+
if (ctx.options.resource) {
|
|
478
|
+
return generateResourcePolicy(ctx);
|
|
479
|
+
}
|
|
480
|
+
return generateSimplePolicy(ctx);
|
|
481
|
+
};
|
|
482
|
+
// ============================================================================
|
|
483
|
+
// Post-generation Instructions
|
|
484
|
+
// ============================================================================
|
|
485
|
+
export function getPolicyInstructions(entityName, options) {
|
|
486
|
+
const lines = [`Your ${entityName} policy has been created.`, '', 'Next steps:'];
|
|
487
|
+
lines.push(' 1. Update the policy functions with your authorization logic');
|
|
488
|
+
lines.push(' 2. Import and use in your procedures:');
|
|
489
|
+
lines.push(` import { ${entityName}Guard } from '@/policies/${entityName.toLowerCase()}';`);
|
|
490
|
+
lines.push(` procedure.guard(${entityName}Guard('update')).mutation(...)`);
|
|
491
|
+
if (options.crud) {
|
|
492
|
+
lines.push(' 3. Implement resource fetching in the guard');
|
|
493
|
+
}
|
|
494
|
+
else if (options.resource) {
|
|
495
|
+
lines.push(' 3. Customize the policy rules for your use case');
|
|
496
|
+
}
|
|
497
|
+
return lines.join('\n');
|
|
498
|
+
}
|
|
499
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../../src/generators/templates/policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Generates a complete resource with model, schema, procedures, and tests.
|
|
5
5
|
* This is the "full stack" generator for quickly scaffolding new entities.
|
|
6
6
|
*/
|
|
7
|
+
import type { FieldDefinition, FieldTypeInfo } from '../fields/types.js';
|
|
7
8
|
import type { GeneratedFile, TemplateContext } from '../types.js';
|
|
8
9
|
export interface ResourceOptions {
|
|
9
10
|
/** Include CRUD operations */
|
|
@@ -22,7 +23,71 @@ export interface ResourceOptions {
|
|
|
22
23
|
skipSchema: boolean;
|
|
23
24
|
/** Skip procedure generation */
|
|
24
25
|
skipProcedure: boolean;
|
|
26
|
+
/** Custom field definitions */
|
|
27
|
+
fields?: FieldDefinition[];
|
|
25
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Get field type info by type
|
|
31
|
+
*/
|
|
32
|
+
export declare function getFieldTypeInfo(type: FieldDefinition['type']): FieldTypeInfo | undefined;
|
|
33
|
+
/** Database type for Prisma native type support */
|
|
34
|
+
export type DatabaseType = 'sqlite' | 'postgresql' | 'mysql';
|
|
35
|
+
/**
|
|
36
|
+
* Convert a field definition to Prisma field line
|
|
37
|
+
*
|
|
38
|
+
* @param field - Field definition to convert
|
|
39
|
+
* @param database - Optional database type for native type modifiers (default: 'sqlite')
|
|
40
|
+
*/
|
|
41
|
+
export declare function fieldToPrisma(field: FieldDefinition, database?: DatabaseType): string;
|
|
42
|
+
/**
|
|
43
|
+
* Format default value for Prisma
|
|
44
|
+
*
|
|
45
|
+
* Different types require different formatting:
|
|
46
|
+
* - Strings: quoted ("value")
|
|
47
|
+
* - Numbers: unquoted (123, 3.14)
|
|
48
|
+
* - Booleans: unquoted (true, false)
|
|
49
|
+
* - Enums: unquoted (DRAFT, ACTIVE)
|
|
50
|
+
* - DateTime: function call (now())
|
|
51
|
+
* - JSON: not supported for defaults
|
|
52
|
+
*/
|
|
53
|
+
export declare function formatPrismaDefault(type: FieldDefinition['type'], value: string): string;
|
|
54
|
+
/**
|
|
55
|
+
* Convert a field definition to Zod schema field
|
|
56
|
+
*/
|
|
57
|
+
export declare function fieldToZod(field: FieldDefinition): string;
|
|
58
|
+
/**
|
|
59
|
+
* Generate Prisma enum definitions
|
|
60
|
+
*/
|
|
61
|
+
export declare function generatePrismaEnums(fields: FieldDefinition[]): string;
|
|
62
|
+
/**
|
|
63
|
+
* Structured enum definition for injection
|
|
64
|
+
*/
|
|
65
|
+
export interface InjectableEnumDef {
|
|
66
|
+
/** Enum name (PascalCase) */
|
|
67
|
+
readonly name: string;
|
|
68
|
+
/** Full enum content (including `enum Name { ... }`) */
|
|
69
|
+
readonly content: string;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Result of generating injectable Prisma content
|
|
73
|
+
*/
|
|
74
|
+
export interface InjectablePrismaContent {
|
|
75
|
+
/** Full model definition (for injection into schema.prisma) */
|
|
76
|
+
readonly modelContent: string;
|
|
77
|
+
/** Model name (PascalCase) */
|
|
78
|
+
readonly modelName: string;
|
|
79
|
+
/** Structured enum definitions (for injection before model) */
|
|
80
|
+
readonly enums: InjectableEnumDef[];
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Generate injectable Prisma content (model + enums without comments)
|
|
84
|
+
*
|
|
85
|
+
* This content can be directly injected into schema.prisma
|
|
86
|
+
*/
|
|
87
|
+
export declare function generateInjectablePrismaContent(entity: {
|
|
88
|
+
pascal: string;
|
|
89
|
+
camel: string;
|
|
90
|
+
}, options: ResourceOptions, database?: DatabaseType): InjectablePrismaContent;
|
|
26
91
|
/**
|
|
27
92
|
* Generate all files for a resource
|
|
28
93
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../../../src/generators/templates/resource.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAMlE,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,kCAAkC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,+BAA+B;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,0BAA0B;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,mCAAmC;IACnC,SAAS,EAAE,OAAO,CAAC;IACnB,6BAA6B;IAC7B,UAAU,EAAE,OAAO,CAAC;IACpB,gCAAgC;IAChC,aAAa,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../../../src/generators/templates/resource.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAMlE,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,kCAAkC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,+BAA+B;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,0BAA0B;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,mCAAmC;IACnC,SAAS,EAAE,OAAO,CAAC;IACnB,6BAA6B;IAC7B,UAAU,EAAE,OAAO,CAAC;IACpB,gCAAgC;IAChC,aAAa,EAAE,OAAO,CAAC;IACvB,+BAA+B;IAC/B,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;CAC5B;AAMD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,GAAG,aAAa,GAAG,SAAS,CAEzF;AAED,mDAAmD;AACnD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,YAAY,GAAG,OAAO,CAAC;AAE7D;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,eAAe,EAAE,QAAQ,GAAE,YAAuB,GAAG,MAAM,CAqC/F;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAuBxF;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAkBzD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,CAYrE;AAMD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,6BAA6B;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,+DAA+D;IAC/D,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,8BAA8B;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,KAAK,EAAE,iBAAiB,EAAE,CAAC;CACrC;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EACzC,OAAO,EAAE,eAAe,EACxB,QAAQ,GAAE,YAAuB,GAChC,uBAAuB,CAwDzB;AAkeD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,eAAe,CAAC,eAAe,CAAC,GAAG,aAAa,EAAE,CAqC5F;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,MAAM,CA0E5F"}
|