pocketbase-zod-schema 0.2.5 → 0.3.0
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 +8 -0
- package/dist/cli/index.cjs +374 -296
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +2 -2
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.js +374 -296
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/migrate.cjs +374 -296
- package/dist/cli/migrate.cjs.map +1 -1
- package/dist/cli/migrate.js +374 -296
- package/dist/cli/migrate.js.map +1 -1
- package/dist/cli/utils/index.d.cts +2 -2
- package/dist/cli/utils/index.d.ts +2 -2
- package/dist/{fields-YjcpBXVp.d.cts → fields-UcOPu1OQ.d.cts} +16 -0
- package/dist/{fields-YjcpBXVp.d.ts → fields-UcOPu1OQ.d.ts} +16 -0
- package/dist/index.cjs +413 -114
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +414 -103
- package/dist/index.js.map +1 -1
- package/dist/migration/analyzer.cjs +12 -2
- package/dist/migration/analyzer.cjs.map +1 -1
- package/dist/migration/analyzer.d.cts +2 -2
- package/dist/migration/analyzer.d.ts +2 -2
- package/dist/migration/analyzer.js +12 -2
- package/dist/migration/analyzer.js.map +1 -1
- package/dist/migration/diff.cjs +76 -1
- package/dist/migration/diff.cjs.map +1 -1
- package/dist/migration/diff.d.cts +2 -2
- package/dist/migration/diff.d.ts +2 -2
- package/dist/migration/diff.js +76 -1
- package/dist/migration/diff.js.map +1 -1
- package/dist/migration/generator.cjs +323 -46
- package/dist/migration/generator.cjs.map +1 -1
- package/dist/migration/generator.d.cts +59 -12
- package/dist/migration/generator.d.ts +59 -12
- package/dist/migration/generator.js +319 -47
- package/dist/migration/generator.js.map +1 -1
- package/dist/migration/index.cjs +399 -49
- package/dist/migration/index.cjs.map +1 -1
- package/dist/migration/index.d.cts +3 -3
- package/dist/migration/index.d.ts +3 -3
- package/dist/migration/index.js +399 -49
- package/dist/migration/index.js.map +1 -1
- package/dist/migration/snapshot.cjs.map +1 -1
- package/dist/migration/snapshot.d.cts +2 -2
- package/dist/migration/snapshot.d.ts +2 -2
- package/dist/migration/snapshot.js.map +1 -1
- package/dist/migration/utils/index.cjs +64 -0
- package/dist/migration/utils/index.cjs.map +1 -1
- package/dist/migration/utils/index.d.cts +39 -202
- package/dist/migration/utils/index.d.ts +39 -202
- package/dist/migration/utils/index.js +63 -1
- package/dist/migration/utils/index.js.map +1 -1
- package/dist/schema.cjs +0 -61
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +2 -86
- package/dist/schema.d.ts +2 -86
- package/dist/schema.js +1 -50
- package/dist/schema.js.map +1 -1
- package/dist/type-mapper-DrQmtznD.d.cts +208 -0
- package/dist/type-mapper-n231Fspm.d.ts +208 -0
- package/dist/{types-LFBGHl9Y.d.ts → types-Ds3NQvny.d.ts} +33 -2
- package/dist/{types-mhQXWNi3.d.cts → types-YoBjsa-A.d.cts} +33 -2
- package/package.json +1 -1
package/dist/migration/index.cjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var fs3 = require('fs');
|
|
4
4
|
var path = require('path');
|
|
5
5
|
var zod = require('zod');
|
|
6
|
+
var crypto = require('crypto');
|
|
6
7
|
|
|
7
8
|
function _interopNamespace(e) {
|
|
8
9
|
if (e && e.__esModule) return e;
|
|
@@ -1581,12 +1582,22 @@ function isAuthCollection(fields) {
|
|
|
1581
1582
|
function buildFieldDefinition(fieldName, zodType) {
|
|
1582
1583
|
const fieldMetadata = extractFieldMetadata(zodType.description);
|
|
1583
1584
|
if (fieldMetadata) {
|
|
1584
|
-
|
|
1585
|
+
let required2;
|
|
1586
|
+
if (fieldMetadata.type === "number") {
|
|
1587
|
+
if (fieldMetadata.options?.required !== void 0) {
|
|
1588
|
+
required2 = fieldMetadata.options.required;
|
|
1589
|
+
} else {
|
|
1590
|
+
required2 = false;
|
|
1591
|
+
}
|
|
1592
|
+
} else {
|
|
1593
|
+
required2 = isFieldRequired(zodType);
|
|
1594
|
+
}
|
|
1595
|
+
const { required: _required, ...options2 } = fieldMetadata.options || {};
|
|
1585
1596
|
const fieldDef2 = {
|
|
1586
1597
|
name: fieldName,
|
|
1587
1598
|
type: fieldMetadata.type,
|
|
1588
1599
|
required: required2,
|
|
1589
|
-
options:
|
|
1600
|
+
options: Object.keys(options2).length > 0 ? options2 : void 0
|
|
1590
1601
|
};
|
|
1591
1602
|
if (fieldMetadata.type === "relation") {
|
|
1592
1603
|
const relationMetadata2 = extractRelationMetadata(zodType.description);
|
|
@@ -2582,6 +2593,65 @@ var SnapshotManager = class {
|
|
|
2582
2593
|
return validateSnapshot(snapshot);
|
|
2583
2594
|
}
|
|
2584
2595
|
};
|
|
2596
|
+
function generateCollectionId() {
|
|
2597
|
+
const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
2598
|
+
const idLength = 15;
|
|
2599
|
+
const bytes = crypto.randomBytes(idLength);
|
|
2600
|
+
let id = "pb_";
|
|
2601
|
+
for (let i = 0; i < idLength; i++) {
|
|
2602
|
+
const index = bytes[i] % chars.length;
|
|
2603
|
+
id += chars[index];
|
|
2604
|
+
}
|
|
2605
|
+
return id;
|
|
2606
|
+
}
|
|
2607
|
+
var CollectionIdRegistry = class {
|
|
2608
|
+
ids;
|
|
2609
|
+
constructor() {
|
|
2610
|
+
this.ids = /* @__PURE__ */ new Set();
|
|
2611
|
+
}
|
|
2612
|
+
/**
|
|
2613
|
+
* Generates a unique collection ID for a given collection name
|
|
2614
|
+
* Special case: Returns constant "_pb_users_auth_" for users collection
|
|
2615
|
+
* Retries up to 10 times if collision occurs (extremely rare)
|
|
2616
|
+
*
|
|
2617
|
+
* @param collectionName - The name of the collection
|
|
2618
|
+
* @returns A unique collection ID
|
|
2619
|
+
* @throws Error if unable to generate unique ID after max attempts
|
|
2620
|
+
*/
|
|
2621
|
+
generate(collectionName) {
|
|
2622
|
+
if (collectionName && collectionName.toLowerCase() === "users") {
|
|
2623
|
+
const usersId = "_pb_users_auth_";
|
|
2624
|
+
this.register(usersId);
|
|
2625
|
+
return usersId;
|
|
2626
|
+
}
|
|
2627
|
+
const maxAttempts = 10;
|
|
2628
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
2629
|
+
const id = generateCollectionId();
|
|
2630
|
+
if (!this.has(id)) {
|
|
2631
|
+
this.register(id);
|
|
2632
|
+
return id;
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
throw new Error("Failed to generate unique collection ID after maximum attempts");
|
|
2636
|
+
}
|
|
2637
|
+
/**
|
|
2638
|
+
* Checks if an ID has already been registered
|
|
2639
|
+
*
|
|
2640
|
+
* @param id - The collection ID to check
|
|
2641
|
+
* @returns True if the ID exists in the registry
|
|
2642
|
+
*/
|
|
2643
|
+
has(id) {
|
|
2644
|
+
return this.ids.has(id);
|
|
2645
|
+
}
|
|
2646
|
+
/**
|
|
2647
|
+
* Registers a collection ID in the registry
|
|
2648
|
+
*
|
|
2649
|
+
* @param id - The collection ID to register
|
|
2650
|
+
*/
|
|
2651
|
+
register(id) {
|
|
2652
|
+
this.ids.add(id);
|
|
2653
|
+
}
|
|
2654
|
+
};
|
|
2585
2655
|
|
|
2586
2656
|
// src/migration/diff.ts
|
|
2587
2657
|
var DEFAULT_CONFIG3 = {
|
|
@@ -2924,6 +2994,18 @@ function aggregateChanges(currentSchema, previousSnapshot, config) {
|
|
|
2924
2994
|
const filteredCollectionsToDelete = collectionsToDelete.filter(
|
|
2925
2995
|
(collection) => !isSystemCollection(collection.name, config)
|
|
2926
2996
|
);
|
|
2997
|
+
const registry = new CollectionIdRegistry();
|
|
2998
|
+
const collectionsWithIds = filteredCollectionsToCreate.map((collection) => {
|
|
2999
|
+
if (collection.id) {
|
|
3000
|
+
registry.register(collection.id);
|
|
3001
|
+
return collection;
|
|
3002
|
+
}
|
|
3003
|
+
const id = registry.generate(collection.name);
|
|
3004
|
+
return {
|
|
3005
|
+
...collection,
|
|
3006
|
+
id
|
|
3007
|
+
};
|
|
3008
|
+
});
|
|
2927
3009
|
const collectionsToModify = [];
|
|
2928
3010
|
const matchedCollections = matchCollectionsByName(currentSchema, previousSnapshot);
|
|
2929
3011
|
for (const [currentCollection, previousCollection] of matchedCollections) {
|
|
@@ -2933,7 +3015,7 @@ function aggregateChanges(currentSchema, previousSnapshot, config) {
|
|
|
2933
3015
|
}
|
|
2934
3016
|
}
|
|
2935
3017
|
return {
|
|
2936
|
-
collectionsToCreate:
|
|
3018
|
+
collectionsToCreate: collectionsWithIds,
|
|
2937
3019
|
collectionsToDelete: filteredCollectionsToDelete,
|
|
2938
3020
|
collectionsToModify
|
|
2939
3021
|
};
|
|
@@ -3169,6 +3251,49 @@ function generateTimestamp(config) {
|
|
|
3169
3251
|
}
|
|
3170
3252
|
return Math.floor(Date.now() / 1e3).toString();
|
|
3171
3253
|
}
|
|
3254
|
+
function splitDiffByCollection(diff, baseTimestamp) {
|
|
3255
|
+
const operations = [];
|
|
3256
|
+
let currentTimestamp = parseInt(baseTimestamp, 10);
|
|
3257
|
+
for (const collection of diff.collectionsToCreate) {
|
|
3258
|
+
operations.push({
|
|
3259
|
+
type: "create",
|
|
3260
|
+
collection,
|
|
3261
|
+
timestamp: currentTimestamp.toString()
|
|
3262
|
+
});
|
|
3263
|
+
currentTimestamp += 1;
|
|
3264
|
+
}
|
|
3265
|
+
for (const modification of diff.collectionsToModify) {
|
|
3266
|
+
operations.push({
|
|
3267
|
+
type: "modify",
|
|
3268
|
+
collection: modification.collection,
|
|
3269
|
+
modifications: modification,
|
|
3270
|
+
timestamp: currentTimestamp.toString()
|
|
3271
|
+
});
|
|
3272
|
+
currentTimestamp += 1;
|
|
3273
|
+
}
|
|
3274
|
+
for (const collection of diff.collectionsToDelete) {
|
|
3275
|
+
operations.push({
|
|
3276
|
+
type: "delete",
|
|
3277
|
+
collection: collection.name || collection,
|
|
3278
|
+
// Handle both object and string
|
|
3279
|
+
timestamp: currentTimestamp.toString()
|
|
3280
|
+
});
|
|
3281
|
+
currentTimestamp += 1;
|
|
3282
|
+
}
|
|
3283
|
+
return operations;
|
|
3284
|
+
}
|
|
3285
|
+
function generateCollectionMigrationFilename(operation) {
|
|
3286
|
+
const timestamp = operation.timestamp;
|
|
3287
|
+
const operationType = operation.type === "modify" ? "updated" : operation.type === "create" ? "created" : "deleted";
|
|
3288
|
+
let collectionName;
|
|
3289
|
+
if (typeof operation.collection === "string") {
|
|
3290
|
+
collectionName = operation.collection;
|
|
3291
|
+
} else {
|
|
3292
|
+
collectionName = operation.collection.name;
|
|
3293
|
+
}
|
|
3294
|
+
const sanitizedName = collectionName.replace(/[^a-zA-Z0-9_]/g, "_").toLowerCase();
|
|
3295
|
+
return `${timestamp}_${operationType}_${sanitizedName}.js`;
|
|
3296
|
+
}
|
|
3172
3297
|
function generateMigrationDescription(diff) {
|
|
3173
3298
|
const parts = [];
|
|
3174
3299
|
if (diff.collectionsToCreate.length > 0) {
|
|
@@ -3276,14 +3401,13 @@ function formatValue(value) {
|
|
|
3276
3401
|
return "null";
|
|
3277
3402
|
}
|
|
3278
3403
|
if (typeof value === "string") {
|
|
3279
|
-
return
|
|
3404
|
+
return JSON.stringify(value);
|
|
3280
3405
|
}
|
|
3281
3406
|
if (typeof value === "number" || typeof value === "boolean") {
|
|
3282
3407
|
return String(value);
|
|
3283
3408
|
}
|
|
3284
3409
|
if (Array.isArray(value)) {
|
|
3285
|
-
|
|
3286
|
-
return `[${items}]`;
|
|
3410
|
+
return JSON.stringify(value).replace(/","/g, '", "');
|
|
3287
3411
|
}
|
|
3288
3412
|
if (typeof value === "object") {
|
|
3289
3413
|
const entries = Object.entries(value).map(([k, v]) => `${k}: ${formatValue(v)}`).join(", ");
|
|
@@ -3291,7 +3415,7 @@ function formatValue(value) {
|
|
|
3291
3415
|
}
|
|
3292
3416
|
return String(value);
|
|
3293
3417
|
}
|
|
3294
|
-
function generateFieldDefinitionObject(field) {
|
|
3418
|
+
function generateFieldDefinitionObject(field, collectionIdMap) {
|
|
3295
3419
|
const parts = [];
|
|
3296
3420
|
parts.push(` name: "${field.name}"`);
|
|
3297
3421
|
parts.push(` type: "${field.type}"`);
|
|
@@ -3299,34 +3423,47 @@ function generateFieldDefinitionObject(field) {
|
|
|
3299
3423
|
if (field.unique !== void 0) {
|
|
3300
3424
|
parts.push(` unique: ${field.unique}`);
|
|
3301
3425
|
}
|
|
3426
|
+
if (field.type === "select") {
|
|
3427
|
+
const maxSelect = field.options?.maxSelect ?? 1;
|
|
3428
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
3429
|
+
const values = field.options?.values ?? [];
|
|
3430
|
+
parts.push(` values: ${formatValue(values)}`);
|
|
3431
|
+
}
|
|
3302
3432
|
if (field.options && Object.keys(field.options).length > 0) {
|
|
3303
3433
|
for (const [key, value] of Object.entries(field.options)) {
|
|
3434
|
+
if (field.type === "select" && (key === "maxSelect" || key === "values")) {
|
|
3435
|
+
continue;
|
|
3436
|
+
}
|
|
3304
3437
|
parts.push(` ${key}: ${formatValue(value)}`);
|
|
3305
3438
|
}
|
|
3306
3439
|
}
|
|
3307
3440
|
if (field.relation) {
|
|
3308
3441
|
const isUsersCollection = field.relation.collection.toLowerCase() === "users";
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
}
|
|
3317
|
-
if (field.relation.cascadeDelete !== void 0) {
|
|
3318
|
-
parts.push(` cascadeDelete: ${field.relation.cascadeDelete}`);
|
|
3442
|
+
let collectionIdValue;
|
|
3443
|
+
if (isUsersCollection) {
|
|
3444
|
+
collectionIdValue = '"_pb_users_auth_"';
|
|
3445
|
+
} else if (collectionIdMap && collectionIdMap.has(field.relation.collection)) {
|
|
3446
|
+
collectionIdValue = `"${collectionIdMap.get(field.relation.collection)}"`;
|
|
3447
|
+
} else {
|
|
3448
|
+
collectionIdValue = `app.findCollectionByNameOrId("${field.relation.collection}").id`;
|
|
3319
3449
|
}
|
|
3450
|
+
parts.push(` collectionId: ${collectionIdValue}`);
|
|
3451
|
+
const maxSelect = field.relation.maxSelect ?? 1;
|
|
3452
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
3453
|
+
const minSelect = field.relation.minSelect ?? null;
|
|
3454
|
+
parts.push(` minSelect: ${minSelect}`);
|
|
3455
|
+
const cascadeDelete = field.relation.cascadeDelete ?? false;
|
|
3456
|
+
parts.push(` cascadeDelete: ${cascadeDelete}`);
|
|
3320
3457
|
}
|
|
3321
3458
|
return ` {
|
|
3322
3459
|
${parts.join(",\n")},
|
|
3323
3460
|
}`;
|
|
3324
3461
|
}
|
|
3325
|
-
function generateFieldsArray(fields) {
|
|
3462
|
+
function generateFieldsArray(fields, collectionIdMap) {
|
|
3326
3463
|
if (fields.length === 0) {
|
|
3327
3464
|
return "[]";
|
|
3328
3465
|
}
|
|
3329
|
-
const fieldObjects = fields.map((field) => generateFieldDefinitionObject(field));
|
|
3466
|
+
const fieldObjects = fields.map((field) => generateFieldDefinitionObject(field, collectionIdMap));
|
|
3330
3467
|
return `[
|
|
3331
3468
|
${fieldObjects.join(",\n")},
|
|
3332
3469
|
]`;
|
|
@@ -3385,7 +3522,7 @@ function generateIndexesArray(indexes) {
|
|
|
3385
3522
|
if (!indexes || indexes.length === 0) {
|
|
3386
3523
|
return "[]";
|
|
3387
3524
|
}
|
|
3388
|
-
const indexStrings = indexes.map((idx) =>
|
|
3525
|
+
const indexStrings = indexes.map((idx) => JSON.stringify(idx));
|
|
3389
3526
|
return `[
|
|
3390
3527
|
${indexStrings.join(",\n ")},
|
|
3391
3528
|
]`;
|
|
@@ -3439,7 +3576,7 @@ function getSystemFields() {
|
|
|
3439
3576
|
}
|
|
3440
3577
|
];
|
|
3441
3578
|
}
|
|
3442
|
-
function generateCollectionCreation(collection, varName = "collection", isLast = false) {
|
|
3579
|
+
function generateCollectionCreation(collection, varName = "collection", isLast = false, collectionIdMap) {
|
|
3443
3580
|
const lines = [];
|
|
3444
3581
|
lines.push(` const ${varName} = new Collection({`);
|
|
3445
3582
|
lines.push(` name: "${collection.name}",`);
|
|
@@ -3453,7 +3590,7 @@ function generateCollectionCreation(collection, varName = "collection", isLast =
|
|
|
3453
3590
|
}
|
|
3454
3591
|
const systemFields = getSystemFields();
|
|
3455
3592
|
const allFields = [...systemFields, ...collection.fields];
|
|
3456
|
-
lines.push(` fields: ${generateFieldsArray(allFields)},`);
|
|
3593
|
+
lines.push(` fields: ${generateFieldsArray(allFields, collectionIdMap)},`);
|
|
3457
3594
|
lines.push(` indexes: ${generateIndexesArray(collection.indexes)},`);
|
|
3458
3595
|
lines.push(` });`);
|
|
3459
3596
|
lines.push(``);
|
|
@@ -3475,42 +3612,59 @@ function getFieldConstructorName(fieldType) {
|
|
|
3475
3612
|
};
|
|
3476
3613
|
return constructorMap[fieldType] || "TextField";
|
|
3477
3614
|
}
|
|
3478
|
-
function generateFieldConstructorOptions(field) {
|
|
3615
|
+
function generateFieldConstructorOptions(field, collectionIdMap) {
|
|
3479
3616
|
const parts = [];
|
|
3480
3617
|
parts.push(` name: "${field.name}"`);
|
|
3481
3618
|
parts.push(` required: ${field.required}`);
|
|
3482
3619
|
if (field.unique !== void 0) {
|
|
3483
3620
|
parts.push(` unique: ${field.unique}`);
|
|
3484
3621
|
}
|
|
3622
|
+
if (field.type === "select") {
|
|
3623
|
+
const maxSelect = field.options?.maxSelect ?? 1;
|
|
3624
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
3625
|
+
const values = field.options?.values ?? [];
|
|
3626
|
+
parts.push(` values: ${formatValue(values)}`);
|
|
3627
|
+
}
|
|
3485
3628
|
if (field.options && Object.keys(field.options).length > 0) {
|
|
3486
3629
|
for (const [key, value] of Object.entries(field.options)) {
|
|
3487
|
-
|
|
3630
|
+
if (field.type === "select" && (key === "maxSelect" || key === "values")) {
|
|
3631
|
+
continue;
|
|
3632
|
+
}
|
|
3633
|
+
if (field.type === "number" && key === "noDecimal") {
|
|
3634
|
+
parts.push(` onlyInt: ${formatValue(value)}`);
|
|
3635
|
+
} else {
|
|
3636
|
+
parts.push(` ${key}: ${formatValue(value)}`);
|
|
3637
|
+
}
|
|
3488
3638
|
}
|
|
3489
3639
|
}
|
|
3490
3640
|
if (field.relation && field.type === "relation") {
|
|
3491
3641
|
const isUsersCollection = field.relation.collection.toLowerCase() === "users";
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
}
|
|
3500
|
-
if (field.relation.cascadeDelete !== void 0) {
|
|
3501
|
-
parts.push(` cascadeDelete: ${field.relation.cascadeDelete}`);
|
|
3642
|
+
let collectionIdValue;
|
|
3643
|
+
if (isUsersCollection) {
|
|
3644
|
+
collectionIdValue = '"_pb_users_auth_"';
|
|
3645
|
+
} else if (collectionIdMap && collectionIdMap.has(field.relation.collection)) {
|
|
3646
|
+
collectionIdValue = `"${collectionIdMap.get(field.relation.collection)}"`;
|
|
3647
|
+
} else {
|
|
3648
|
+
collectionIdValue = `app.findCollectionByNameOrId("${field.relation.collection}").id`;
|
|
3502
3649
|
}
|
|
3650
|
+
parts.push(` collectionId: ${collectionIdValue}`);
|
|
3651
|
+
const maxSelect = field.relation.maxSelect ?? 1;
|
|
3652
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
3653
|
+
const minSelect = field.relation.minSelect ?? null;
|
|
3654
|
+
parts.push(` minSelect: ${minSelect}`);
|
|
3655
|
+
const cascadeDelete = field.relation.cascadeDelete ?? false;
|
|
3656
|
+
parts.push(` cascadeDelete: ${cascadeDelete}`);
|
|
3503
3657
|
}
|
|
3504
3658
|
return parts.join(",\n");
|
|
3505
3659
|
}
|
|
3506
|
-
function generateFieldAddition(collectionName, field, varName, isLast = false) {
|
|
3660
|
+
function generateFieldAddition(collectionName, field, varName, isLast = false, collectionIdMap) {
|
|
3507
3661
|
const lines = [];
|
|
3508
3662
|
const constructorName = getFieldConstructorName(field.type);
|
|
3509
3663
|
const collectionVar = varName || `collection_${collectionName}_${field.name}`;
|
|
3510
3664
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
3511
3665
|
lines.push(``);
|
|
3512
3666
|
lines.push(` ${collectionVar}.fields.add(new ${constructorName}({`);
|
|
3513
|
-
lines.push(generateFieldConstructorOptions(field));
|
|
3667
|
+
lines.push(generateFieldConstructorOptions(field, collectionIdMap));
|
|
3514
3668
|
lines.push(` }));`);
|
|
3515
3669
|
lines.push(``);
|
|
3516
3670
|
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
@@ -3560,7 +3714,7 @@ function generateIndexAddition(collectionName, index, varName, isLast = false) {
|
|
|
3560
3714
|
const lines = [];
|
|
3561
3715
|
const collectionVar = varName || `collection_${collectionName}_idx`;
|
|
3562
3716
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
3563
|
-
lines.push(` ${collectionVar}.indexes.push(
|
|
3717
|
+
lines.push(` ${collectionVar}.indexes.push(${JSON.stringify(index)});`);
|
|
3564
3718
|
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
3565
3719
|
return lines.join("\n");
|
|
3566
3720
|
}
|
|
@@ -3569,7 +3723,7 @@ function generateIndexRemoval(collectionName, index, varName, isLast = false) {
|
|
|
3569
3723
|
const collectionVar = varName || `collection_${collectionName}_idx`;
|
|
3570
3724
|
const indexVar = `${collectionVar}_indexToRemove`;
|
|
3571
3725
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
3572
|
-
lines.push(` const ${indexVar} = ${collectionVar}.indexes.findIndex(idx => idx ===
|
|
3726
|
+
lines.push(` const ${indexVar} = ${collectionVar}.indexes.findIndex(idx => idx === ${JSON.stringify(index)});`);
|
|
3573
3727
|
lines.push(` if (${indexVar} !== -1) {`);
|
|
3574
3728
|
lines.push(` ${collectionVar}.indexes.splice(${indexVar}, 1);`);
|
|
3575
3729
|
lines.push(` }`);
|
|
@@ -3598,16 +3752,179 @@ function generateCollectionDeletion(collectionName, varName = "collection", isLa
|
|
|
3598
3752
|
lines.push(isLast ? ` return app.delete(${varName});` : ` app.delete(${varName});`);
|
|
3599
3753
|
return lines.join("\n");
|
|
3600
3754
|
}
|
|
3755
|
+
function generateOperationUpMigration(operation, collectionIdMap) {
|
|
3756
|
+
const lines = [];
|
|
3757
|
+
if (operation.type === "create") {
|
|
3758
|
+
const collection = operation.collection;
|
|
3759
|
+
const varName = `collection_${collection.name}`;
|
|
3760
|
+
lines.push(generateCollectionCreation(collection, varName, true, collectionIdMap));
|
|
3761
|
+
} else if (operation.type === "modify") {
|
|
3762
|
+
const modification = operation.modifications;
|
|
3763
|
+
const collectionName = typeof operation.collection === "string" ? operation.collection : operation.collection?.name ?? modification.collection;
|
|
3764
|
+
let operationCount = 0;
|
|
3765
|
+
const totalOperations = modification.fieldsToAdd.length + modification.fieldsToModify.length + modification.fieldsToRemove.length + modification.indexesToAdd.length + modification.indexesToRemove.length + modification.rulesToUpdate.length + modification.permissionsToUpdate.length;
|
|
3766
|
+
for (const field of modification.fieldsToAdd) {
|
|
3767
|
+
operationCount++;
|
|
3768
|
+
const varName = `collection_${collectionName}_add_${field.name}`;
|
|
3769
|
+
const isLast = operationCount === totalOperations;
|
|
3770
|
+
lines.push(generateFieldAddition(collectionName, field, varName, isLast, collectionIdMap));
|
|
3771
|
+
if (!isLast) lines.push("");
|
|
3772
|
+
}
|
|
3773
|
+
for (const fieldMod of modification.fieldsToModify) {
|
|
3774
|
+
operationCount++;
|
|
3775
|
+
const varName = `collection_${collectionName}_modify_${fieldMod.fieldName}`;
|
|
3776
|
+
const isLast = operationCount === totalOperations;
|
|
3777
|
+
lines.push(generateFieldModification(collectionName, fieldMod, varName, isLast));
|
|
3778
|
+
if (!isLast) lines.push("");
|
|
3779
|
+
}
|
|
3780
|
+
for (const field of modification.fieldsToRemove) {
|
|
3781
|
+
operationCount++;
|
|
3782
|
+
const varName = `collection_${collectionName}_remove_${field.name}`;
|
|
3783
|
+
const isLast = operationCount === totalOperations;
|
|
3784
|
+
lines.push(generateFieldDeletion(collectionName, field.name, varName, isLast));
|
|
3785
|
+
if (!isLast) lines.push("");
|
|
3786
|
+
}
|
|
3787
|
+
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
3788
|
+
operationCount++;
|
|
3789
|
+
const index = modification.indexesToAdd[i];
|
|
3790
|
+
const varName = `collection_${collectionName}_addidx_${i}`;
|
|
3791
|
+
const isLast = operationCount === totalOperations;
|
|
3792
|
+
lines.push(generateIndexAddition(collectionName, index, varName, isLast));
|
|
3793
|
+
if (!isLast) lines.push("");
|
|
3794
|
+
}
|
|
3795
|
+
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
3796
|
+
operationCount++;
|
|
3797
|
+
const index = modification.indexesToRemove[i];
|
|
3798
|
+
const varName = `collection_${collectionName}_rmidx_${i}`;
|
|
3799
|
+
const isLast = operationCount === totalOperations;
|
|
3800
|
+
lines.push(generateIndexRemoval(collectionName, index, varName, isLast));
|
|
3801
|
+
if (!isLast) lines.push("");
|
|
3802
|
+
}
|
|
3803
|
+
if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {
|
|
3804
|
+
for (const permission of modification.permissionsToUpdate) {
|
|
3805
|
+
operationCount++;
|
|
3806
|
+
const varName = `collection_${collectionName}_perm_${permission.ruleType}`;
|
|
3807
|
+
const isLast = operationCount === totalOperations;
|
|
3808
|
+
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.newValue, varName, isLast));
|
|
3809
|
+
if (!isLast) lines.push("");
|
|
3810
|
+
}
|
|
3811
|
+
} else if (modification.rulesToUpdate.length > 0) {
|
|
3812
|
+
for (const rule of modification.rulesToUpdate) {
|
|
3813
|
+
operationCount++;
|
|
3814
|
+
const varName = `collection_${collectionName}_rule_${rule.ruleType}`;
|
|
3815
|
+
const isLast = operationCount === totalOperations;
|
|
3816
|
+
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.newValue, varName, isLast));
|
|
3817
|
+
if (!isLast) lines.push("");
|
|
3818
|
+
}
|
|
3819
|
+
}
|
|
3820
|
+
} else if (operation.type === "delete") {
|
|
3821
|
+
const collectionName = typeof operation.collection === "string" ? operation.collection : operation.collection.name;
|
|
3822
|
+
const varName = `collection_${collectionName}`;
|
|
3823
|
+
lines.push(generateCollectionDeletion(collectionName, varName, true));
|
|
3824
|
+
}
|
|
3825
|
+
return lines.join("\n");
|
|
3826
|
+
}
|
|
3827
|
+
function generateOperationDownMigration(operation, collectionIdMap) {
|
|
3828
|
+
const lines = [];
|
|
3829
|
+
if (operation.type === "create") {
|
|
3830
|
+
const collection = operation.collection;
|
|
3831
|
+
const varName = `collection_${collection.name}`;
|
|
3832
|
+
lines.push(generateCollectionDeletion(collection.name, varName, true));
|
|
3833
|
+
} else if (operation.type === "modify") {
|
|
3834
|
+
const modification = operation.modifications;
|
|
3835
|
+
const collectionName = typeof operation.collection === "string" ? operation.collection : operation.collection?.name ?? modification.collection;
|
|
3836
|
+
let operationCount = 0;
|
|
3837
|
+
const totalOperations = modification.fieldsToAdd.length + modification.fieldsToModify.length + modification.fieldsToRemove.length + modification.indexesToAdd.length + modification.indexesToRemove.length + modification.rulesToUpdate.length + modification.permissionsToUpdate.length;
|
|
3838
|
+
if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {
|
|
3839
|
+
for (const permission of modification.permissionsToUpdate) {
|
|
3840
|
+
operationCount++;
|
|
3841
|
+
const varName = `collection_${collectionName}_revert_perm_${permission.ruleType}`;
|
|
3842
|
+
const isLast = operationCount === totalOperations;
|
|
3843
|
+
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.oldValue, varName, isLast));
|
|
3844
|
+
if (!isLast) lines.push("");
|
|
3845
|
+
}
|
|
3846
|
+
} else if (modification.rulesToUpdate.length > 0) {
|
|
3847
|
+
for (const rule of modification.rulesToUpdate) {
|
|
3848
|
+
operationCount++;
|
|
3849
|
+
const varName = `collection_${collectionName}_revert_rule_${rule.ruleType}`;
|
|
3850
|
+
const isLast = operationCount === totalOperations;
|
|
3851
|
+
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.oldValue, varName, isLast));
|
|
3852
|
+
if (!isLast) lines.push("");
|
|
3853
|
+
}
|
|
3854
|
+
}
|
|
3855
|
+
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
3856
|
+
operationCount++;
|
|
3857
|
+
const index = modification.indexesToRemove[i];
|
|
3858
|
+
const varName = `collection_${collectionName}_restore_idx_${i}`;
|
|
3859
|
+
const isLast = operationCount === totalOperations;
|
|
3860
|
+
lines.push(generateIndexAddition(collectionName, index, varName, isLast));
|
|
3861
|
+
if (!isLast) lines.push("");
|
|
3862
|
+
}
|
|
3863
|
+
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
3864
|
+
operationCount++;
|
|
3865
|
+
const index = modification.indexesToAdd[i];
|
|
3866
|
+
const varName = `collection_${collectionName}_revert_idx_${i}`;
|
|
3867
|
+
const isLast = operationCount === totalOperations;
|
|
3868
|
+
lines.push(generateIndexRemoval(collectionName, index, varName, isLast));
|
|
3869
|
+
if (!isLast) lines.push("");
|
|
3870
|
+
}
|
|
3871
|
+
for (const field of modification.fieldsToRemove) {
|
|
3872
|
+
operationCount++;
|
|
3873
|
+
const varName = `collection_${collectionName}_restore_${field.name}`;
|
|
3874
|
+
const isLast = operationCount === totalOperations;
|
|
3875
|
+
lines.push(generateFieldAddition(collectionName, field, varName, isLast, collectionIdMap));
|
|
3876
|
+
if (!isLast) lines.push("");
|
|
3877
|
+
}
|
|
3878
|
+
for (const fieldMod of modification.fieldsToModify) {
|
|
3879
|
+
operationCount++;
|
|
3880
|
+
const reverseChanges = fieldMod.changes.map((change) => ({
|
|
3881
|
+
property: change.property,
|
|
3882
|
+
oldValue: change.newValue,
|
|
3883
|
+
newValue: change.oldValue
|
|
3884
|
+
}));
|
|
3885
|
+
const reverseMod = {
|
|
3886
|
+
fieldName: fieldMod.fieldName,
|
|
3887
|
+
currentDefinition: fieldMod.newDefinition,
|
|
3888
|
+
newDefinition: fieldMod.currentDefinition,
|
|
3889
|
+
changes: reverseChanges
|
|
3890
|
+
};
|
|
3891
|
+
const varName = `collection_${collectionName}_revert_${fieldMod.fieldName}`;
|
|
3892
|
+
const isLast = operationCount === totalOperations;
|
|
3893
|
+
lines.push(generateFieldModification(collectionName, reverseMod, varName, isLast));
|
|
3894
|
+
if (!isLast) lines.push("");
|
|
3895
|
+
}
|
|
3896
|
+
for (const field of modification.fieldsToAdd) {
|
|
3897
|
+
operationCount++;
|
|
3898
|
+
const varName = `collection_${collectionName}_revert_add_${field.name}`;
|
|
3899
|
+
const isLast = operationCount === totalOperations;
|
|
3900
|
+
lines.push(generateFieldDeletion(collectionName, field.name, varName, isLast));
|
|
3901
|
+
if (!isLast) lines.push("");
|
|
3902
|
+
}
|
|
3903
|
+
} else if (operation.type === "delete") {
|
|
3904
|
+
const collection = operation.collection;
|
|
3905
|
+
if (typeof collection !== "string") {
|
|
3906
|
+
const varName = `collection_${collection.name}`;
|
|
3907
|
+
lines.push(generateCollectionCreation(collection, varName, true, collectionIdMap));
|
|
3908
|
+
}
|
|
3909
|
+
}
|
|
3910
|
+
return lines.join("\n");
|
|
3911
|
+
}
|
|
3601
3912
|
function generateUpMigration(diff) {
|
|
3602
3913
|
const lines = [];
|
|
3603
3914
|
lines.push(` // UP MIGRATION`);
|
|
3604
3915
|
lines.push(``);
|
|
3916
|
+
const collectionIdMap = /* @__PURE__ */ new Map();
|
|
3917
|
+
for (const collection of diff.collectionsToCreate) {
|
|
3918
|
+
if (collection.id) {
|
|
3919
|
+
collectionIdMap.set(collection.name, collection.id);
|
|
3920
|
+
}
|
|
3921
|
+
}
|
|
3605
3922
|
if (diff.collectionsToCreate.length > 0) {
|
|
3606
3923
|
lines.push(` // Create new collections`);
|
|
3607
3924
|
for (let i = 0; i < diff.collectionsToCreate.length; i++) {
|
|
3608
3925
|
const collection = diff.collectionsToCreate[i];
|
|
3609
3926
|
const varName = `collection_${collection.name}_create`;
|
|
3610
|
-
lines.push(generateCollectionCreation(collection, varName));
|
|
3927
|
+
lines.push(generateCollectionCreation(collection, varName, false, collectionIdMap));
|
|
3611
3928
|
lines.push(``);
|
|
3612
3929
|
}
|
|
3613
3930
|
}
|
|
@@ -3619,7 +3936,7 @@ function generateUpMigration(diff) {
|
|
|
3619
3936
|
lines.push(` // Add fields to ${collectionName}`);
|
|
3620
3937
|
for (const field of modification.fieldsToAdd) {
|
|
3621
3938
|
const varName = `collection_${collectionName}_add_${field.name}`;
|
|
3622
|
-
lines.push(generateFieldAddition(collectionName, field, varName));
|
|
3939
|
+
lines.push(generateFieldAddition(collectionName, field, varName, false, collectionIdMap));
|
|
3623
3940
|
lines.push(``);
|
|
3624
3941
|
}
|
|
3625
3942
|
}
|
|
@@ -3710,12 +4027,23 @@ function generateDownMigration(diff) {
|
|
|
3710
4027
|
const lines = [];
|
|
3711
4028
|
lines.push(` // DOWN MIGRATION (ROLLBACK)`);
|
|
3712
4029
|
lines.push(``);
|
|
4030
|
+
const collectionIdMap = /* @__PURE__ */ new Map();
|
|
4031
|
+
for (const collection of diff.collectionsToCreate) {
|
|
4032
|
+
if (collection.id) {
|
|
4033
|
+
collectionIdMap.set(collection.name, collection.id);
|
|
4034
|
+
}
|
|
4035
|
+
}
|
|
4036
|
+
for (const collection of diff.collectionsToDelete) {
|
|
4037
|
+
if (collection.id) {
|
|
4038
|
+
collectionIdMap.set(collection.name, collection.id);
|
|
4039
|
+
}
|
|
4040
|
+
}
|
|
3713
4041
|
if (diff.collectionsToDelete.length > 0) {
|
|
3714
4042
|
lines.push(` // Recreate deleted collections`);
|
|
3715
4043
|
for (let i = 0; i < diff.collectionsToDelete.length; i++) {
|
|
3716
4044
|
const collection = diff.collectionsToDelete[i];
|
|
3717
4045
|
const varName = `collection_${collection.name}_recreate`;
|
|
3718
|
-
lines.push(generateCollectionCreation(collection, varName));
|
|
4046
|
+
lines.push(generateCollectionCreation(collection, varName, false, collectionIdMap));
|
|
3719
4047
|
lines.push(``);
|
|
3720
4048
|
}
|
|
3721
4049
|
}
|
|
@@ -3760,7 +4088,7 @@ function generateDownMigration(diff) {
|
|
|
3760
4088
|
lines.push(` // Restore fields to ${collectionName}`);
|
|
3761
4089
|
for (const field of modification.fieldsToRemove) {
|
|
3762
4090
|
const varName = `collection_${collectionName}_restore_${field.name}`;
|
|
3763
|
-
lines.push(generateFieldAddition(collectionName, field, varName));
|
|
4091
|
+
lines.push(generateFieldAddition(collectionName, field, varName, false, collectionIdMap));
|
|
3764
4092
|
lines.push(``);
|
|
3765
4093
|
}
|
|
3766
4094
|
}
|
|
@@ -3829,12 +4157,33 @@ function generate(diff, config) {
|
|
|
3829
4157
|
const normalizedConfig = typeof config === "string" ? { migrationDir: config } : config;
|
|
3830
4158
|
try {
|
|
3831
4159
|
const migrationDir = resolveMigrationDir(normalizedConfig);
|
|
3832
|
-
const
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
const
|
|
3837
|
-
|
|
4160
|
+
const hasChanges2 = diff.collectionsToCreate.length > 0 || diff.collectionsToModify.length > 0 || diff.collectionsToDelete.length > 0;
|
|
4161
|
+
if (!hasChanges2) {
|
|
4162
|
+
return [];
|
|
4163
|
+
}
|
|
4164
|
+
const collectionIdMap = /* @__PURE__ */ new Map();
|
|
4165
|
+
for (const collection of diff.collectionsToCreate) {
|
|
4166
|
+
if (collection.id) {
|
|
4167
|
+
collectionIdMap.set(collection.name, collection.id);
|
|
4168
|
+
}
|
|
4169
|
+
}
|
|
4170
|
+
for (const collection of diff.collectionsToDelete) {
|
|
4171
|
+
if (collection.id) {
|
|
4172
|
+
collectionIdMap.set(collection.name, collection.id);
|
|
4173
|
+
}
|
|
4174
|
+
}
|
|
4175
|
+
const baseTimestamp = generateTimestamp(normalizedConfig);
|
|
4176
|
+
const operations = splitDiffByCollection(diff, baseTimestamp);
|
|
4177
|
+
const filePaths = [];
|
|
4178
|
+
for (const operation of operations) {
|
|
4179
|
+
const upCode = generateOperationUpMigration(operation, collectionIdMap);
|
|
4180
|
+
const downCode = generateOperationDownMigration(operation, collectionIdMap);
|
|
4181
|
+
const content = createMigrationFileStructure(upCode, downCode, normalizedConfig);
|
|
4182
|
+
const filename = generateCollectionMigrationFilename(operation);
|
|
4183
|
+
const filePath = writeMigrationFile(migrationDir, filename, content);
|
|
4184
|
+
filePaths.push(filePath);
|
|
4185
|
+
}
|
|
4186
|
+
return filePaths;
|
|
3838
4187
|
} catch (error) {
|
|
3839
4188
|
if (error instanceof MigrationGenerationError || error instanceof FileSystemError) {
|
|
3840
4189
|
throw error;
|
|
@@ -3852,7 +4201,8 @@ var MigrationGenerator = class {
|
|
|
3852
4201
|
this.config = mergeConfig4(config);
|
|
3853
4202
|
}
|
|
3854
4203
|
/**
|
|
3855
|
-
* Generates
|
|
4204
|
+
* Generates migration files from a schema diff
|
|
4205
|
+
* Returns array of file paths (one per collection operation)
|
|
3856
4206
|
*/
|
|
3857
4207
|
generate(diff) {
|
|
3858
4208
|
return generate(diff, this.config);
|