pocketbase-zod-schema 0.1.2
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/CHANGELOG.md +18 -0
- package/LICENSE +21 -0
- package/README.md +167 -0
- package/dist/cli/index.cjs +3383 -0
- package/dist/cli/index.cjs.map +1 -0
- package/dist/cli/index.d.cts +30 -0
- package/dist/cli/index.d.ts +30 -0
- package/dist/cli/index.js +3331 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/migrate.cjs +3380 -0
- package/dist/cli/migrate.cjs.map +1 -0
- package/dist/cli/migrate.d.cts +1 -0
- package/dist/cli/migrate.d.ts +1 -0
- package/dist/cli/migrate.js +3353 -0
- package/dist/cli/migrate.js.map +1 -0
- package/dist/cli/utils/index.cjs +540 -0
- package/dist/cli/utils/index.cjs.map +1 -0
- package/dist/cli/utils/index.d.cts +232 -0
- package/dist/cli/utils/index.d.ts +232 -0
- package/dist/cli/utils/index.js +487 -0
- package/dist/cli/utils/index.js.map +1 -0
- package/dist/enums.cjs +19 -0
- package/dist/enums.cjs.map +1 -0
- package/dist/enums.d.cts +6 -0
- package/dist/enums.d.ts +6 -0
- package/dist/enums.js +17 -0
- package/dist/enums.js.map +1 -0
- package/dist/index.cjs +4900 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +18 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +4726 -0
- package/dist/index.js.map +1 -0
- package/dist/migration/analyzer.cjs +1267 -0
- package/dist/migration/analyzer.cjs.map +1 -0
- package/dist/migration/analyzer.d.cts +186 -0
- package/dist/migration/analyzer.d.ts +186 -0
- package/dist/migration/analyzer.js +1232 -0
- package/dist/migration/analyzer.js.map +1 -0
- package/dist/migration/diff.cjs +557 -0
- package/dist/migration/diff.cjs.map +1 -0
- package/dist/migration/diff.d.cts +291 -0
- package/dist/migration/diff.d.ts +291 -0
- package/dist/migration/diff.js +534 -0
- package/dist/migration/diff.js.map +1 -0
- package/dist/migration/generator.cjs +778 -0
- package/dist/migration/generator.cjs.map +1 -0
- package/dist/migration/generator.d.cts +225 -0
- package/dist/migration/generator.d.ts +225 -0
- package/dist/migration/generator.js +737 -0
- package/dist/migration/generator.js.map +1 -0
- package/dist/migration/index.cjs +3390 -0
- package/dist/migration/index.cjs.map +1 -0
- package/dist/migration/index.d.cts +103 -0
- package/dist/migration/index.d.ts +103 -0
- package/dist/migration/index.js +3265 -0
- package/dist/migration/index.js.map +1 -0
- package/dist/migration/snapshot.cjs +609 -0
- package/dist/migration/snapshot.cjs.map +1 -0
- package/dist/migration/snapshot.d.cts +167 -0
- package/dist/migration/snapshot.d.ts +167 -0
- package/dist/migration/snapshot.js +575 -0
- package/dist/migration/snapshot.js.map +1 -0
- package/dist/migration/utils/index.cjs +672 -0
- package/dist/migration/utils/index.cjs.map +1 -0
- package/dist/migration/utils/index.d.cts +207 -0
- package/dist/migration/utils/index.d.ts +207 -0
- package/dist/migration/utils/index.js +641 -0
- package/dist/migration/utils/index.js.map +1 -0
- package/dist/mutator.cjs +427 -0
- package/dist/mutator.cjs.map +1 -0
- package/dist/mutator.d.cts +190 -0
- package/dist/mutator.d.ts +190 -0
- package/dist/mutator.js +425 -0
- package/dist/mutator.js.map +1 -0
- package/dist/permissions-ZHafVSIx.d.cts +71 -0
- package/dist/permissions-ZHafVSIx.d.ts +71 -0
- package/dist/schema.cjs +430 -0
- package/dist/schema.cjs.map +1 -0
- package/dist/schema.d.cts +316 -0
- package/dist/schema.d.ts +316 -0
- package/dist/schema.js +396 -0
- package/dist/schema.js.map +1 -0
- package/dist/types-BbTgmg6H.d.cts +91 -0
- package/dist/types-z1Dkjg8m.d.ts +91 -0
- package/dist/types.cjs +4 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +14 -0
- package/dist/types.d.ts +14 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/user-jS1aYoeD.d.cts +123 -0
- package/dist/user-jS1aYoeD.d.ts +123 -0
- package/package.json +165 -0
package/dist/schema.js
ADDED
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
// src/schema/base.ts
|
|
4
|
+
var baseSchema = {
|
|
5
|
+
id: z.string().describe("unique id"),
|
|
6
|
+
collectionId: z.string().describe("collection id"),
|
|
7
|
+
collectionName: z.string().describe("collection name"),
|
|
8
|
+
expand: z.record(z.any()).describe("expandable fields")
|
|
9
|
+
};
|
|
10
|
+
var baseSchemaWithTimestamps = {
|
|
11
|
+
...baseSchema,
|
|
12
|
+
created: z.string().describe("creation timestamp"),
|
|
13
|
+
updated: z.string().describe("last update timestamp")
|
|
14
|
+
};
|
|
15
|
+
var baseImageFileSchema = {
|
|
16
|
+
...baseSchema,
|
|
17
|
+
thumbnailURL: z.string().optional(),
|
|
18
|
+
imageFiles: z.array(z.string())
|
|
19
|
+
};
|
|
20
|
+
var inputImageFileSchema = {
|
|
21
|
+
imageFiles: z.array(z.instanceof(File))
|
|
22
|
+
};
|
|
23
|
+
var omitImageFilesSchema = {
|
|
24
|
+
imageFiles: true
|
|
25
|
+
};
|
|
26
|
+
function textField(options) {
|
|
27
|
+
let schema = z.string();
|
|
28
|
+
if (options?.min !== void 0) schema = schema.min(options.min);
|
|
29
|
+
if (options?.max !== void 0) schema = schema.max(options.max);
|
|
30
|
+
if (options?.pattern !== void 0) schema = schema.regex(options.pattern);
|
|
31
|
+
return schema;
|
|
32
|
+
}
|
|
33
|
+
function emailField() {
|
|
34
|
+
return z.string().email();
|
|
35
|
+
}
|
|
36
|
+
function urlField() {
|
|
37
|
+
return z.string().url();
|
|
38
|
+
}
|
|
39
|
+
function numberField(options) {
|
|
40
|
+
let schema = z.number();
|
|
41
|
+
if (options?.min !== void 0) schema = schema.min(options.min);
|
|
42
|
+
if (options?.max !== void 0) schema = schema.max(options.max);
|
|
43
|
+
return schema;
|
|
44
|
+
}
|
|
45
|
+
function boolField() {
|
|
46
|
+
return z.boolean();
|
|
47
|
+
}
|
|
48
|
+
function dateField() {
|
|
49
|
+
return z.date();
|
|
50
|
+
}
|
|
51
|
+
function selectField(values) {
|
|
52
|
+
return z.enum(values);
|
|
53
|
+
}
|
|
54
|
+
function jsonField(schema) {
|
|
55
|
+
return schema ?? z.record(z.any());
|
|
56
|
+
}
|
|
57
|
+
function fileField() {
|
|
58
|
+
return z.instanceof(File);
|
|
59
|
+
}
|
|
60
|
+
function filesField(options) {
|
|
61
|
+
let schema = z.array(z.instanceof(File));
|
|
62
|
+
if (options?.min !== void 0) schema = schema.min(options.min);
|
|
63
|
+
if (options?.max !== void 0) schema = schema.max(options.max);
|
|
64
|
+
return schema;
|
|
65
|
+
}
|
|
66
|
+
function relationField() {
|
|
67
|
+
return z.string();
|
|
68
|
+
}
|
|
69
|
+
function relationsField(options) {
|
|
70
|
+
let schema = z.array(z.string());
|
|
71
|
+
if (options?.min !== void 0) schema = schema.min(options.min);
|
|
72
|
+
if (options?.max !== void 0) schema = schema.max(options.max);
|
|
73
|
+
return schema;
|
|
74
|
+
}
|
|
75
|
+
function editorField() {
|
|
76
|
+
return z.string();
|
|
77
|
+
}
|
|
78
|
+
function geoPointField() {
|
|
79
|
+
return z.object({
|
|
80
|
+
lon: z.number(),
|
|
81
|
+
lat: z.number()
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function withPermissions(schema, config) {
|
|
85
|
+
const metadata = {
|
|
86
|
+
permissions: config
|
|
87
|
+
};
|
|
88
|
+
return schema.describe(JSON.stringify(metadata));
|
|
89
|
+
}
|
|
90
|
+
function withIndexes(schema, indexes) {
|
|
91
|
+
let existingMetadata = {};
|
|
92
|
+
if (schema.description) {
|
|
93
|
+
try {
|
|
94
|
+
existingMetadata = JSON.parse(schema.description);
|
|
95
|
+
} catch {
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const metadata = {
|
|
99
|
+
...existingMetadata,
|
|
100
|
+
indexes
|
|
101
|
+
};
|
|
102
|
+
return schema.describe(JSON.stringify(metadata));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// src/schema/permission-templates.ts
|
|
106
|
+
var PermissionTemplates = {
|
|
107
|
+
/**
|
|
108
|
+
* Public access - anyone can perform all operations
|
|
109
|
+
*/
|
|
110
|
+
public: () => ({
|
|
111
|
+
listRule: "",
|
|
112
|
+
viewRule: "",
|
|
113
|
+
createRule: "",
|
|
114
|
+
updateRule: "",
|
|
115
|
+
deleteRule: ""
|
|
116
|
+
}),
|
|
117
|
+
/**
|
|
118
|
+
* Authenticated users only - requires valid authentication for all operations
|
|
119
|
+
*/
|
|
120
|
+
authenticated: () => ({
|
|
121
|
+
listRule: '@request.auth.id != ""',
|
|
122
|
+
viewRule: '@request.auth.id != ""',
|
|
123
|
+
createRule: '@request.auth.id != ""',
|
|
124
|
+
updateRule: '@request.auth.id != ""',
|
|
125
|
+
deleteRule: '@request.auth.id != ""'
|
|
126
|
+
}),
|
|
127
|
+
/**
|
|
128
|
+
* Owner-only access - users can only manage their own records
|
|
129
|
+
* @param ownerField - Name of the relation field pointing to user (default: 'User')
|
|
130
|
+
*/
|
|
131
|
+
ownerOnly: (ownerField = "User") => ({
|
|
132
|
+
listRule: `@request.auth.id != "" && ${ownerField} = @request.auth.id`,
|
|
133
|
+
viewRule: `@request.auth.id != "" && ${ownerField} = @request.auth.id`,
|
|
134
|
+
createRule: '@request.auth.id != ""',
|
|
135
|
+
updateRule: `@request.auth.id != "" && ${ownerField} = @request.auth.id`,
|
|
136
|
+
deleteRule: `@request.auth.id != "" && ${ownerField} = @request.auth.id`
|
|
137
|
+
}),
|
|
138
|
+
/**
|
|
139
|
+
* Admin/superuser only access
|
|
140
|
+
* Assumes a 'role' field exists with 'admin' value
|
|
141
|
+
* @param roleField - Name of the role field (default: 'role')
|
|
142
|
+
*/
|
|
143
|
+
adminOnly: (roleField = "role") => ({
|
|
144
|
+
listRule: `@request.auth.id != "" && @request.auth.${roleField} = "admin"`,
|
|
145
|
+
viewRule: `@request.auth.id != "" && @request.auth.${roleField} = "admin"`,
|
|
146
|
+
createRule: `@request.auth.id != "" && @request.auth.${roleField} = "admin"`,
|
|
147
|
+
updateRule: `@request.auth.id != "" && @request.auth.${roleField} = "admin"`,
|
|
148
|
+
deleteRule: `@request.auth.id != "" && @request.auth.${roleField} = "admin"`
|
|
149
|
+
}),
|
|
150
|
+
/**
|
|
151
|
+
* Public read, authenticated write
|
|
152
|
+
* Anyone can list/view, but only authenticated users can create/update/delete
|
|
153
|
+
*/
|
|
154
|
+
readPublic: () => ({
|
|
155
|
+
listRule: "",
|
|
156
|
+
viewRule: "",
|
|
157
|
+
createRule: '@request.auth.id != ""',
|
|
158
|
+
updateRule: '@request.auth.id != ""',
|
|
159
|
+
deleteRule: '@request.auth.id != ""'
|
|
160
|
+
}),
|
|
161
|
+
/**
|
|
162
|
+
* Locked access - only superusers can perform operations
|
|
163
|
+
* All rules are set to null (locked)
|
|
164
|
+
*/
|
|
165
|
+
locked: () => ({
|
|
166
|
+
listRule: null,
|
|
167
|
+
viewRule: null,
|
|
168
|
+
createRule: null,
|
|
169
|
+
updateRule: null,
|
|
170
|
+
deleteRule: null
|
|
171
|
+
}),
|
|
172
|
+
/**
|
|
173
|
+
* Read-only authenticated - authenticated users can read, no write access
|
|
174
|
+
*/
|
|
175
|
+
readOnlyAuthenticated: () => ({
|
|
176
|
+
listRule: '@request.auth.id != ""',
|
|
177
|
+
viewRule: '@request.auth.id != ""',
|
|
178
|
+
createRule: null,
|
|
179
|
+
updateRule: null,
|
|
180
|
+
deleteRule: null
|
|
181
|
+
})
|
|
182
|
+
};
|
|
183
|
+
function resolveTemplate(config) {
|
|
184
|
+
let baseRules;
|
|
185
|
+
switch (config.template) {
|
|
186
|
+
case "public":
|
|
187
|
+
baseRules = PermissionTemplates.public();
|
|
188
|
+
break;
|
|
189
|
+
case "authenticated":
|
|
190
|
+
baseRules = PermissionTemplates.authenticated();
|
|
191
|
+
break;
|
|
192
|
+
case "owner-only":
|
|
193
|
+
baseRules = PermissionTemplates.ownerOnly(config.ownerField);
|
|
194
|
+
break;
|
|
195
|
+
case "admin-only":
|
|
196
|
+
baseRules = PermissionTemplates.adminOnly(config.roleField);
|
|
197
|
+
break;
|
|
198
|
+
case "read-public":
|
|
199
|
+
baseRules = PermissionTemplates.readPublic();
|
|
200
|
+
break;
|
|
201
|
+
case "custom":
|
|
202
|
+
baseRules = {};
|
|
203
|
+
break;
|
|
204
|
+
default: {
|
|
205
|
+
const _exhaustive = config.template;
|
|
206
|
+
throw new Error(`Unknown template type: ${_exhaustive}`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return {
|
|
210
|
+
...baseRules,
|
|
211
|
+
...config.customRules
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function isTemplateConfig(config) {
|
|
215
|
+
return "template" in config;
|
|
216
|
+
}
|
|
217
|
+
function isPermissionSchema(config) {
|
|
218
|
+
return "listRule" in config || "viewRule" in config || "createRule" in config || "updateRule" in config || "deleteRule" in config || "manageRule" in config;
|
|
219
|
+
}
|
|
220
|
+
function validatePermissionConfig(config, isAuthCollection = false) {
|
|
221
|
+
const result = {
|
|
222
|
+
valid: true,
|
|
223
|
+
errors: [],
|
|
224
|
+
warnings: []
|
|
225
|
+
};
|
|
226
|
+
let permissions;
|
|
227
|
+
if (isTemplateConfig(config)) {
|
|
228
|
+
if (config.template === "owner-only" && !config.ownerField) {
|
|
229
|
+
result.warnings.push("owner-only template without ownerField specified - using default 'User'");
|
|
230
|
+
}
|
|
231
|
+
if (config.template === "admin-only" && !config.roleField) {
|
|
232
|
+
result.warnings.push("admin-only template without roleField specified - using default 'role'");
|
|
233
|
+
}
|
|
234
|
+
permissions = resolveTemplate(config);
|
|
235
|
+
} else {
|
|
236
|
+
permissions = config;
|
|
237
|
+
}
|
|
238
|
+
if (permissions.manageRule !== void 0 && !isAuthCollection) {
|
|
239
|
+
result.errors.push("manageRule is only valid for auth collections");
|
|
240
|
+
result.valid = false;
|
|
241
|
+
}
|
|
242
|
+
const ruleTypes = ["listRule", "viewRule", "createRule", "updateRule", "deleteRule"];
|
|
243
|
+
if (isAuthCollection) {
|
|
244
|
+
ruleTypes.push("manageRule");
|
|
245
|
+
}
|
|
246
|
+
for (const ruleType of ruleTypes) {
|
|
247
|
+
const rule = permissions[ruleType];
|
|
248
|
+
if (rule !== void 0 && rule !== null && rule !== "") {
|
|
249
|
+
const ruleValidation = validateRuleExpression(rule);
|
|
250
|
+
if (!ruleValidation.valid) {
|
|
251
|
+
result.errors.push(`${ruleType}: ${ruleValidation.errors.join(", ")}`);
|
|
252
|
+
result.valid = false;
|
|
253
|
+
}
|
|
254
|
+
result.warnings.push(...ruleValidation.warnings.map((w) => `${ruleType}: ${w}`));
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return result;
|
|
258
|
+
}
|
|
259
|
+
function validateRuleExpression(expression) {
|
|
260
|
+
const result = {
|
|
261
|
+
valid: true,
|
|
262
|
+
errors: [],
|
|
263
|
+
warnings: []
|
|
264
|
+
};
|
|
265
|
+
if (expression === null || expression === "") {
|
|
266
|
+
return result;
|
|
267
|
+
}
|
|
268
|
+
let parenCount = 0;
|
|
269
|
+
for (const char of expression) {
|
|
270
|
+
if (char === "(") parenCount++;
|
|
271
|
+
if (char === ")") parenCount--;
|
|
272
|
+
if (parenCount < 0) {
|
|
273
|
+
result.errors.push("Unbalanced parentheses");
|
|
274
|
+
result.valid = false;
|
|
275
|
+
return result;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if (parenCount !== 0) {
|
|
279
|
+
result.errors.push("Unbalanced parentheses");
|
|
280
|
+
result.valid = false;
|
|
281
|
+
}
|
|
282
|
+
if (expression.includes("==")) {
|
|
283
|
+
result.warnings.push("Use '=' instead of '==' for equality comparison");
|
|
284
|
+
}
|
|
285
|
+
const requestRefs = expression.match(/@request\.[a-zA-Z_][a-zA-Z0-9_.]*/g) || [];
|
|
286
|
+
for (const ref of requestRefs) {
|
|
287
|
+
const isValid = ref.startsWith("@request.auth.") || ref === "@request.method" || ref === "@request.context" || ref.startsWith("@request.body.") || ref.startsWith("@request.query.") || ref.startsWith("@request.headers.");
|
|
288
|
+
if (!isValid) {
|
|
289
|
+
result.errors.push(`Invalid @request reference: '${ref}'`);
|
|
290
|
+
result.valid = false;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return result;
|
|
294
|
+
}
|
|
295
|
+
function createPermissions(permissions) {
|
|
296
|
+
return {
|
|
297
|
+
listRule: permissions.listRule ?? null,
|
|
298
|
+
viewRule: permissions.viewRule ?? null,
|
|
299
|
+
createRule: permissions.createRule ?? null,
|
|
300
|
+
updateRule: permissions.updateRule ?? null,
|
|
301
|
+
deleteRule: permissions.deleteRule ?? null,
|
|
302
|
+
manageRule: permissions.manageRule ?? null
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
function mergePermissions(...schemas) {
|
|
306
|
+
const merged = {
|
|
307
|
+
listRule: null,
|
|
308
|
+
viewRule: null,
|
|
309
|
+
createRule: null,
|
|
310
|
+
updateRule: null,
|
|
311
|
+
deleteRule: null,
|
|
312
|
+
manageRule: null
|
|
313
|
+
};
|
|
314
|
+
for (const schema of schemas) {
|
|
315
|
+
if (schema.listRule !== void 0) merged.listRule = schema.listRule;
|
|
316
|
+
if (schema.viewRule !== void 0) merged.viewRule = schema.viewRule;
|
|
317
|
+
if (schema.createRule !== void 0) merged.createRule = schema.createRule;
|
|
318
|
+
if (schema.updateRule !== void 0) merged.updateRule = schema.updateRule;
|
|
319
|
+
if (schema.deleteRule !== void 0) merged.deleteRule = schema.deleteRule;
|
|
320
|
+
if (schema.manageRule !== void 0) merged.manageRule = schema.manageRule;
|
|
321
|
+
}
|
|
322
|
+
return merged;
|
|
323
|
+
}
|
|
324
|
+
var StatusEnum = z.enum([
|
|
325
|
+
"draft",
|
|
326
|
+
// Initial proposal stage (RequestDraft, ProjectDraft)
|
|
327
|
+
"active",
|
|
328
|
+
// Work in progress
|
|
329
|
+
"complete",
|
|
330
|
+
// Fully completed project
|
|
331
|
+
"fail"
|
|
332
|
+
// Failed project at any stage
|
|
333
|
+
]);
|
|
334
|
+
|
|
335
|
+
// src/schema/project.ts
|
|
336
|
+
var ProjectInputSchema = z.object({
|
|
337
|
+
// Required fields
|
|
338
|
+
title: z.string(),
|
|
339
|
+
content: z.string(),
|
|
340
|
+
status: StatusEnum,
|
|
341
|
+
summary: z.string().optional(),
|
|
342
|
+
User: z.string().nonempty("User ID is missing"),
|
|
343
|
+
SubscriberUsers: z.array(z.string())
|
|
344
|
+
}).extend(inputImageFileSchema);
|
|
345
|
+
var ProjectSchema = withPermissions(
|
|
346
|
+
ProjectInputSchema.omit(omitImageFilesSchema).extend(baseImageFileSchema),
|
|
347
|
+
{
|
|
348
|
+
template: "owner-only",
|
|
349
|
+
ownerField: "User",
|
|
350
|
+
customRules: {
|
|
351
|
+
// Override list rule to allow authenticated users to see all projects
|
|
352
|
+
listRule: '@request.auth.id != ""',
|
|
353
|
+
// Allow viewing if user is owner OR a subscriber
|
|
354
|
+
viewRule: '@request.auth.id != "" && (User = @request.auth.id || SubscriberUsers ?= @request.auth.id)'
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
);
|
|
358
|
+
var UserInputSchema = z.object({
|
|
359
|
+
name: z.string().min(2, "Name must be longer").optional(),
|
|
360
|
+
email: z.string().email(),
|
|
361
|
+
password: z.string().min(8, "Password must be at least 8 characters"),
|
|
362
|
+
passwordConfirm: z.string(),
|
|
363
|
+
avatar: z.instanceof(File).optional()
|
|
364
|
+
});
|
|
365
|
+
var UserDatabaseSchema = z.object({
|
|
366
|
+
name: z.string().min(2, "Name must be longer").optional(),
|
|
367
|
+
email: z.string().email(),
|
|
368
|
+
password: z.string().min(8, "Password must be at least 8 characters"),
|
|
369
|
+
avatar: z.instanceof(File).optional()
|
|
370
|
+
});
|
|
371
|
+
var UserSchema = withIndexes(
|
|
372
|
+
withPermissions(UserDatabaseSchema.extend(baseSchema), {
|
|
373
|
+
// Users can list other users (for mentions, user search, etc.)
|
|
374
|
+
listRule: "id = @request.auth.id",
|
|
375
|
+
// Users can view their own profile
|
|
376
|
+
viewRule: "id = @request.auth.id",
|
|
377
|
+
// Anyone can create an account (sign up)
|
|
378
|
+
createRule: "",
|
|
379
|
+
// Users can only update their own profile
|
|
380
|
+
updateRule: "id = @request.auth.id",
|
|
381
|
+
// Users can only delete their own account
|
|
382
|
+
deleteRule: "id = @request.auth.id",
|
|
383
|
+
// Users can only manage their own account (change email, password, etc.)
|
|
384
|
+
manageRule: "id = @request.auth.id"
|
|
385
|
+
}),
|
|
386
|
+
[
|
|
387
|
+
// Email should be unique for authentication
|
|
388
|
+
"CREATE UNIQUE INDEX idx_users_email ON users (email)",
|
|
389
|
+
// Index on name for user search and sorting
|
|
390
|
+
"CREATE INDEX idx_users_name ON users (name)"
|
|
391
|
+
]
|
|
392
|
+
);
|
|
393
|
+
|
|
394
|
+
export { PermissionTemplates, ProjectInputSchema, ProjectSchema, UserInputSchema, UserSchema, baseImageFileSchema, baseSchema, baseSchemaWithTimestamps, boolField, createPermissions, dateField, editorField, emailField, fileField, filesField, geoPointField, inputImageFileSchema, isPermissionSchema, isTemplateConfig, jsonField, mergePermissions, numberField, omitImageFilesSchema, relationField, relationsField, resolveTemplate, selectField, textField, urlField, validatePermissionConfig, validateRuleExpression, withIndexes, withPermissions };
|
|
395
|
+
//# sourceMappingURL=schema.js.map
|
|
396
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schema/base.ts","../src/schema/permission-templates.ts","../src/enums.ts","../src/schema/project.ts","../src/schema/user.ts"],"names":["z"],"mappings":"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","file":"schema.js","sourcesContent":["import { z } from \"zod\";\nimport type { PermissionSchema, PermissionTemplateConfig } from \"./permissions\";\n\n/**\n * Base schema fields that PocketBase automatically adds to all records\n * These fields are managed by PocketBase and should not be set manually\n */\nexport const baseSchema = {\n id: z.string().describe(\"unique id\"),\n collectionId: z.string().describe(\"collection id\"),\n collectionName: z.string().describe(\"collection name\"),\n expand: z.record(z.any()).describe(\"expandable fields\"),\n};\n\n/**\n * Extended base schema with timestamp fields\n * Includes created and updated autodate fields\n */\nexport const baseSchemaWithTimestamps = {\n ...baseSchema,\n created: z.string().describe(\"creation timestamp\"),\n updated: z.string().describe(\"last update timestamp\"),\n};\n\n/**\n * Base schema for image file collections\n * Extends base schema with thumbnail URL and image files array\n */\nexport const baseImageFileSchema = {\n ...baseSchema,\n thumbnailURL: z.string().optional(),\n imageFiles: z.array(z.string()),\n};\n\n/**\n * Input schema for image file uploads\n * Used in forms where users upload File objects\n * Requires Node.js 20+ or browser environment with File API\n */\nexport const inputImageFileSchema = {\n imageFiles: z.array(z.instanceof(File)),\n};\n\n/**\n * Helper constant for omitting image files from schemas\n * Used with Zod's .omit() method\n */\nexport const omitImageFilesSchema = {\n imageFiles: true,\n} as const;\n\n// ============================================================================\n// Common PocketBase Field Type Patterns\n// ============================================================================\n\n/**\n * Creates a text field schema with optional constraints\n * @param options - Optional constraints for the text field\n */\nexport function textField(options?: { min?: number; max?: number; pattern?: RegExp }) {\n let schema = z.string();\n if (options?.min !== undefined) schema = schema.min(options.min);\n if (options?.max !== undefined) schema = schema.max(options.max);\n if (options?.pattern !== undefined) schema = schema.regex(options.pattern);\n return schema;\n}\n\n/**\n * Creates an email field schema\n * Maps to PocketBase 'email' field type\n */\nexport function emailField() {\n return z.string().email();\n}\n\n/**\n * Creates a URL field schema\n * Maps to PocketBase 'url' field type\n */\nexport function urlField() {\n return z.string().url();\n}\n\n/**\n * Creates a number field schema with optional constraints\n * @param options - Optional constraints for the number field\n */\nexport function numberField(options?: { min?: number; max?: number }) {\n let schema = z.number();\n if (options?.min !== undefined) schema = schema.min(options.min);\n if (options?.max !== undefined) schema = schema.max(options.max);\n return schema;\n}\n\n/**\n * Creates a boolean field schema\n * Maps to PocketBase 'bool' field type\n */\nexport function boolField() {\n return z.boolean();\n}\n\n/**\n * Creates a date field schema\n * Maps to PocketBase 'date' field type\n */\nexport function dateField() {\n return z.date();\n}\n\n/**\n * Creates a select field schema from enum values\n * Maps to PocketBase 'select' field type\n * @param values - Array of allowed string values\n */\nexport function selectField<T extends [string, ...string[]]>(values: T) {\n return z.enum(values);\n}\n\n/**\n * Creates a JSON field schema\n * Maps to PocketBase 'json' field type\n * @param schema - Optional Zod schema for the JSON structure\n */\nexport function jsonField<T extends z.ZodTypeAny>(schema?: T) {\n return schema ?? z.record(z.any());\n}\n\n/**\n * Creates a single file field schema for form input\n * Maps to PocketBase 'file' field type with maxSelect=1\n * Requires Node.js 20+ or browser environment with File API\n */\nexport function fileField() {\n return z.instanceof(File);\n}\n\n/**\n * Creates a multiple file field schema for form input\n * Maps to PocketBase 'file' field type with maxSelect>1\n * Requires Node.js 20+ or browser environment with File API\n * @param options - Optional constraints for the file field\n */\nexport function filesField(options?: { min?: number; max?: number }) {\n let schema = z.array(z.instanceof(File));\n if (options?.min !== undefined) schema = schema.min(options.min);\n if (options?.max !== undefined) schema = schema.max(options.max);\n return schema;\n}\n\n/**\n * Creates a single relation field schema\n * Maps to PocketBase 'relation' field type with maxSelect=1\n * Field name should start with uppercase to be detected as relation\n */\nexport function relationField() {\n return z.string();\n}\n\n/**\n * Creates a multiple relation field schema\n * Maps to PocketBase 'relation' field type with maxSelect>1\n * Field name should contain uppercase to be detected as relation\n * @param options - Optional constraints for the relation field\n */\nexport function relationsField(options?: { min?: number; max?: number }) {\n let schema = z.array(z.string());\n if (options?.min !== undefined) schema = schema.min(options.min);\n if (options?.max !== undefined) schema = schema.max(options.max);\n return schema;\n}\n\n/**\n * Creates an editor field schema (rich text)\n * Maps to PocketBase 'editor' field type\n */\nexport function editorField() {\n return z.string();\n}\n\n/**\n * Creates a geo point field schema\n * Maps to PocketBase 'geoPoint' field type\n */\nexport function geoPointField() {\n return z.object({\n lon: z.number(),\n lat: z.number(),\n });\n}\n\n/**\n * Attach permission metadata to a Zod schema\n *\n * This helper function allows you to define PocketBase API rules alongside your\n * entity schema definitions. The permissions are stored as metadata using Zod's\n * describe() method and will be extracted during migration generation.\n *\n * @param schema - The Zod schema to attach permissions to\n * @param config - Either a PermissionTemplateConfig (for template-based permissions)\n * or a PermissionSchema (for custom permissions)\n * @returns The schema with permission metadata attached\n *\n * @example\n * // Using a template\n * const ProjectSchema = withPermissions(\n * z.object({ title: z.string(), User: z.string() }),\n * { template: 'owner-only', ownerField: 'User' }\n * );\n *\n * @example\n * // Using custom rules\n * const ProjectSchema = withPermissions(\n * z.object({ title: z.string() }),\n * { listRule: '@request.auth.id != \"\"', viewRule: '' }\n * );\n *\n * @example\n * // Using template with custom rule overrides\n * const ProjectSchema = withPermissions(\n * z.object({ title: z.string(), User: z.string() }),\n * {\n * template: 'owner-only',\n * ownerField: 'User',\n * customRules: { listRule: '@request.auth.id != \"\"' }\n * }\n * );\n */\nexport function withPermissions<T extends z.ZodTypeAny>(\n schema: T,\n config: PermissionTemplateConfig | PermissionSchema\n): T {\n // Create metadata object with permissions config directly\n // The PermissionAnalyzer will handle resolving templates vs direct schemas\n const metadata = {\n permissions: config,\n };\n\n // Attach permission metadata to schema using Zod's describe() method\n // The metadata is serialized as JSON and stored in the schema's description\n return schema.describe(JSON.stringify(metadata)) as T;\n}\n\n/**\n * Attach index definitions to a Zod schema\n *\n * This helper function allows you to define PocketBase indexes alongside your\n * entity schema definitions. The indexes are stored as metadata using Zod's\n * describe() method and will be extracted during migration generation.\n *\n * @param schema - The Zod schema to attach indexes to\n * @param indexes - Array of PocketBase index SQL statements\n * @returns The schema with index metadata attached\n *\n * @example\n * // Define indexes for a user schema\n * const UserSchema = withIndexes(\n * withPermissions(\n * z.object({ name: z.string(), email: z.string().email() }),\n * userPermissions\n * ),\n * [\n * 'CREATE UNIQUE INDEX idx_users_email ON users (email)',\n * 'CREATE INDEX idx_users_name ON users (name)'\n * ]\n * );\n *\n * @example\n * // Single index\n * const ProjectSchema = withIndexes(\n * ProjectDatabaseSchema,\n * ['CREATE INDEX idx_projects_status ON projects (status)']\n * );\n */\nexport function withIndexes<T extends z.ZodTypeAny>(schema: T, indexes: string[]): T {\n // Extract existing metadata if present\n let existingMetadata: any = {};\n\n if (schema.description) {\n try {\n existingMetadata = JSON.parse(schema.description);\n } catch {\n // If description is not JSON, ignore it\n }\n }\n\n // Merge indexes with existing metadata\n const metadata = {\n ...existingMetadata,\n indexes,\n };\n\n // Attach metadata to schema using Zod's describe() method\n return schema.describe(JSON.stringify(metadata)) as T;\n}\n","import type { PermissionSchema, PermissionTemplateConfig, RuleExpression } from \"./permissions\";\n\n/**\n * Predefined permission templates for common access control patterns\n */\nexport const PermissionTemplates = {\n /**\n * Public access - anyone can perform all operations\n */\n public: (): PermissionSchema => ({\n listRule: \"\",\n viewRule: \"\",\n createRule: \"\",\n updateRule: \"\",\n deleteRule: \"\",\n }),\n\n /**\n * Authenticated users only - requires valid authentication for all operations\n */\n authenticated: (): PermissionSchema => ({\n listRule: '@request.auth.id != \"\"',\n viewRule: '@request.auth.id != \"\"',\n createRule: '@request.auth.id != \"\"',\n updateRule: '@request.auth.id != \"\"',\n deleteRule: '@request.auth.id != \"\"',\n }),\n\n /**\n * Owner-only access - users can only manage their own records\n * @param ownerField - Name of the relation field pointing to user (default: 'User')\n */\n ownerOnly: (ownerField: string = \"User\"): PermissionSchema => ({\n listRule: `@request.auth.id != \"\" && ${ownerField} = @request.auth.id`,\n viewRule: `@request.auth.id != \"\" && ${ownerField} = @request.auth.id`,\n createRule: '@request.auth.id != \"\"',\n updateRule: `@request.auth.id != \"\" && ${ownerField} = @request.auth.id`,\n deleteRule: `@request.auth.id != \"\" && ${ownerField} = @request.auth.id`,\n }),\n\n /**\n * Admin/superuser only access\n * Assumes a 'role' field exists with 'admin' value\n * @param roleField - Name of the role field (default: 'role')\n */\n adminOnly: (roleField: string = \"role\"): PermissionSchema => ({\n listRule: `@request.auth.id != \"\" && @request.auth.${roleField} = \"admin\"`,\n viewRule: `@request.auth.id != \"\" && @request.auth.${roleField} = \"admin\"`,\n createRule: `@request.auth.id != \"\" && @request.auth.${roleField} = \"admin\"`,\n updateRule: `@request.auth.id != \"\" && @request.auth.${roleField} = \"admin\"`,\n deleteRule: `@request.auth.id != \"\" && @request.auth.${roleField} = \"admin\"`,\n }),\n\n /**\n * Public read, authenticated write\n * Anyone can list/view, but only authenticated users can create/update/delete\n */\n readPublic: (): PermissionSchema => ({\n listRule: \"\",\n viewRule: \"\",\n createRule: '@request.auth.id != \"\"',\n updateRule: '@request.auth.id != \"\"',\n deleteRule: '@request.auth.id != \"\"',\n }),\n\n /**\n * Locked access - only superusers can perform operations\n * All rules are set to null (locked)\n */\n locked: (): PermissionSchema => ({\n listRule: null,\n viewRule: null,\n createRule: null,\n updateRule: null,\n deleteRule: null,\n }),\n\n /**\n * Read-only authenticated - authenticated users can read, no write access\n */\n readOnlyAuthenticated: (): PermissionSchema => ({\n listRule: '@request.auth.id != \"\"',\n viewRule: '@request.auth.id != \"\"',\n createRule: null,\n updateRule: null,\n deleteRule: null,\n }),\n};\n\n/**\n * Resolve template configuration to concrete permission schema\n * @param config - Template configuration or direct permission schema\n * @returns Resolved permission schema with all rules defined\n */\nexport function resolveTemplate(config: PermissionTemplateConfig): PermissionSchema {\n let baseRules: PermissionSchema;\n\n switch (config.template) {\n case \"public\":\n baseRules = PermissionTemplates.public();\n break;\n case \"authenticated\":\n baseRules = PermissionTemplates.authenticated();\n break;\n case \"owner-only\":\n baseRules = PermissionTemplates.ownerOnly(config.ownerField);\n break;\n case \"admin-only\":\n baseRules = PermissionTemplates.adminOnly(config.roleField);\n break;\n case \"read-public\":\n baseRules = PermissionTemplates.readPublic();\n break;\n case \"custom\":\n baseRules = {};\n break;\n default: {\n // Exhaustive check - TypeScript will error if we miss a template type\n const _exhaustive: never = config.template;\n throw new Error(`Unknown template type: ${_exhaustive}`);\n }\n }\n\n // Merge with custom rules if provided (custom rules override template rules)\n return {\n ...baseRules,\n ...config.customRules,\n };\n}\n\n/**\n * Check if a configuration is a template config or direct permission schema\n * @param config - Configuration to check\n * @returns True if it's a template configuration\n */\nexport function isTemplateConfig(\n config: PermissionTemplateConfig | PermissionSchema\n): config is PermissionTemplateConfig {\n return \"template\" in config;\n}\n\n/**\n * Check if a configuration is a direct permission schema\n * @param config - Configuration to check\n * @returns True if it's a direct permission schema\n */\nexport function isPermissionSchema(config: PermissionTemplateConfig | PermissionSchema): config is PermissionSchema {\n return (\n \"listRule\" in config ||\n \"viewRule\" in config ||\n \"createRule\" in config ||\n \"updateRule\" in config ||\n \"deleteRule\" in config ||\n \"manageRule\" in config\n );\n}\n\n/**\n * Validation result for permission configuration\n */\nexport interface PermissionValidationResult {\n valid: boolean;\n errors: string[];\n warnings: string[];\n}\n\n/**\n * Validate a permission configuration\n * @param config - Permission configuration to validate\n * @param isAuthCollection - Whether this is for an auth collection\n * @returns Validation result\n */\nexport function validatePermissionConfig(\n config: PermissionTemplateConfig | PermissionSchema,\n isAuthCollection: boolean = false\n): PermissionValidationResult {\n const result: PermissionValidationResult = {\n valid: true,\n errors: [],\n warnings: [],\n };\n\n // Resolve to permission schema\n let permissions: PermissionSchema;\n if (isTemplateConfig(config)) {\n // Validate template config\n if (config.template === \"owner-only\" && !config.ownerField) {\n result.warnings.push(\"owner-only template without ownerField specified - using default 'User'\");\n }\n if (config.template === \"admin-only\" && !config.roleField) {\n result.warnings.push(\"admin-only template without roleField specified - using default 'role'\");\n }\n permissions = resolveTemplate(config);\n } else {\n permissions = config;\n }\n\n // Validate manageRule usage\n if (permissions.manageRule !== undefined && !isAuthCollection) {\n result.errors.push(\"manageRule is only valid for auth collections\");\n result.valid = false;\n }\n\n // Validate rule expressions\n const ruleTypes: (keyof PermissionSchema)[] = [\"listRule\", \"viewRule\", \"createRule\", \"updateRule\", \"deleteRule\"];\n if (isAuthCollection) {\n ruleTypes.push(\"manageRule\");\n }\n\n for (const ruleType of ruleTypes) {\n const rule = permissions[ruleType];\n if (rule !== undefined && rule !== null && rule !== \"\") {\n const ruleValidation = validateRuleExpression(rule);\n if (!ruleValidation.valid) {\n result.errors.push(`${ruleType}: ${ruleValidation.errors.join(\", \")}`);\n result.valid = false;\n }\n result.warnings.push(...ruleValidation.warnings.map((w) => `${ruleType}: ${w}`));\n }\n }\n\n return result;\n}\n\n/**\n * Validate a single rule expression for basic syntax\n * @param expression - Rule expression to validate\n * @returns Validation result\n */\nexport function validateRuleExpression(expression: RuleExpression): PermissionValidationResult {\n const result: PermissionValidationResult = {\n valid: true,\n errors: [],\n warnings: [],\n };\n\n // Null and empty string are always valid\n if (expression === null || expression === \"\") {\n return result;\n }\n\n // Check for balanced parentheses\n let parenCount = 0;\n for (const char of expression) {\n if (char === \"(\") parenCount++;\n if (char === \")\") parenCount--;\n if (parenCount < 0) {\n result.errors.push(\"Unbalanced parentheses\");\n result.valid = false;\n return result;\n }\n }\n if (parenCount !== 0) {\n result.errors.push(\"Unbalanced parentheses\");\n result.valid = false;\n }\n\n // Check for common mistakes\n if (expression.includes(\"==\")) {\n result.warnings.push(\"Use '=' instead of '==' for equality comparison\");\n }\n\n // Check for valid @request references\n const requestRefs = expression.match(/@request\\.[a-zA-Z_][a-zA-Z0-9_.]*/g) || [];\n for (const ref of requestRefs) {\n const isValid =\n ref.startsWith(\"@request.auth.\") ||\n ref === \"@request.method\" ||\n ref === \"@request.context\" ||\n ref.startsWith(\"@request.body.\") ||\n ref.startsWith(\"@request.query.\") ||\n ref.startsWith(\"@request.headers.\");\n\n if (!isValid) {\n result.errors.push(`Invalid @request reference: '${ref}'`);\n result.valid = false;\n }\n }\n\n return result;\n}\n\n/**\n * Create a custom permission schema with type safety\n * @param permissions - Partial permission schema\n * @returns Complete permission schema with null defaults\n */\nexport function createPermissions(permissions: Partial<PermissionSchema>): PermissionSchema {\n return {\n listRule: permissions.listRule ?? null,\n viewRule: permissions.viewRule ?? null,\n createRule: permissions.createRule ?? null,\n updateRule: permissions.updateRule ?? null,\n deleteRule: permissions.deleteRule ?? null,\n manageRule: permissions.manageRule ?? null,\n };\n}\n\n/**\n * Merge multiple permission schemas, with later schemas taking precedence\n * @param schemas - Permission schemas to merge\n * @returns Merged permission schema\n */\nexport function mergePermissions(...schemas: Partial<PermissionSchema>[]): PermissionSchema {\n const merged: PermissionSchema = {\n listRule: null,\n viewRule: null,\n createRule: null,\n updateRule: null,\n deleteRule: null,\n manageRule: null,\n };\n\n for (const schema of schemas) {\n if (schema.listRule !== undefined) merged.listRule = schema.listRule;\n if (schema.viewRule !== undefined) merged.viewRule = schema.viewRule;\n if (schema.createRule !== undefined) merged.createRule = schema.createRule;\n if (schema.updateRule !== undefined) merged.updateRule = schema.updateRule;\n if (schema.deleteRule !== undefined) merged.deleteRule = schema.deleteRule;\n if (schema.manageRule !== undefined) merged.manageRule = schema.manageRule;\n }\n\n return merged;\n}\n","import { z } from \"zod\";\n\nexport const StatusEnum = z.enum([\n \"draft\", // Initial proposal stage (RequestDraft, ProjectDraft)\n \"active\", // Work in progress\n \"complete\", // Fully completed project\n \"fail\", // Failed project at any stage\n]);\nexport type StatusEnumType = z.infer<typeof StatusEnum>;\n","import { z } from \"zod\";\nimport { StatusEnum } from \"../enums\";\nimport { baseImageFileSchema, inputImageFileSchema, omitImageFilesSchema, withPermissions } from \"./base\";\n\nexport const ProjectInputSchema = z\n .object({\n // Required fields\n title: z.string(),\n content: z.string(),\n status: StatusEnum,\n summary: z.string().optional(),\n\n User: z.string().nonempty(\"User ID is missing\"),\n SubscriberUsers: z.array(z.string()),\n })\n .extend(inputImageFileSchema);\n\n// Apply permissions using template with custom overrides\n// Uses 'owner-only' template but allows all authenticated users to list projects\n// This allows users to see all projects but only manage their own\nexport const ProjectSchema = withPermissions(\n ProjectInputSchema.omit(omitImageFilesSchema).extend(baseImageFileSchema),\n {\n template: \"owner-only\",\n ownerField: \"User\",\n customRules: {\n // Override list rule to allow authenticated users to see all projects\n listRule: '@request.auth.id != \"\"',\n // Allow viewing if user is owner OR a subscriber\n viewRule: '@request.auth.id != \"\" && (User = @request.auth.id || SubscriberUsers ?= @request.auth.id)',\n },\n }\n);\n","import { z } from \"zod\";\nimport { baseSchema, withIndexes, withPermissions } from \"./base\";\n\n/** -- User Collections -- */\n// Input schema for forms (includes passwordConfirm for validation)\nexport const UserInputSchema = z.object({\n name: z.string().min(2, \"Name must be longer\").optional(),\n email: z.string().email(),\n password: z.string().min(8, \"Password must be at least 8 characters\"),\n passwordConfirm: z.string(),\n avatar: z.instanceof(File).optional(),\n});\n\n// Database schema (excludes passwordConfirm, includes avatar as file field)\nconst UserDatabaseSchema = z.object({\n name: z.string().min(2, \"Name must be longer\").optional(),\n email: z.string().email(),\n password: z.string().min(8, \"Password must be at least 8 characters\"),\n avatar: z.instanceof(File).optional(),\n});\n\n// Apply permissions and indexes for auth collection\n// Users can view all profiles, but only manage their own\nexport const UserSchema = withIndexes(\n withPermissions(UserDatabaseSchema.extend(baseSchema), {\n // Users can list other users (for mentions, user search, etc.)\n listRule: \"id = @request.auth.id\",\n // Users can view their own profile\n viewRule: \"id = @request.auth.id\",\n // Anyone can create an account (sign up)\n createRule: \"\",\n // Users can only update their own profile\n updateRule: \"id = @request.auth.id\",\n // Users can only delete their own account\n deleteRule: \"id = @request.auth.id\",\n // Users can only manage their own account (change email, password, etc.)\n manageRule: \"id = @request.auth.id\",\n }),\n [\n // Email should be unique for authentication\n \"CREATE UNIQUE INDEX idx_users_email ON users (email)\",\n // Index on name for user search and sorting\n \"CREATE INDEX idx_users_name ON users (name)\",\n ]\n);\n"]}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { A as APIRuleType } from './permissions-ZHafVSIx.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shared types for migration tool
|
|
5
|
+
*/
|
|
6
|
+
type PocketBaseFieldType = "text" | "email" | "url" | "number" | "bool" | "date" | "select" | "relation" | "file" | "json" | "editor" | "geoPoint" | "autodate";
|
|
7
|
+
|
|
8
|
+
interface FieldDefinition {
|
|
9
|
+
name: string;
|
|
10
|
+
type: PocketBaseFieldType;
|
|
11
|
+
required: boolean;
|
|
12
|
+
unique?: boolean;
|
|
13
|
+
options?: Record<string, any>;
|
|
14
|
+
relation?: {
|
|
15
|
+
collection: string;
|
|
16
|
+
cascadeDelete?: boolean;
|
|
17
|
+
maxSelect?: number;
|
|
18
|
+
minSelect?: number;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
interface CollectionSchema {
|
|
22
|
+
name: string;
|
|
23
|
+
type: "base" | "auth";
|
|
24
|
+
fields: FieldDefinition[];
|
|
25
|
+
indexes?: string[];
|
|
26
|
+
rules?: {
|
|
27
|
+
listRule?: string | null;
|
|
28
|
+
viewRule?: string | null;
|
|
29
|
+
createRule?: string | null;
|
|
30
|
+
updateRule?: string | null;
|
|
31
|
+
deleteRule?: string | null;
|
|
32
|
+
manageRule?: string | null;
|
|
33
|
+
};
|
|
34
|
+
permissions?: {
|
|
35
|
+
listRule?: string | null;
|
|
36
|
+
viewRule?: string | null;
|
|
37
|
+
createRule?: string | null;
|
|
38
|
+
updateRule?: string | null;
|
|
39
|
+
deleteRule?: string | null;
|
|
40
|
+
manageRule?: string | null;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
interface SchemaDefinition {
|
|
44
|
+
collections: Map<string, CollectionSchema>;
|
|
45
|
+
}
|
|
46
|
+
interface SchemaSnapshot {
|
|
47
|
+
version: string;
|
|
48
|
+
timestamp: string;
|
|
49
|
+
collections: Map<string, CollectionSchema>;
|
|
50
|
+
}
|
|
51
|
+
interface FieldChange {
|
|
52
|
+
property: string;
|
|
53
|
+
oldValue: any;
|
|
54
|
+
newValue: any;
|
|
55
|
+
}
|
|
56
|
+
interface FieldModification {
|
|
57
|
+
fieldName: string;
|
|
58
|
+
currentDefinition: any;
|
|
59
|
+
newDefinition: FieldDefinition;
|
|
60
|
+
changes: FieldChange[];
|
|
61
|
+
}
|
|
62
|
+
interface RuleUpdate {
|
|
63
|
+
ruleType: "listRule" | "viewRule" | "createRule" | "updateRule" | "deleteRule" | "manageRule";
|
|
64
|
+
oldValue: string | null;
|
|
65
|
+
newValue: string | null;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Permission change tracking for migrations
|
|
69
|
+
*/
|
|
70
|
+
interface PermissionChange {
|
|
71
|
+
ruleType: APIRuleType;
|
|
72
|
+
oldValue: string | null;
|
|
73
|
+
newValue: string | null;
|
|
74
|
+
}
|
|
75
|
+
interface CollectionModification {
|
|
76
|
+
collection: string;
|
|
77
|
+
fieldsToAdd: FieldDefinition[];
|
|
78
|
+
fieldsToRemove: any[];
|
|
79
|
+
fieldsToModify: FieldModification[];
|
|
80
|
+
indexesToAdd: string[];
|
|
81
|
+
indexesToRemove: string[];
|
|
82
|
+
rulesToUpdate: RuleUpdate[];
|
|
83
|
+
permissionsToUpdate: PermissionChange[];
|
|
84
|
+
}
|
|
85
|
+
interface SchemaDiff {
|
|
86
|
+
collectionsToCreate: CollectionSchema[];
|
|
87
|
+
collectionsToDelete: any[];
|
|
88
|
+
collectionsToModify: CollectionModification[];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export type { CollectionSchema as C, FieldDefinition as F, PocketBaseFieldType as P, RuleUpdate as R, SchemaDefinition as S, SchemaSnapshot as a, FieldChange as b, FieldModification as c, PermissionChange as d, CollectionModification as e, SchemaDiff as f };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { A as APIRuleType } from './permissions-ZHafVSIx.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shared types for migration tool
|
|
5
|
+
*/
|
|
6
|
+
type PocketBaseFieldType = "text" | "email" | "url" | "number" | "bool" | "date" | "select" | "relation" | "file" | "json" | "editor" | "geoPoint" | "autodate";
|
|
7
|
+
|
|
8
|
+
interface FieldDefinition {
|
|
9
|
+
name: string;
|
|
10
|
+
type: PocketBaseFieldType;
|
|
11
|
+
required: boolean;
|
|
12
|
+
unique?: boolean;
|
|
13
|
+
options?: Record<string, any>;
|
|
14
|
+
relation?: {
|
|
15
|
+
collection: string;
|
|
16
|
+
cascadeDelete?: boolean;
|
|
17
|
+
maxSelect?: number;
|
|
18
|
+
minSelect?: number;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
interface CollectionSchema {
|
|
22
|
+
name: string;
|
|
23
|
+
type: "base" | "auth";
|
|
24
|
+
fields: FieldDefinition[];
|
|
25
|
+
indexes?: string[];
|
|
26
|
+
rules?: {
|
|
27
|
+
listRule?: string | null;
|
|
28
|
+
viewRule?: string | null;
|
|
29
|
+
createRule?: string | null;
|
|
30
|
+
updateRule?: string | null;
|
|
31
|
+
deleteRule?: string | null;
|
|
32
|
+
manageRule?: string | null;
|
|
33
|
+
};
|
|
34
|
+
permissions?: {
|
|
35
|
+
listRule?: string | null;
|
|
36
|
+
viewRule?: string | null;
|
|
37
|
+
createRule?: string | null;
|
|
38
|
+
updateRule?: string | null;
|
|
39
|
+
deleteRule?: string | null;
|
|
40
|
+
manageRule?: string | null;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
interface SchemaDefinition {
|
|
44
|
+
collections: Map<string, CollectionSchema>;
|
|
45
|
+
}
|
|
46
|
+
interface SchemaSnapshot {
|
|
47
|
+
version: string;
|
|
48
|
+
timestamp: string;
|
|
49
|
+
collections: Map<string, CollectionSchema>;
|
|
50
|
+
}
|
|
51
|
+
interface FieldChange {
|
|
52
|
+
property: string;
|
|
53
|
+
oldValue: any;
|
|
54
|
+
newValue: any;
|
|
55
|
+
}
|
|
56
|
+
interface FieldModification {
|
|
57
|
+
fieldName: string;
|
|
58
|
+
currentDefinition: any;
|
|
59
|
+
newDefinition: FieldDefinition;
|
|
60
|
+
changes: FieldChange[];
|
|
61
|
+
}
|
|
62
|
+
interface RuleUpdate {
|
|
63
|
+
ruleType: "listRule" | "viewRule" | "createRule" | "updateRule" | "deleteRule" | "manageRule";
|
|
64
|
+
oldValue: string | null;
|
|
65
|
+
newValue: string | null;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Permission change tracking for migrations
|
|
69
|
+
*/
|
|
70
|
+
interface PermissionChange {
|
|
71
|
+
ruleType: APIRuleType;
|
|
72
|
+
oldValue: string | null;
|
|
73
|
+
newValue: string | null;
|
|
74
|
+
}
|
|
75
|
+
interface CollectionModification {
|
|
76
|
+
collection: string;
|
|
77
|
+
fieldsToAdd: FieldDefinition[];
|
|
78
|
+
fieldsToRemove: any[];
|
|
79
|
+
fieldsToModify: FieldModification[];
|
|
80
|
+
indexesToAdd: string[];
|
|
81
|
+
indexesToRemove: string[];
|
|
82
|
+
rulesToUpdate: RuleUpdate[];
|
|
83
|
+
permissionsToUpdate: PermissionChange[];
|
|
84
|
+
}
|
|
85
|
+
interface SchemaDiff {
|
|
86
|
+
collectionsToCreate: CollectionSchema[];
|
|
87
|
+
collectionsToDelete: any[];
|
|
88
|
+
collectionsToModify: CollectionModification[];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export type { CollectionSchema as C, FieldDefinition as F, PocketBaseFieldType as P, RuleUpdate as R, SchemaDefinition as S, SchemaSnapshot as a, FieldChange as b, FieldModification as c, PermissionChange as d, CollectionModification as e, SchemaDiff as f };
|
package/dist/types.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"types.cjs","sourcesContent":[]}
|