pocketbase-zod-schema 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/migrate.cjs.map +1 -1
- package/dist/cli/migrate.js.map +1 -1
- package/dist/index.cjs +414 -497
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -3
- package/dist/index.d.ts +1 -3
- package/dist/index.js +414 -490
- package/dist/index.js.map +1 -1
- package/dist/migration/index.cjs.map +1 -1
- package/dist/migration/index.js.map +1 -1
- package/dist/migration/snapshot.cjs.map +1 -1
- package/dist/migration/snapshot.js.map +1 -1
- package/dist/mutator.cjs +2 -98
- package/dist/mutator.cjs.map +1 -1
- package/dist/mutator.d.cts +4 -31
- package/dist/mutator.d.ts +4 -31
- package/dist/mutator.js +2 -98
- package/dist/mutator.js.map +1 -1
- package/dist/schema.cjs +0 -78
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +0 -1
- package/dist/schema.d.ts +0 -1
- package/dist/schema.js +1 -72
- package/dist/schema.js.map +1 -1
- package/package.json +1 -6
- package/dist/types.cjs +0 -4
- package/dist/types.cjs.map +0 -1
- package/dist/types.d.cts +0 -14
- package/dist/types.d.ts +0 -14
- package/dist/types.js +0 -3
- package/dist/types.js.map +0 -1
- package/dist/user-BnFWg5tw.d.cts +0 -161
- package/dist/user-BnFWg5tw.d.ts +0 -161
package/dist/index.js
CHANGED
|
@@ -15,440 +15,6 @@ var StatusEnum = z.enum([
|
|
|
15
15
|
"fail"
|
|
16
16
|
// Failed project at any stage
|
|
17
17
|
]);
|
|
18
|
-
var baseSchema = {
|
|
19
|
-
id: z.string().describe("unique id"),
|
|
20
|
-
collectionId: z.string().describe("collection id"),
|
|
21
|
-
collectionName: z.string().describe("collection name"),
|
|
22
|
-
expand: z.record(z.any()).describe("expandable fields"),
|
|
23
|
-
created: z.string().describe("creation timestamp"),
|
|
24
|
-
updated: z.string().describe("last update timestamp")
|
|
25
|
-
};
|
|
26
|
-
var baseSchemaWithTimestamps = {
|
|
27
|
-
...baseSchema,
|
|
28
|
-
created: z.string().describe("creation timestamp"),
|
|
29
|
-
updated: z.string().describe("last update timestamp")
|
|
30
|
-
};
|
|
31
|
-
var baseImageFileSchema = {
|
|
32
|
-
...baseSchema,
|
|
33
|
-
thumbnailURL: z.string().optional(),
|
|
34
|
-
imageFiles: z.array(z.string())
|
|
35
|
-
};
|
|
36
|
-
var inputImageFileSchema = {
|
|
37
|
-
imageFiles: z.array(z.instanceof(File))
|
|
38
|
-
};
|
|
39
|
-
var omitImageFilesSchema = {
|
|
40
|
-
imageFiles: true
|
|
41
|
-
};
|
|
42
|
-
function textField(options) {
|
|
43
|
-
let schema = z.string();
|
|
44
|
-
if (options?.min !== void 0) schema = schema.min(options.min);
|
|
45
|
-
if (options?.max !== void 0) schema = schema.max(options.max);
|
|
46
|
-
if (options?.pattern !== void 0) schema = schema.regex(options.pattern);
|
|
47
|
-
return schema;
|
|
48
|
-
}
|
|
49
|
-
function emailField() {
|
|
50
|
-
return z.string().email();
|
|
51
|
-
}
|
|
52
|
-
function urlField() {
|
|
53
|
-
return z.string().url();
|
|
54
|
-
}
|
|
55
|
-
function numberField(options) {
|
|
56
|
-
let schema = z.number();
|
|
57
|
-
if (options?.min !== void 0) schema = schema.min(options.min);
|
|
58
|
-
if (options?.max !== void 0) schema = schema.max(options.max);
|
|
59
|
-
return schema;
|
|
60
|
-
}
|
|
61
|
-
function boolField() {
|
|
62
|
-
return z.boolean();
|
|
63
|
-
}
|
|
64
|
-
function dateField() {
|
|
65
|
-
return z.date();
|
|
66
|
-
}
|
|
67
|
-
function selectField(values) {
|
|
68
|
-
return z.enum(values);
|
|
69
|
-
}
|
|
70
|
-
function jsonField(schema) {
|
|
71
|
-
return schema ?? z.record(z.any());
|
|
72
|
-
}
|
|
73
|
-
function fileField() {
|
|
74
|
-
return z.instanceof(File);
|
|
75
|
-
}
|
|
76
|
-
function filesField(options) {
|
|
77
|
-
let schema = z.array(z.instanceof(File));
|
|
78
|
-
if (options?.min !== void 0) schema = schema.min(options.min);
|
|
79
|
-
if (options?.max !== void 0) schema = schema.max(options.max);
|
|
80
|
-
return schema;
|
|
81
|
-
}
|
|
82
|
-
var RELATION_METADATA_KEY = "__pocketbase_relation__";
|
|
83
|
-
function RelationField(config) {
|
|
84
|
-
const metadata = {
|
|
85
|
-
[RELATION_METADATA_KEY]: {
|
|
86
|
-
type: "single",
|
|
87
|
-
collection: config.collection,
|
|
88
|
-
cascadeDelete: config.cascadeDelete ?? false,
|
|
89
|
-
maxSelect: 1,
|
|
90
|
-
minSelect: 0
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
return z.string().describe(JSON.stringify(metadata));
|
|
94
|
-
}
|
|
95
|
-
function RelationsField(config) {
|
|
96
|
-
const metadata = {
|
|
97
|
-
[RELATION_METADATA_KEY]: {
|
|
98
|
-
type: "multiple",
|
|
99
|
-
collection: config.collection,
|
|
100
|
-
cascadeDelete: config.cascadeDelete ?? false,
|
|
101
|
-
maxSelect: config.maxSelect ?? 999,
|
|
102
|
-
minSelect: config.minSelect ?? 0
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
let schema = z.array(z.string());
|
|
106
|
-
if (config.minSelect !== void 0) {
|
|
107
|
-
schema = schema.min(config.minSelect);
|
|
108
|
-
}
|
|
109
|
-
if (config.maxSelect !== void 0) {
|
|
110
|
-
schema = schema.max(config.maxSelect);
|
|
111
|
-
}
|
|
112
|
-
return schema.describe(JSON.stringify(metadata));
|
|
113
|
-
}
|
|
114
|
-
function extractRelationMetadata(description) {
|
|
115
|
-
if (!description) return null;
|
|
116
|
-
try {
|
|
117
|
-
const parsed = JSON.parse(description);
|
|
118
|
-
if (parsed[RELATION_METADATA_KEY]) {
|
|
119
|
-
return parsed[RELATION_METADATA_KEY];
|
|
120
|
-
}
|
|
121
|
-
} catch {
|
|
122
|
-
}
|
|
123
|
-
return null;
|
|
124
|
-
}
|
|
125
|
-
function editorField() {
|
|
126
|
-
return z.string();
|
|
127
|
-
}
|
|
128
|
-
function geoPointField() {
|
|
129
|
-
return z.object({
|
|
130
|
-
lon: z.number(),
|
|
131
|
-
lat: z.number()
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
function withPermissions(schema, config) {
|
|
135
|
-
const metadata = {
|
|
136
|
-
permissions: config
|
|
137
|
-
};
|
|
138
|
-
return schema.describe(JSON.stringify(metadata));
|
|
139
|
-
}
|
|
140
|
-
function withIndexes(schema, indexes) {
|
|
141
|
-
let existingMetadata = {};
|
|
142
|
-
if (schema.description) {
|
|
143
|
-
try {
|
|
144
|
-
existingMetadata = JSON.parse(schema.description);
|
|
145
|
-
} catch {
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
const metadata = {
|
|
149
|
-
...existingMetadata,
|
|
150
|
-
indexes
|
|
151
|
-
};
|
|
152
|
-
return schema.describe(JSON.stringify(metadata));
|
|
153
|
-
}
|
|
154
|
-
function defineCollection(config) {
|
|
155
|
-
const { collectionName, schema, permissions, indexes, type, ...futureOptions } = config;
|
|
156
|
-
const metadata = {
|
|
157
|
-
collectionName
|
|
158
|
-
};
|
|
159
|
-
if (type) {
|
|
160
|
-
metadata.type = type;
|
|
161
|
-
}
|
|
162
|
-
if (permissions) {
|
|
163
|
-
metadata.permissions = permissions;
|
|
164
|
-
}
|
|
165
|
-
if (indexes) {
|
|
166
|
-
metadata.indexes = indexes;
|
|
167
|
-
}
|
|
168
|
-
if (Object.keys(futureOptions).length > 0) {
|
|
169
|
-
Object.assign(metadata, futureOptions);
|
|
170
|
-
}
|
|
171
|
-
return schema.describe(JSON.stringify(metadata));
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// src/utils/permission-templates.ts
|
|
175
|
-
var PermissionTemplates = {
|
|
176
|
-
/**
|
|
177
|
-
* Public access - anyone can perform all operations
|
|
178
|
-
*/
|
|
179
|
-
public: () => ({
|
|
180
|
-
listRule: "",
|
|
181
|
-
viewRule: "",
|
|
182
|
-
createRule: "",
|
|
183
|
-
updateRule: "",
|
|
184
|
-
deleteRule: ""
|
|
185
|
-
}),
|
|
186
|
-
/**
|
|
187
|
-
* Authenticated users only - requires valid authentication for all operations
|
|
188
|
-
*/
|
|
189
|
-
authenticated: () => ({
|
|
190
|
-
listRule: '@request.auth.id != ""',
|
|
191
|
-
viewRule: '@request.auth.id != ""',
|
|
192
|
-
createRule: '@request.auth.id != ""',
|
|
193
|
-
updateRule: '@request.auth.id != ""',
|
|
194
|
-
deleteRule: '@request.auth.id != ""'
|
|
195
|
-
}),
|
|
196
|
-
/**
|
|
197
|
-
* Owner-only access - users can only manage their own records
|
|
198
|
-
* @param ownerField - Name of the relation field pointing to user (default: 'User')
|
|
199
|
-
*/
|
|
200
|
-
ownerOnly: (ownerField = "User") => ({
|
|
201
|
-
listRule: `@request.auth.id != "" && ${ownerField} = @request.auth.id`,
|
|
202
|
-
viewRule: `@request.auth.id != "" && ${ownerField} = @request.auth.id`,
|
|
203
|
-
createRule: '@request.auth.id != ""',
|
|
204
|
-
updateRule: `@request.auth.id != "" && ${ownerField} = @request.auth.id`,
|
|
205
|
-
deleteRule: `@request.auth.id != "" && ${ownerField} = @request.auth.id`
|
|
206
|
-
}),
|
|
207
|
-
/**
|
|
208
|
-
* Admin/superuser only access
|
|
209
|
-
* Assumes a 'role' field exists with 'admin' value
|
|
210
|
-
* @param roleField - Name of the role field (default: 'role')
|
|
211
|
-
*/
|
|
212
|
-
adminOnly: (roleField = "role") => ({
|
|
213
|
-
listRule: `@request.auth.id != "" && @request.auth.${roleField} = "admin"`,
|
|
214
|
-
viewRule: `@request.auth.id != "" && @request.auth.${roleField} = "admin"`,
|
|
215
|
-
createRule: `@request.auth.id != "" && @request.auth.${roleField} = "admin"`,
|
|
216
|
-
updateRule: `@request.auth.id != "" && @request.auth.${roleField} = "admin"`,
|
|
217
|
-
deleteRule: `@request.auth.id != "" && @request.auth.${roleField} = "admin"`
|
|
218
|
-
}),
|
|
219
|
-
/**
|
|
220
|
-
* Public read, authenticated write
|
|
221
|
-
* Anyone can list/view, but only authenticated users can create/update/delete
|
|
222
|
-
*/
|
|
223
|
-
readPublic: () => ({
|
|
224
|
-
listRule: "",
|
|
225
|
-
viewRule: "",
|
|
226
|
-
createRule: '@request.auth.id != ""',
|
|
227
|
-
updateRule: '@request.auth.id != ""',
|
|
228
|
-
deleteRule: '@request.auth.id != ""'
|
|
229
|
-
}),
|
|
230
|
-
/**
|
|
231
|
-
* Locked access - only superusers can perform operations
|
|
232
|
-
* All rules are set to null (locked)
|
|
233
|
-
*/
|
|
234
|
-
locked: () => ({
|
|
235
|
-
listRule: null,
|
|
236
|
-
viewRule: null,
|
|
237
|
-
createRule: null,
|
|
238
|
-
updateRule: null,
|
|
239
|
-
deleteRule: null
|
|
240
|
-
}),
|
|
241
|
-
/**
|
|
242
|
-
* Read-only authenticated - authenticated users can read, no write access
|
|
243
|
-
*/
|
|
244
|
-
readOnlyAuthenticated: () => ({
|
|
245
|
-
listRule: '@request.auth.id != ""',
|
|
246
|
-
viewRule: '@request.auth.id != ""',
|
|
247
|
-
createRule: null,
|
|
248
|
-
updateRule: null,
|
|
249
|
-
deleteRule: null
|
|
250
|
-
})
|
|
251
|
-
};
|
|
252
|
-
function resolveTemplate(config) {
|
|
253
|
-
let baseRules;
|
|
254
|
-
switch (config.template) {
|
|
255
|
-
case "public":
|
|
256
|
-
baseRules = PermissionTemplates.public();
|
|
257
|
-
break;
|
|
258
|
-
case "authenticated":
|
|
259
|
-
baseRules = PermissionTemplates.authenticated();
|
|
260
|
-
break;
|
|
261
|
-
case "owner-only":
|
|
262
|
-
baseRules = PermissionTemplates.ownerOnly(config.ownerField);
|
|
263
|
-
break;
|
|
264
|
-
case "admin-only":
|
|
265
|
-
baseRules = PermissionTemplates.adminOnly(config.roleField);
|
|
266
|
-
break;
|
|
267
|
-
case "read-public":
|
|
268
|
-
baseRules = PermissionTemplates.readPublic();
|
|
269
|
-
break;
|
|
270
|
-
case "custom":
|
|
271
|
-
baseRules = {};
|
|
272
|
-
break;
|
|
273
|
-
default: {
|
|
274
|
-
const _exhaustive = config.template;
|
|
275
|
-
throw new Error(`Unknown template type: ${_exhaustive}`);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
return {
|
|
279
|
-
...baseRules,
|
|
280
|
-
...config.customRules
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
function isTemplateConfig(config) {
|
|
284
|
-
return "template" in config;
|
|
285
|
-
}
|
|
286
|
-
function isPermissionSchema(config) {
|
|
287
|
-
return "listRule" in config || "viewRule" in config || "createRule" in config || "updateRule" in config || "deleteRule" in config || "manageRule" in config;
|
|
288
|
-
}
|
|
289
|
-
function validatePermissionConfig(config, isAuthCollection2 = false) {
|
|
290
|
-
const result = {
|
|
291
|
-
valid: true,
|
|
292
|
-
errors: [],
|
|
293
|
-
warnings: []
|
|
294
|
-
};
|
|
295
|
-
let permissions;
|
|
296
|
-
if (isTemplateConfig(config)) {
|
|
297
|
-
if (config.template === "owner-only" && !config.ownerField) {
|
|
298
|
-
result.warnings.push("owner-only template without ownerField specified - using default 'User'");
|
|
299
|
-
}
|
|
300
|
-
if (config.template === "admin-only" && !config.roleField) {
|
|
301
|
-
result.warnings.push("admin-only template without roleField specified - using default 'role'");
|
|
302
|
-
}
|
|
303
|
-
permissions = resolveTemplate(config);
|
|
304
|
-
} else {
|
|
305
|
-
permissions = config;
|
|
306
|
-
}
|
|
307
|
-
if (permissions.manageRule !== void 0 && !isAuthCollection2) {
|
|
308
|
-
result.errors.push("manageRule is only valid for auth collections");
|
|
309
|
-
result.valid = false;
|
|
310
|
-
}
|
|
311
|
-
const ruleTypes = ["listRule", "viewRule", "createRule", "updateRule", "deleteRule"];
|
|
312
|
-
if (isAuthCollection2) {
|
|
313
|
-
ruleTypes.push("manageRule");
|
|
314
|
-
}
|
|
315
|
-
for (const ruleType of ruleTypes) {
|
|
316
|
-
const rule = permissions[ruleType];
|
|
317
|
-
if (rule !== void 0 && rule !== null && rule !== "") {
|
|
318
|
-
const ruleValidation = validateRuleExpression(rule);
|
|
319
|
-
if (!ruleValidation.valid) {
|
|
320
|
-
result.errors.push(`${ruleType}: ${ruleValidation.errors.join(", ")}`);
|
|
321
|
-
result.valid = false;
|
|
322
|
-
}
|
|
323
|
-
result.warnings.push(...ruleValidation.warnings.map((w) => `${ruleType}: ${w}`));
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
return result;
|
|
327
|
-
}
|
|
328
|
-
function validateRuleExpression(expression) {
|
|
329
|
-
const result = {
|
|
330
|
-
valid: true,
|
|
331
|
-
errors: [],
|
|
332
|
-
warnings: []
|
|
333
|
-
};
|
|
334
|
-
if (expression === null || expression === "") {
|
|
335
|
-
return result;
|
|
336
|
-
}
|
|
337
|
-
let parenCount = 0;
|
|
338
|
-
for (const char of expression) {
|
|
339
|
-
if (char === "(") parenCount++;
|
|
340
|
-
if (char === ")") parenCount--;
|
|
341
|
-
if (parenCount < 0) {
|
|
342
|
-
result.errors.push("Unbalanced parentheses");
|
|
343
|
-
result.valid = false;
|
|
344
|
-
return result;
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
if (parenCount !== 0) {
|
|
348
|
-
result.errors.push("Unbalanced parentheses");
|
|
349
|
-
result.valid = false;
|
|
350
|
-
}
|
|
351
|
-
if (expression.includes("==")) {
|
|
352
|
-
result.warnings.push("Use '=' instead of '==' for equality comparison");
|
|
353
|
-
}
|
|
354
|
-
const requestRefs = expression.match(/@request\.[a-zA-Z_][a-zA-Z0-9_.]*/g) || [];
|
|
355
|
-
for (const ref of requestRefs) {
|
|
356
|
-
const isValid = ref.startsWith("@request.auth.") || ref === "@request.method" || ref === "@request.context" || ref.startsWith("@request.body.") || ref.startsWith("@request.query.") || ref.startsWith("@request.headers.");
|
|
357
|
-
if (!isValid) {
|
|
358
|
-
result.errors.push(`Invalid @request reference: '${ref}'`);
|
|
359
|
-
result.valid = false;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
return result;
|
|
363
|
-
}
|
|
364
|
-
function createPermissions(permissions) {
|
|
365
|
-
return {
|
|
366
|
-
listRule: permissions.listRule ?? null,
|
|
367
|
-
viewRule: permissions.viewRule ?? null,
|
|
368
|
-
createRule: permissions.createRule ?? null,
|
|
369
|
-
updateRule: permissions.updateRule ?? null,
|
|
370
|
-
deleteRule: permissions.deleteRule ?? null,
|
|
371
|
-
manageRule: permissions.manageRule ?? null
|
|
372
|
-
};
|
|
373
|
-
}
|
|
374
|
-
function mergePermissions(...schemas) {
|
|
375
|
-
const merged = {
|
|
376
|
-
listRule: null,
|
|
377
|
-
viewRule: null,
|
|
378
|
-
createRule: null,
|
|
379
|
-
updateRule: null,
|
|
380
|
-
deleteRule: null,
|
|
381
|
-
manageRule: null
|
|
382
|
-
};
|
|
383
|
-
for (const schema of schemas) {
|
|
384
|
-
if (schema.listRule !== void 0) merged.listRule = schema.listRule;
|
|
385
|
-
if (schema.viewRule !== void 0) merged.viewRule = schema.viewRule;
|
|
386
|
-
if (schema.createRule !== void 0) merged.createRule = schema.createRule;
|
|
387
|
-
if (schema.updateRule !== void 0) merged.updateRule = schema.updateRule;
|
|
388
|
-
if (schema.deleteRule !== void 0) merged.deleteRule = schema.deleteRule;
|
|
389
|
-
if (schema.manageRule !== void 0) merged.manageRule = schema.manageRule;
|
|
390
|
-
}
|
|
391
|
-
return merged;
|
|
392
|
-
}
|
|
393
|
-
var ProjectInputSchema = z.object({
|
|
394
|
-
// Required fields
|
|
395
|
-
title: z.string(),
|
|
396
|
-
content: z.string(),
|
|
397
|
-
status: StatusEnum,
|
|
398
|
-
summary: z.string().optional(),
|
|
399
|
-
OwnerUser: RelationField({ collection: "Users" }),
|
|
400
|
-
SubscriberUsers: RelationsField({ collection: "Users" })
|
|
401
|
-
}).extend(inputImageFileSchema);
|
|
402
|
-
var ProjectSchema = ProjectInputSchema.omit(omitImageFilesSchema).extend(baseImageFileSchema);
|
|
403
|
-
var ProjectCollection = defineCollection({
|
|
404
|
-
collectionName: "Projects",
|
|
405
|
-
schema: ProjectSchema,
|
|
406
|
-
permissions: {
|
|
407
|
-
template: "owner-only",
|
|
408
|
-
ownerField: "OwnerUser",
|
|
409
|
-
customRules: {
|
|
410
|
-
listRule: '@request.auth.id != ""',
|
|
411
|
-
viewRule: '@request.auth.id != "" && (OwnerUser = @request.auth.id || SubscriberUsers ?= @request.auth.id)'
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
});
|
|
415
|
-
var UserInputSchema = z.object({
|
|
416
|
-
name: z.string().optional(),
|
|
417
|
-
email: z.string().email(),
|
|
418
|
-
password: z.string().min(8, "Password must be at least 8 characters"),
|
|
419
|
-
passwordConfirm: z.string(),
|
|
420
|
-
avatar: z.instanceof(File).optional()
|
|
421
|
-
});
|
|
422
|
-
var UserCollectionSchema = z.object({
|
|
423
|
-
name: z.string().optional(),
|
|
424
|
-
email: z.string().email(),
|
|
425
|
-
password: z.string().min(8, "Password must be at least 8 characters"),
|
|
426
|
-
avatar: z.instanceof(File).optional()
|
|
427
|
-
});
|
|
428
|
-
var UserSchema = UserCollectionSchema.extend(baseSchema);
|
|
429
|
-
var UserCollection = defineCollection({
|
|
430
|
-
collectionName: "users",
|
|
431
|
-
type: "auth",
|
|
432
|
-
schema: UserSchema,
|
|
433
|
-
permissions: {
|
|
434
|
-
// Users can list their own profile
|
|
435
|
-
listRule: "id = @request.auth.id",
|
|
436
|
-
// Users can view their own profile
|
|
437
|
-
viewRule: "id = @request.auth.id",
|
|
438
|
-
// Anyone can create an account (sign up)
|
|
439
|
-
createRule: "",
|
|
440
|
-
// Users can only update their own profile
|
|
441
|
-
updateRule: "id = @request.auth.id",
|
|
442
|
-
// Users can only delete their own account
|
|
443
|
-
deleteRule: "id = @request.auth.id"
|
|
444
|
-
// manageRule is null in PocketBase default (not set)
|
|
445
|
-
},
|
|
446
|
-
indexes: [
|
|
447
|
-
// PocketBase's default indexes for auth collections
|
|
448
|
-
"CREATE UNIQUE INDEX `idx_tokenKey__pb_users_auth_` ON `users` (`tokenKey`)",
|
|
449
|
-
"CREATE UNIQUE INDEX `idx_email__pb_users_auth_` ON `users` (`email`) WHERE `email` != ''"
|
|
450
|
-
]
|
|
451
|
-
});
|
|
452
18
|
var BaseMutator = class {
|
|
453
19
|
pb;
|
|
454
20
|
// Define a default property that subclasses will override
|
|
@@ -721,78 +287,436 @@ var BaseMutator = class {
|
|
|
721
287
|
throw error;
|
|
722
288
|
}
|
|
723
289
|
/**
|
|
724
|
-
* Check if an error is a "not found" error
|
|
290
|
+
* Check if an error is a "not found" error
|
|
291
|
+
*/
|
|
292
|
+
isNotFoundError(error) {
|
|
293
|
+
return error instanceof Error && (error.message.includes("404") || error.message.toLowerCase().includes("not found"));
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Standard error handling wrapper (legacy method, consider using handleError instead)
|
|
297
|
+
*/
|
|
298
|
+
errorWrapper(error) {
|
|
299
|
+
console.error(`Error in ${this.constructor.name}:`, error);
|
|
300
|
+
throw error;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Subscribe to changes on a specific record
|
|
304
|
+
* @param id The ID of the record to subscribe to
|
|
305
|
+
* @param callback Function to call when changes occur
|
|
306
|
+
* @param expand Optional expand parameters
|
|
307
|
+
* @returns Promise that resolves to an unsubscribe function
|
|
308
|
+
*/
|
|
309
|
+
async subscribeToRecord(id, callback, expand) {
|
|
310
|
+
const finalExpand = this.prepareExpand(expand);
|
|
311
|
+
const options = finalExpand ? { expand: finalExpand } : {};
|
|
312
|
+
return this.getCollection().subscribe(id, callback, options);
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Subscribe to changes on the entire collection
|
|
316
|
+
* @param callback Function to call when changes occur
|
|
317
|
+
* @param expand Optional expand parameters
|
|
318
|
+
* @returns Promise that resolves to an unsubscribe function
|
|
319
|
+
*/
|
|
320
|
+
async subscribeToCollection(callback, expand) {
|
|
321
|
+
const finalExpand = this.prepareExpand(expand);
|
|
322
|
+
const options = finalExpand ? { expand: finalExpand } : {};
|
|
323
|
+
return this.getCollection().subscribe("*", callback, options);
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Unsubscribe from a specific record's changes
|
|
327
|
+
* @param id The ID of the record to unsubscribe from
|
|
328
|
+
*/
|
|
329
|
+
unsubscribeFromRecord(id) {
|
|
330
|
+
this.getCollection().unsubscribe(id);
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Unsubscribe from collection-wide changes
|
|
334
|
+
*/
|
|
335
|
+
unsubscribeFromCollection() {
|
|
336
|
+
this.getCollection().unsubscribe("*");
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Unsubscribe from all subscriptions in this collection
|
|
340
|
+
*/
|
|
341
|
+
unsubscribeAll() {
|
|
342
|
+
this.getCollection().unsubscribe();
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
var baseSchema = {
|
|
346
|
+
id: z.string().describe("unique id"),
|
|
347
|
+
collectionId: z.string().describe("collection id"),
|
|
348
|
+
collectionName: z.string().describe("collection name"),
|
|
349
|
+
expand: z.record(z.any()).describe("expandable fields"),
|
|
350
|
+
created: z.string().describe("creation timestamp"),
|
|
351
|
+
updated: z.string().describe("last update timestamp")
|
|
352
|
+
};
|
|
353
|
+
var baseSchemaWithTimestamps = {
|
|
354
|
+
...baseSchema,
|
|
355
|
+
created: z.string().describe("creation timestamp"),
|
|
356
|
+
updated: z.string().describe("last update timestamp")
|
|
357
|
+
};
|
|
358
|
+
var baseImageFileSchema = {
|
|
359
|
+
...baseSchema,
|
|
360
|
+
thumbnailURL: z.string().optional(),
|
|
361
|
+
imageFiles: z.array(z.string())
|
|
362
|
+
};
|
|
363
|
+
var inputImageFileSchema = {
|
|
364
|
+
imageFiles: z.array(z.instanceof(File))
|
|
365
|
+
};
|
|
366
|
+
var omitImageFilesSchema = {
|
|
367
|
+
imageFiles: true
|
|
368
|
+
};
|
|
369
|
+
function textField(options) {
|
|
370
|
+
let schema = z.string();
|
|
371
|
+
if (options?.min !== void 0) schema = schema.min(options.min);
|
|
372
|
+
if (options?.max !== void 0) schema = schema.max(options.max);
|
|
373
|
+
if (options?.pattern !== void 0) schema = schema.regex(options.pattern);
|
|
374
|
+
return schema;
|
|
375
|
+
}
|
|
376
|
+
function emailField() {
|
|
377
|
+
return z.string().email();
|
|
378
|
+
}
|
|
379
|
+
function urlField() {
|
|
380
|
+
return z.string().url();
|
|
381
|
+
}
|
|
382
|
+
function numberField(options) {
|
|
383
|
+
let schema = z.number();
|
|
384
|
+
if (options?.min !== void 0) schema = schema.min(options.min);
|
|
385
|
+
if (options?.max !== void 0) schema = schema.max(options.max);
|
|
386
|
+
return schema;
|
|
387
|
+
}
|
|
388
|
+
function boolField() {
|
|
389
|
+
return z.boolean();
|
|
390
|
+
}
|
|
391
|
+
function dateField() {
|
|
392
|
+
return z.date();
|
|
393
|
+
}
|
|
394
|
+
function selectField(values) {
|
|
395
|
+
return z.enum(values);
|
|
396
|
+
}
|
|
397
|
+
function jsonField(schema) {
|
|
398
|
+
return schema ?? z.record(z.any());
|
|
399
|
+
}
|
|
400
|
+
function fileField() {
|
|
401
|
+
return z.instanceof(File);
|
|
402
|
+
}
|
|
403
|
+
function filesField(options) {
|
|
404
|
+
let schema = z.array(z.instanceof(File));
|
|
405
|
+
if (options?.min !== void 0) schema = schema.min(options.min);
|
|
406
|
+
if (options?.max !== void 0) schema = schema.max(options.max);
|
|
407
|
+
return schema;
|
|
408
|
+
}
|
|
409
|
+
var RELATION_METADATA_KEY = "__pocketbase_relation__";
|
|
410
|
+
function RelationField(config) {
|
|
411
|
+
const metadata = {
|
|
412
|
+
[RELATION_METADATA_KEY]: {
|
|
413
|
+
type: "single",
|
|
414
|
+
collection: config.collection,
|
|
415
|
+
cascadeDelete: config.cascadeDelete ?? false,
|
|
416
|
+
maxSelect: 1,
|
|
417
|
+
minSelect: 0
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
return z.string().describe(JSON.stringify(metadata));
|
|
421
|
+
}
|
|
422
|
+
function RelationsField(config) {
|
|
423
|
+
const metadata = {
|
|
424
|
+
[RELATION_METADATA_KEY]: {
|
|
425
|
+
type: "multiple",
|
|
426
|
+
collection: config.collection,
|
|
427
|
+
cascadeDelete: config.cascadeDelete ?? false,
|
|
428
|
+
maxSelect: config.maxSelect ?? 999,
|
|
429
|
+
minSelect: config.minSelect ?? 0
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
let schema = z.array(z.string());
|
|
433
|
+
if (config.minSelect !== void 0) {
|
|
434
|
+
schema = schema.min(config.minSelect);
|
|
435
|
+
}
|
|
436
|
+
if (config.maxSelect !== void 0) {
|
|
437
|
+
schema = schema.max(config.maxSelect);
|
|
438
|
+
}
|
|
439
|
+
return schema.describe(JSON.stringify(metadata));
|
|
440
|
+
}
|
|
441
|
+
function extractRelationMetadata(description) {
|
|
442
|
+
if (!description) return null;
|
|
443
|
+
try {
|
|
444
|
+
const parsed = JSON.parse(description);
|
|
445
|
+
if (parsed[RELATION_METADATA_KEY]) {
|
|
446
|
+
return parsed[RELATION_METADATA_KEY];
|
|
447
|
+
}
|
|
448
|
+
} catch {
|
|
449
|
+
}
|
|
450
|
+
return null;
|
|
451
|
+
}
|
|
452
|
+
function editorField() {
|
|
453
|
+
return z.string();
|
|
454
|
+
}
|
|
455
|
+
function geoPointField() {
|
|
456
|
+
return z.object({
|
|
457
|
+
lon: z.number(),
|
|
458
|
+
lat: z.number()
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
function withPermissions(schema, config) {
|
|
462
|
+
const metadata = {
|
|
463
|
+
permissions: config
|
|
464
|
+
};
|
|
465
|
+
return schema.describe(JSON.stringify(metadata));
|
|
466
|
+
}
|
|
467
|
+
function withIndexes(schema, indexes) {
|
|
468
|
+
let existingMetadata = {};
|
|
469
|
+
if (schema.description) {
|
|
470
|
+
try {
|
|
471
|
+
existingMetadata = JSON.parse(schema.description);
|
|
472
|
+
} catch {
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
const metadata = {
|
|
476
|
+
...existingMetadata,
|
|
477
|
+
indexes
|
|
478
|
+
};
|
|
479
|
+
return schema.describe(JSON.stringify(metadata));
|
|
480
|
+
}
|
|
481
|
+
function defineCollection(config) {
|
|
482
|
+
const { collectionName, schema, permissions, indexes, type, ...futureOptions } = config;
|
|
483
|
+
const metadata = {
|
|
484
|
+
collectionName
|
|
485
|
+
};
|
|
486
|
+
if (type) {
|
|
487
|
+
metadata.type = type;
|
|
488
|
+
}
|
|
489
|
+
if (permissions) {
|
|
490
|
+
metadata.permissions = permissions;
|
|
491
|
+
}
|
|
492
|
+
if (indexes) {
|
|
493
|
+
metadata.indexes = indexes;
|
|
494
|
+
}
|
|
495
|
+
if (Object.keys(futureOptions).length > 0) {
|
|
496
|
+
Object.assign(metadata, futureOptions);
|
|
497
|
+
}
|
|
498
|
+
return schema.describe(JSON.stringify(metadata));
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// src/utils/permission-templates.ts
|
|
502
|
+
var PermissionTemplates = {
|
|
503
|
+
/**
|
|
504
|
+
* Public access - anyone can perform all operations
|
|
725
505
|
*/
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
506
|
+
public: () => ({
|
|
507
|
+
listRule: "",
|
|
508
|
+
viewRule: "",
|
|
509
|
+
createRule: "",
|
|
510
|
+
updateRule: "",
|
|
511
|
+
deleteRule: ""
|
|
512
|
+
}),
|
|
729
513
|
/**
|
|
730
|
-
*
|
|
514
|
+
* Authenticated users only - requires valid authentication for all operations
|
|
731
515
|
*/
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
516
|
+
authenticated: () => ({
|
|
517
|
+
listRule: '@request.auth.id != ""',
|
|
518
|
+
viewRule: '@request.auth.id != ""',
|
|
519
|
+
createRule: '@request.auth.id != ""',
|
|
520
|
+
updateRule: '@request.auth.id != ""',
|
|
521
|
+
deleteRule: '@request.auth.id != ""'
|
|
522
|
+
}),
|
|
736
523
|
/**
|
|
737
|
-
*
|
|
738
|
-
* @param
|
|
739
|
-
* @param callback Function to call when changes occur
|
|
740
|
-
* @param expand Optional expand parameters
|
|
741
|
-
* @returns Promise that resolves to an unsubscribe function
|
|
524
|
+
* Owner-only access - users can only manage their own records
|
|
525
|
+
* @param ownerField - Name of the relation field pointing to user (default: 'User')
|
|
742
526
|
*/
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
527
|
+
ownerOnly: (ownerField = "User") => ({
|
|
528
|
+
listRule: `@request.auth.id != "" && ${ownerField} = @request.auth.id`,
|
|
529
|
+
viewRule: `@request.auth.id != "" && ${ownerField} = @request.auth.id`,
|
|
530
|
+
createRule: '@request.auth.id != ""',
|
|
531
|
+
updateRule: `@request.auth.id != "" && ${ownerField} = @request.auth.id`,
|
|
532
|
+
deleteRule: `@request.auth.id != "" && ${ownerField} = @request.auth.id`
|
|
533
|
+
}),
|
|
748
534
|
/**
|
|
749
|
-
*
|
|
750
|
-
*
|
|
751
|
-
* @param
|
|
752
|
-
* @returns Promise that resolves to an unsubscribe function
|
|
535
|
+
* Admin/superuser only access
|
|
536
|
+
* Assumes a 'role' field exists with 'admin' value
|
|
537
|
+
* @param roleField - Name of the role field (default: 'role')
|
|
753
538
|
*/
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
539
|
+
adminOnly: (roleField = "role") => ({
|
|
540
|
+
listRule: `@request.auth.id != "" && @request.auth.${roleField} = "admin"`,
|
|
541
|
+
viewRule: `@request.auth.id != "" && @request.auth.${roleField} = "admin"`,
|
|
542
|
+
createRule: `@request.auth.id != "" && @request.auth.${roleField} = "admin"`,
|
|
543
|
+
updateRule: `@request.auth.id != "" && @request.auth.${roleField} = "admin"`,
|
|
544
|
+
deleteRule: `@request.auth.id != "" && @request.auth.${roleField} = "admin"`
|
|
545
|
+
}),
|
|
759
546
|
/**
|
|
760
|
-
*
|
|
761
|
-
*
|
|
547
|
+
* Public read, authenticated write
|
|
548
|
+
* Anyone can list/view, but only authenticated users can create/update/delete
|
|
762
549
|
*/
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
550
|
+
readPublic: () => ({
|
|
551
|
+
listRule: "",
|
|
552
|
+
viewRule: "",
|
|
553
|
+
createRule: '@request.auth.id != ""',
|
|
554
|
+
updateRule: '@request.auth.id != ""',
|
|
555
|
+
deleteRule: '@request.auth.id != ""'
|
|
556
|
+
}),
|
|
766
557
|
/**
|
|
767
|
-
*
|
|
558
|
+
* Locked access - only superusers can perform operations
|
|
559
|
+
* All rules are set to null (locked)
|
|
768
560
|
*/
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
561
|
+
locked: () => ({
|
|
562
|
+
listRule: null,
|
|
563
|
+
viewRule: null,
|
|
564
|
+
createRule: null,
|
|
565
|
+
updateRule: null,
|
|
566
|
+
deleteRule: null
|
|
567
|
+
}),
|
|
772
568
|
/**
|
|
773
|
-
*
|
|
569
|
+
* Read-only authenticated - authenticated users can read, no write access
|
|
774
570
|
*/
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
571
|
+
readOnlyAuthenticated: () => ({
|
|
572
|
+
listRule: '@request.auth.id != ""',
|
|
573
|
+
viewRule: '@request.auth.id != ""',
|
|
574
|
+
createRule: null,
|
|
575
|
+
updateRule: null,
|
|
576
|
+
deleteRule: null
|
|
577
|
+
})
|
|
778
578
|
};
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
579
|
+
function resolveTemplate(config) {
|
|
580
|
+
let baseRules;
|
|
581
|
+
switch (config.template) {
|
|
582
|
+
case "public":
|
|
583
|
+
baseRules = PermissionTemplates.public();
|
|
584
|
+
break;
|
|
585
|
+
case "authenticated":
|
|
586
|
+
baseRules = PermissionTemplates.authenticated();
|
|
587
|
+
break;
|
|
588
|
+
case "owner-only":
|
|
589
|
+
baseRules = PermissionTemplates.ownerOnly(config.ownerField);
|
|
590
|
+
break;
|
|
591
|
+
case "admin-only":
|
|
592
|
+
baseRules = PermissionTemplates.adminOnly(config.roleField);
|
|
593
|
+
break;
|
|
594
|
+
case "read-public":
|
|
595
|
+
baseRules = PermissionTemplates.readPublic();
|
|
596
|
+
break;
|
|
597
|
+
case "custom":
|
|
598
|
+
baseRules = {};
|
|
599
|
+
break;
|
|
600
|
+
default: {
|
|
601
|
+
const _exhaustive = config.template;
|
|
602
|
+
throw new Error(`Unknown template type: ${_exhaustive}`);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
return {
|
|
606
|
+
...baseRules,
|
|
607
|
+
...config.customRules
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
function isTemplateConfig(config) {
|
|
611
|
+
return "template" in config;
|
|
612
|
+
}
|
|
613
|
+
function isPermissionSchema(config) {
|
|
614
|
+
return "listRule" in config || "viewRule" in config || "createRule" in config || "updateRule" in config || "deleteRule" in config || "manageRule" in config;
|
|
615
|
+
}
|
|
616
|
+
function validatePermissionConfig(config, isAuthCollection2 = false) {
|
|
617
|
+
const result = {
|
|
618
|
+
valid: true,
|
|
619
|
+
errors: [],
|
|
620
|
+
warnings: []
|
|
621
|
+
};
|
|
622
|
+
let permissions;
|
|
623
|
+
if (isTemplateConfig(config)) {
|
|
624
|
+
if (config.template === "owner-only" && !config.ownerField) {
|
|
625
|
+
result.warnings.push("owner-only template without ownerField specified - using default 'User'");
|
|
626
|
+
}
|
|
627
|
+
if (config.template === "admin-only" && !config.roleField) {
|
|
628
|
+
result.warnings.push("admin-only template without roleField specified - using default 'role'");
|
|
629
|
+
}
|
|
630
|
+
permissions = resolveTemplate(config);
|
|
631
|
+
} else {
|
|
632
|
+
permissions = config;
|
|
633
|
+
}
|
|
634
|
+
if (permissions.manageRule !== void 0 && !isAuthCollection2) {
|
|
635
|
+
result.errors.push("manageRule is only valid for auth collections");
|
|
636
|
+
result.valid = false;
|
|
788
637
|
}
|
|
789
|
-
|
|
790
|
-
|
|
638
|
+
const ruleTypes = ["listRule", "viewRule", "createRule", "updateRule", "deleteRule"];
|
|
639
|
+
if (isAuthCollection2) {
|
|
640
|
+
ruleTypes.push("manageRule");
|
|
791
641
|
}
|
|
792
|
-
|
|
793
|
-
|
|
642
|
+
for (const ruleType of ruleTypes) {
|
|
643
|
+
const rule = permissions[ruleType];
|
|
644
|
+
if (rule !== void 0 && rule !== null && rule !== "") {
|
|
645
|
+
const ruleValidation = validateRuleExpression(rule);
|
|
646
|
+
if (!ruleValidation.valid) {
|
|
647
|
+
result.errors.push(`${ruleType}: ${ruleValidation.errors.join(", ")}`);
|
|
648
|
+
result.valid = false;
|
|
649
|
+
}
|
|
650
|
+
result.warnings.push(...ruleValidation.warnings.map((w) => `${ruleType}: ${w}`));
|
|
651
|
+
}
|
|
794
652
|
}
|
|
795
|
-
|
|
653
|
+
return result;
|
|
654
|
+
}
|
|
655
|
+
function validateRuleExpression(expression) {
|
|
656
|
+
const result = {
|
|
657
|
+
valid: true,
|
|
658
|
+
errors: [],
|
|
659
|
+
warnings: []
|
|
660
|
+
};
|
|
661
|
+
if (expression === null || expression === "") {
|
|
662
|
+
return result;
|
|
663
|
+
}
|
|
664
|
+
let parenCount = 0;
|
|
665
|
+
for (const char of expression) {
|
|
666
|
+
if (char === "(") parenCount++;
|
|
667
|
+
if (char === ")") parenCount--;
|
|
668
|
+
if (parenCount < 0) {
|
|
669
|
+
result.errors.push("Unbalanced parentheses");
|
|
670
|
+
result.valid = false;
|
|
671
|
+
return result;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
if (parenCount !== 0) {
|
|
675
|
+
result.errors.push("Unbalanced parentheses");
|
|
676
|
+
result.valid = false;
|
|
677
|
+
}
|
|
678
|
+
if (expression.includes("==")) {
|
|
679
|
+
result.warnings.push("Use '=' instead of '==' for equality comparison");
|
|
680
|
+
}
|
|
681
|
+
const requestRefs = expression.match(/@request\.[a-zA-Z_][a-zA-Z0-9_.]*/g) || [];
|
|
682
|
+
for (const ref of requestRefs) {
|
|
683
|
+
const isValid = ref.startsWith("@request.auth.") || ref === "@request.method" || ref === "@request.context" || ref.startsWith("@request.body.") || ref.startsWith("@request.query.") || ref.startsWith("@request.headers.");
|
|
684
|
+
if (!isValid) {
|
|
685
|
+
result.errors.push(`Invalid @request reference: '${ref}'`);
|
|
686
|
+
result.valid = false;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
return result;
|
|
690
|
+
}
|
|
691
|
+
function createPermissions(permissions) {
|
|
692
|
+
return {
|
|
693
|
+
listRule: permissions.listRule ?? null,
|
|
694
|
+
viewRule: permissions.viewRule ?? null,
|
|
695
|
+
createRule: permissions.createRule ?? null,
|
|
696
|
+
updateRule: permissions.updateRule ?? null,
|
|
697
|
+
deleteRule: permissions.deleteRule ?? null,
|
|
698
|
+
manageRule: permissions.manageRule ?? null
|
|
699
|
+
};
|
|
700
|
+
}
|
|
701
|
+
function mergePermissions(...schemas) {
|
|
702
|
+
const merged = {
|
|
703
|
+
listRule: null,
|
|
704
|
+
viewRule: null,
|
|
705
|
+
createRule: null,
|
|
706
|
+
updateRule: null,
|
|
707
|
+
deleteRule: null,
|
|
708
|
+
manageRule: null
|
|
709
|
+
};
|
|
710
|
+
for (const schema of schemas) {
|
|
711
|
+
if (schema.listRule !== void 0) merged.listRule = schema.listRule;
|
|
712
|
+
if (schema.viewRule !== void 0) merged.viewRule = schema.viewRule;
|
|
713
|
+
if (schema.createRule !== void 0) merged.createRule = schema.createRule;
|
|
714
|
+
if (schema.updateRule !== void 0) merged.updateRule = schema.updateRule;
|
|
715
|
+
if (schema.deleteRule !== void 0) merged.deleteRule = schema.deleteRule;
|
|
716
|
+
if (schema.manageRule !== void 0) merged.manageRule = schema.manageRule;
|
|
717
|
+
}
|
|
718
|
+
return merged;
|
|
719
|
+
}
|
|
796
720
|
|
|
797
721
|
// src/migration/errors.ts
|
|
798
722
|
var MigrationError = class _MigrationError extends Error {
|
|
@@ -5319,6 +5243,6 @@ async function executeStatus(options) {
|
|
|
5319
5243
|
}
|
|
5320
5244
|
}
|
|
5321
5245
|
|
|
5322
|
-
export { CLIUsageError, ConfigurationError, DiffEngine, FIELD_TYPE_INFO, FileSystemError, MigrationError, MigrationGenerationError, MigrationGenerator, POCKETBASE_FIELD_TYPES, PermissionTemplates,
|
|
5246
|
+
export { BaseMutator, CLIUsageError, ConfigurationError, DiffEngine, FIELD_TYPE_INFO, FileSystemError, MigrationError, MigrationGenerationError, MigrationGenerator, POCKETBASE_FIELD_TYPES, PermissionTemplates, RelationField, RelationsField, SchemaAnalyzer, SchemaParsingError, SnapshotError, SnapshotManager, StatusEnum, aggregateChanges, baseImageFileSchema, baseSchema, baseSchemaWithTimestamps, boolField, buildFieldDefinition, buildSchemaDefinition, categorizeChangesBySeverity, compare, compareFieldConstraints, compareFieldOptions, compareFieldTypes, comparePermissions, compareRelationConfigurations, convertPocketBaseMigration, convertZodSchemaToCollectionSchema, createMigrationFileStructure, createPermissions, dateField, defineCollection, detectDestructiveChanges, detectFieldChanges, discoverSchemaFiles, editorField, emailField, extractComprehensiveFieldOptions, extractFieldDefinitions, extractFieldOptions, extractIndexes, extractRelationMetadata, extractSchemaDefinitions, fileField, filesField, filterSystemCollections, findLatestSnapshot, findNewCollections, findNewFields, findRemovedCollections, findRemovedFields, formatChangeSummary, generate, generateChangeSummary, generateCollectionCreation, generateCollectionPermissions, generateCollectionRules, generateDownMigration, generateFieldAddition, generateFieldDefinitionObject, generateFieldDeletion, generateFieldModification, generateFieldsArray, generateIndexesArray, executeGenerate as generateMigration, generateMigrationDescription, generateMigrationFilename, generatePermissionUpdate, generateTimestamp, generateUpMigration, geoPointField, getArrayElementType, getCollectionNameFromFile, getDefaultValue, getFieldTypeInfo, getMaxSelect, executeStatus as getMigrationStatus, getMinSelect, getSnapshotPath, getSnapshotVersion, getUsersSystemFields, importSchemaModule, inputImageFileSchema, isArrayType, isAuthCollection, isEditorField, isFieldRequired, isFileFieldByName, isGeoPointType, isMultipleRelationField, isPermissionSchema, isRelationField, isSingleRelationField, isSystemCollection, isTemplateConfig, jsonField, loadBaseMigration, loadConfig, loadSnapshot, loadSnapshotIfExists, loadSnapshotWithMigrations, logError, logInfo, logSection, logSuccess, logWarning, mapZodArrayType, mapZodBooleanType, mapZodDateType, mapZodEnumType, mapZodNumberType, mapZodRecordType, mapZodStringType, mapZodTypeToPocketBase, matchCollectionsByName, matchFieldsByName, mergePermissions, mergeSnapshots, numberField, omitImageFilesSchema, parseSchemaFiles, pluralize, requiresForceFlag, resolveTargetCollection, resolveTemplate, saveSnapshot, selectField, selectSchemaForCollection, singularize, snapshotExists, textField, toCollectionName, unwrapZodType, urlField, validatePermissionConfig, validateRuleExpression, validateSnapshot, withIndexes, withPermissions, withProgress, writeMigrationFile };
|
|
5323
5247
|
//# sourceMappingURL=index.js.map
|
|
5324
5248
|
//# sourceMappingURL=index.js.map
|