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.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as fs3 from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
+
import { randomBytes } from 'crypto';
|
|
4
5
|
|
|
5
6
|
// src/migration/analyzer.ts
|
|
6
7
|
({
|
|
@@ -1558,12 +1559,22 @@ function isAuthCollection(fields) {
|
|
|
1558
1559
|
function buildFieldDefinition(fieldName, zodType) {
|
|
1559
1560
|
const fieldMetadata = extractFieldMetadata(zodType.description);
|
|
1560
1561
|
if (fieldMetadata) {
|
|
1561
|
-
|
|
1562
|
+
let required2;
|
|
1563
|
+
if (fieldMetadata.type === "number") {
|
|
1564
|
+
if (fieldMetadata.options?.required !== void 0) {
|
|
1565
|
+
required2 = fieldMetadata.options.required;
|
|
1566
|
+
} else {
|
|
1567
|
+
required2 = false;
|
|
1568
|
+
}
|
|
1569
|
+
} else {
|
|
1570
|
+
required2 = isFieldRequired(zodType);
|
|
1571
|
+
}
|
|
1572
|
+
const { required: _required, ...options2 } = fieldMetadata.options || {};
|
|
1562
1573
|
const fieldDef2 = {
|
|
1563
1574
|
name: fieldName,
|
|
1564
1575
|
type: fieldMetadata.type,
|
|
1565
1576
|
required: required2,
|
|
1566
|
-
options:
|
|
1577
|
+
options: Object.keys(options2).length > 0 ? options2 : void 0
|
|
1567
1578
|
};
|
|
1568
1579
|
if (fieldMetadata.type === "relation") {
|
|
1569
1580
|
const relationMetadata2 = extractRelationMetadata(zodType.description);
|
|
@@ -2559,6 +2570,65 @@ var SnapshotManager = class {
|
|
|
2559
2570
|
return validateSnapshot(snapshot);
|
|
2560
2571
|
}
|
|
2561
2572
|
};
|
|
2573
|
+
function generateCollectionId() {
|
|
2574
|
+
const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
2575
|
+
const idLength = 15;
|
|
2576
|
+
const bytes = randomBytes(idLength);
|
|
2577
|
+
let id = "pb_";
|
|
2578
|
+
for (let i = 0; i < idLength; i++) {
|
|
2579
|
+
const index = bytes[i] % chars.length;
|
|
2580
|
+
id += chars[index];
|
|
2581
|
+
}
|
|
2582
|
+
return id;
|
|
2583
|
+
}
|
|
2584
|
+
var CollectionIdRegistry = class {
|
|
2585
|
+
ids;
|
|
2586
|
+
constructor() {
|
|
2587
|
+
this.ids = /* @__PURE__ */ new Set();
|
|
2588
|
+
}
|
|
2589
|
+
/**
|
|
2590
|
+
* Generates a unique collection ID for a given collection name
|
|
2591
|
+
* Special case: Returns constant "_pb_users_auth_" for users collection
|
|
2592
|
+
* Retries up to 10 times if collision occurs (extremely rare)
|
|
2593
|
+
*
|
|
2594
|
+
* @param collectionName - The name of the collection
|
|
2595
|
+
* @returns A unique collection ID
|
|
2596
|
+
* @throws Error if unable to generate unique ID after max attempts
|
|
2597
|
+
*/
|
|
2598
|
+
generate(collectionName) {
|
|
2599
|
+
if (collectionName && collectionName.toLowerCase() === "users") {
|
|
2600
|
+
const usersId = "_pb_users_auth_";
|
|
2601
|
+
this.register(usersId);
|
|
2602
|
+
return usersId;
|
|
2603
|
+
}
|
|
2604
|
+
const maxAttempts = 10;
|
|
2605
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
2606
|
+
const id = generateCollectionId();
|
|
2607
|
+
if (!this.has(id)) {
|
|
2608
|
+
this.register(id);
|
|
2609
|
+
return id;
|
|
2610
|
+
}
|
|
2611
|
+
}
|
|
2612
|
+
throw new Error("Failed to generate unique collection ID after maximum attempts");
|
|
2613
|
+
}
|
|
2614
|
+
/**
|
|
2615
|
+
* Checks if an ID has already been registered
|
|
2616
|
+
*
|
|
2617
|
+
* @param id - The collection ID to check
|
|
2618
|
+
* @returns True if the ID exists in the registry
|
|
2619
|
+
*/
|
|
2620
|
+
has(id) {
|
|
2621
|
+
return this.ids.has(id);
|
|
2622
|
+
}
|
|
2623
|
+
/**
|
|
2624
|
+
* Registers a collection ID in the registry
|
|
2625
|
+
*
|
|
2626
|
+
* @param id - The collection ID to register
|
|
2627
|
+
*/
|
|
2628
|
+
register(id) {
|
|
2629
|
+
this.ids.add(id);
|
|
2630
|
+
}
|
|
2631
|
+
};
|
|
2562
2632
|
|
|
2563
2633
|
// src/migration/diff.ts
|
|
2564
2634
|
var DEFAULT_CONFIG3 = {
|
|
@@ -2901,6 +2971,18 @@ function aggregateChanges(currentSchema, previousSnapshot, config) {
|
|
|
2901
2971
|
const filteredCollectionsToDelete = collectionsToDelete.filter(
|
|
2902
2972
|
(collection) => !isSystemCollection(collection.name, config)
|
|
2903
2973
|
);
|
|
2974
|
+
const registry = new CollectionIdRegistry();
|
|
2975
|
+
const collectionsWithIds = filteredCollectionsToCreate.map((collection) => {
|
|
2976
|
+
if (collection.id) {
|
|
2977
|
+
registry.register(collection.id);
|
|
2978
|
+
return collection;
|
|
2979
|
+
}
|
|
2980
|
+
const id = registry.generate(collection.name);
|
|
2981
|
+
return {
|
|
2982
|
+
...collection,
|
|
2983
|
+
id
|
|
2984
|
+
};
|
|
2985
|
+
});
|
|
2904
2986
|
const collectionsToModify = [];
|
|
2905
2987
|
const matchedCollections = matchCollectionsByName(currentSchema, previousSnapshot);
|
|
2906
2988
|
for (const [currentCollection, previousCollection] of matchedCollections) {
|
|
@@ -2910,7 +2992,7 @@ function aggregateChanges(currentSchema, previousSnapshot, config) {
|
|
|
2910
2992
|
}
|
|
2911
2993
|
}
|
|
2912
2994
|
return {
|
|
2913
|
-
collectionsToCreate:
|
|
2995
|
+
collectionsToCreate: collectionsWithIds,
|
|
2914
2996
|
collectionsToDelete: filteredCollectionsToDelete,
|
|
2915
2997
|
collectionsToModify
|
|
2916
2998
|
};
|
|
@@ -3146,6 +3228,49 @@ function generateTimestamp(config) {
|
|
|
3146
3228
|
}
|
|
3147
3229
|
return Math.floor(Date.now() / 1e3).toString();
|
|
3148
3230
|
}
|
|
3231
|
+
function splitDiffByCollection(diff, baseTimestamp) {
|
|
3232
|
+
const operations = [];
|
|
3233
|
+
let currentTimestamp = parseInt(baseTimestamp, 10);
|
|
3234
|
+
for (const collection of diff.collectionsToCreate) {
|
|
3235
|
+
operations.push({
|
|
3236
|
+
type: "create",
|
|
3237
|
+
collection,
|
|
3238
|
+
timestamp: currentTimestamp.toString()
|
|
3239
|
+
});
|
|
3240
|
+
currentTimestamp += 1;
|
|
3241
|
+
}
|
|
3242
|
+
for (const modification of diff.collectionsToModify) {
|
|
3243
|
+
operations.push({
|
|
3244
|
+
type: "modify",
|
|
3245
|
+
collection: modification.collection,
|
|
3246
|
+
modifications: modification,
|
|
3247
|
+
timestamp: currentTimestamp.toString()
|
|
3248
|
+
});
|
|
3249
|
+
currentTimestamp += 1;
|
|
3250
|
+
}
|
|
3251
|
+
for (const collection of diff.collectionsToDelete) {
|
|
3252
|
+
operations.push({
|
|
3253
|
+
type: "delete",
|
|
3254
|
+
collection: collection.name || collection,
|
|
3255
|
+
// Handle both object and string
|
|
3256
|
+
timestamp: currentTimestamp.toString()
|
|
3257
|
+
});
|
|
3258
|
+
currentTimestamp += 1;
|
|
3259
|
+
}
|
|
3260
|
+
return operations;
|
|
3261
|
+
}
|
|
3262
|
+
function generateCollectionMigrationFilename(operation) {
|
|
3263
|
+
const timestamp = operation.timestamp;
|
|
3264
|
+
const operationType = operation.type === "modify" ? "updated" : operation.type === "create" ? "created" : "deleted";
|
|
3265
|
+
let collectionName;
|
|
3266
|
+
if (typeof operation.collection === "string") {
|
|
3267
|
+
collectionName = operation.collection;
|
|
3268
|
+
} else {
|
|
3269
|
+
collectionName = operation.collection.name;
|
|
3270
|
+
}
|
|
3271
|
+
const sanitizedName = collectionName.replace(/[^a-zA-Z0-9_]/g, "_").toLowerCase();
|
|
3272
|
+
return `${timestamp}_${operationType}_${sanitizedName}.js`;
|
|
3273
|
+
}
|
|
3149
3274
|
function generateMigrationDescription(diff) {
|
|
3150
3275
|
const parts = [];
|
|
3151
3276
|
if (diff.collectionsToCreate.length > 0) {
|
|
@@ -3253,14 +3378,13 @@ function formatValue(value) {
|
|
|
3253
3378
|
return "null";
|
|
3254
3379
|
}
|
|
3255
3380
|
if (typeof value === "string") {
|
|
3256
|
-
return
|
|
3381
|
+
return JSON.stringify(value);
|
|
3257
3382
|
}
|
|
3258
3383
|
if (typeof value === "number" || typeof value === "boolean") {
|
|
3259
3384
|
return String(value);
|
|
3260
3385
|
}
|
|
3261
3386
|
if (Array.isArray(value)) {
|
|
3262
|
-
|
|
3263
|
-
return `[${items}]`;
|
|
3387
|
+
return JSON.stringify(value).replace(/","/g, '", "');
|
|
3264
3388
|
}
|
|
3265
3389
|
if (typeof value === "object") {
|
|
3266
3390
|
const entries = Object.entries(value).map(([k, v]) => `${k}: ${formatValue(v)}`).join(", ");
|
|
@@ -3268,7 +3392,7 @@ function formatValue(value) {
|
|
|
3268
3392
|
}
|
|
3269
3393
|
return String(value);
|
|
3270
3394
|
}
|
|
3271
|
-
function generateFieldDefinitionObject(field) {
|
|
3395
|
+
function generateFieldDefinitionObject(field, collectionIdMap) {
|
|
3272
3396
|
const parts = [];
|
|
3273
3397
|
parts.push(` name: "${field.name}"`);
|
|
3274
3398
|
parts.push(` type: "${field.type}"`);
|
|
@@ -3276,34 +3400,47 @@ function generateFieldDefinitionObject(field) {
|
|
|
3276
3400
|
if (field.unique !== void 0) {
|
|
3277
3401
|
parts.push(` unique: ${field.unique}`);
|
|
3278
3402
|
}
|
|
3403
|
+
if (field.type === "select") {
|
|
3404
|
+
const maxSelect = field.options?.maxSelect ?? 1;
|
|
3405
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
3406
|
+
const values = field.options?.values ?? [];
|
|
3407
|
+
parts.push(` values: ${formatValue(values)}`);
|
|
3408
|
+
}
|
|
3279
3409
|
if (field.options && Object.keys(field.options).length > 0) {
|
|
3280
3410
|
for (const [key, value] of Object.entries(field.options)) {
|
|
3411
|
+
if (field.type === "select" && (key === "maxSelect" || key === "values")) {
|
|
3412
|
+
continue;
|
|
3413
|
+
}
|
|
3281
3414
|
parts.push(` ${key}: ${formatValue(value)}`);
|
|
3282
3415
|
}
|
|
3283
3416
|
}
|
|
3284
3417
|
if (field.relation) {
|
|
3285
3418
|
const isUsersCollection = field.relation.collection.toLowerCase() === "users";
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
}
|
|
3294
|
-
if (field.relation.cascadeDelete !== void 0) {
|
|
3295
|
-
parts.push(` cascadeDelete: ${field.relation.cascadeDelete}`);
|
|
3419
|
+
let collectionIdValue;
|
|
3420
|
+
if (isUsersCollection) {
|
|
3421
|
+
collectionIdValue = '"_pb_users_auth_"';
|
|
3422
|
+
} else if (collectionIdMap && collectionIdMap.has(field.relation.collection)) {
|
|
3423
|
+
collectionIdValue = `"${collectionIdMap.get(field.relation.collection)}"`;
|
|
3424
|
+
} else {
|
|
3425
|
+
collectionIdValue = `app.findCollectionByNameOrId("${field.relation.collection}").id`;
|
|
3296
3426
|
}
|
|
3427
|
+
parts.push(` collectionId: ${collectionIdValue}`);
|
|
3428
|
+
const maxSelect = field.relation.maxSelect ?? 1;
|
|
3429
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
3430
|
+
const minSelect = field.relation.minSelect ?? null;
|
|
3431
|
+
parts.push(` minSelect: ${minSelect}`);
|
|
3432
|
+
const cascadeDelete = field.relation.cascadeDelete ?? false;
|
|
3433
|
+
parts.push(` cascadeDelete: ${cascadeDelete}`);
|
|
3297
3434
|
}
|
|
3298
3435
|
return ` {
|
|
3299
3436
|
${parts.join(",\n")},
|
|
3300
3437
|
}`;
|
|
3301
3438
|
}
|
|
3302
|
-
function generateFieldsArray(fields) {
|
|
3439
|
+
function generateFieldsArray(fields, collectionIdMap) {
|
|
3303
3440
|
if (fields.length === 0) {
|
|
3304
3441
|
return "[]";
|
|
3305
3442
|
}
|
|
3306
|
-
const fieldObjects = fields.map((field) => generateFieldDefinitionObject(field));
|
|
3443
|
+
const fieldObjects = fields.map((field) => generateFieldDefinitionObject(field, collectionIdMap));
|
|
3307
3444
|
return `[
|
|
3308
3445
|
${fieldObjects.join(",\n")},
|
|
3309
3446
|
]`;
|
|
@@ -3362,7 +3499,7 @@ function generateIndexesArray(indexes) {
|
|
|
3362
3499
|
if (!indexes || indexes.length === 0) {
|
|
3363
3500
|
return "[]";
|
|
3364
3501
|
}
|
|
3365
|
-
const indexStrings = indexes.map((idx) =>
|
|
3502
|
+
const indexStrings = indexes.map((idx) => JSON.stringify(idx));
|
|
3366
3503
|
return `[
|
|
3367
3504
|
${indexStrings.join(",\n ")},
|
|
3368
3505
|
]`;
|
|
@@ -3416,7 +3553,7 @@ function getSystemFields() {
|
|
|
3416
3553
|
}
|
|
3417
3554
|
];
|
|
3418
3555
|
}
|
|
3419
|
-
function generateCollectionCreation(collection, varName = "collection", isLast = false) {
|
|
3556
|
+
function generateCollectionCreation(collection, varName = "collection", isLast = false, collectionIdMap) {
|
|
3420
3557
|
const lines = [];
|
|
3421
3558
|
lines.push(` const ${varName} = new Collection({`);
|
|
3422
3559
|
lines.push(` name: "${collection.name}",`);
|
|
@@ -3430,7 +3567,7 @@ function generateCollectionCreation(collection, varName = "collection", isLast =
|
|
|
3430
3567
|
}
|
|
3431
3568
|
const systemFields = getSystemFields();
|
|
3432
3569
|
const allFields = [...systemFields, ...collection.fields];
|
|
3433
|
-
lines.push(` fields: ${generateFieldsArray(allFields)},`);
|
|
3570
|
+
lines.push(` fields: ${generateFieldsArray(allFields, collectionIdMap)},`);
|
|
3434
3571
|
lines.push(` indexes: ${generateIndexesArray(collection.indexes)},`);
|
|
3435
3572
|
lines.push(` });`);
|
|
3436
3573
|
lines.push(``);
|
|
@@ -3452,42 +3589,59 @@ function getFieldConstructorName(fieldType) {
|
|
|
3452
3589
|
};
|
|
3453
3590
|
return constructorMap[fieldType] || "TextField";
|
|
3454
3591
|
}
|
|
3455
|
-
function generateFieldConstructorOptions(field) {
|
|
3592
|
+
function generateFieldConstructorOptions(field, collectionIdMap) {
|
|
3456
3593
|
const parts = [];
|
|
3457
3594
|
parts.push(` name: "${field.name}"`);
|
|
3458
3595
|
parts.push(` required: ${field.required}`);
|
|
3459
3596
|
if (field.unique !== void 0) {
|
|
3460
3597
|
parts.push(` unique: ${field.unique}`);
|
|
3461
3598
|
}
|
|
3599
|
+
if (field.type === "select") {
|
|
3600
|
+
const maxSelect = field.options?.maxSelect ?? 1;
|
|
3601
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
3602
|
+
const values = field.options?.values ?? [];
|
|
3603
|
+
parts.push(` values: ${formatValue(values)}`);
|
|
3604
|
+
}
|
|
3462
3605
|
if (field.options && Object.keys(field.options).length > 0) {
|
|
3463
3606
|
for (const [key, value] of Object.entries(field.options)) {
|
|
3464
|
-
|
|
3607
|
+
if (field.type === "select" && (key === "maxSelect" || key === "values")) {
|
|
3608
|
+
continue;
|
|
3609
|
+
}
|
|
3610
|
+
if (field.type === "number" && key === "noDecimal") {
|
|
3611
|
+
parts.push(` onlyInt: ${formatValue(value)}`);
|
|
3612
|
+
} else {
|
|
3613
|
+
parts.push(` ${key}: ${formatValue(value)}`);
|
|
3614
|
+
}
|
|
3465
3615
|
}
|
|
3466
3616
|
}
|
|
3467
3617
|
if (field.relation && field.type === "relation") {
|
|
3468
3618
|
const isUsersCollection = field.relation.collection.toLowerCase() === "users";
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
}
|
|
3477
|
-
if (field.relation.cascadeDelete !== void 0) {
|
|
3478
|
-
parts.push(` cascadeDelete: ${field.relation.cascadeDelete}`);
|
|
3619
|
+
let collectionIdValue;
|
|
3620
|
+
if (isUsersCollection) {
|
|
3621
|
+
collectionIdValue = '"_pb_users_auth_"';
|
|
3622
|
+
} else if (collectionIdMap && collectionIdMap.has(field.relation.collection)) {
|
|
3623
|
+
collectionIdValue = `"${collectionIdMap.get(field.relation.collection)}"`;
|
|
3624
|
+
} else {
|
|
3625
|
+
collectionIdValue = `app.findCollectionByNameOrId("${field.relation.collection}").id`;
|
|
3479
3626
|
}
|
|
3627
|
+
parts.push(` collectionId: ${collectionIdValue}`);
|
|
3628
|
+
const maxSelect = field.relation.maxSelect ?? 1;
|
|
3629
|
+
parts.push(` maxSelect: ${maxSelect}`);
|
|
3630
|
+
const minSelect = field.relation.minSelect ?? null;
|
|
3631
|
+
parts.push(` minSelect: ${minSelect}`);
|
|
3632
|
+
const cascadeDelete = field.relation.cascadeDelete ?? false;
|
|
3633
|
+
parts.push(` cascadeDelete: ${cascadeDelete}`);
|
|
3480
3634
|
}
|
|
3481
3635
|
return parts.join(",\n");
|
|
3482
3636
|
}
|
|
3483
|
-
function generateFieldAddition(collectionName, field, varName, isLast = false) {
|
|
3637
|
+
function generateFieldAddition(collectionName, field, varName, isLast = false, collectionIdMap) {
|
|
3484
3638
|
const lines = [];
|
|
3485
3639
|
const constructorName = getFieldConstructorName(field.type);
|
|
3486
3640
|
const collectionVar = varName || `collection_${collectionName}_${field.name}`;
|
|
3487
3641
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
3488
3642
|
lines.push(``);
|
|
3489
3643
|
lines.push(` ${collectionVar}.fields.add(new ${constructorName}({`);
|
|
3490
|
-
lines.push(generateFieldConstructorOptions(field));
|
|
3644
|
+
lines.push(generateFieldConstructorOptions(field, collectionIdMap));
|
|
3491
3645
|
lines.push(` }));`);
|
|
3492
3646
|
lines.push(``);
|
|
3493
3647
|
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
@@ -3537,7 +3691,7 @@ function generateIndexAddition(collectionName, index, varName, isLast = false) {
|
|
|
3537
3691
|
const lines = [];
|
|
3538
3692
|
const collectionVar = varName || `collection_${collectionName}_idx`;
|
|
3539
3693
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
3540
|
-
lines.push(` ${collectionVar}.indexes.push(
|
|
3694
|
+
lines.push(` ${collectionVar}.indexes.push(${JSON.stringify(index)});`);
|
|
3541
3695
|
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
3542
3696
|
return lines.join("\n");
|
|
3543
3697
|
}
|
|
@@ -3546,7 +3700,7 @@ function generateIndexRemoval(collectionName, index, varName, isLast = false) {
|
|
|
3546
3700
|
const collectionVar = varName || `collection_${collectionName}_idx`;
|
|
3547
3701
|
const indexVar = `${collectionVar}_indexToRemove`;
|
|
3548
3702
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
3549
|
-
lines.push(` const ${indexVar} = ${collectionVar}.indexes.findIndex(idx => idx ===
|
|
3703
|
+
lines.push(` const ${indexVar} = ${collectionVar}.indexes.findIndex(idx => idx === ${JSON.stringify(index)});`);
|
|
3550
3704
|
lines.push(` if (${indexVar} !== -1) {`);
|
|
3551
3705
|
lines.push(` ${collectionVar}.indexes.splice(${indexVar}, 1);`);
|
|
3552
3706
|
lines.push(` }`);
|
|
@@ -3575,16 +3729,179 @@ function generateCollectionDeletion(collectionName, varName = "collection", isLa
|
|
|
3575
3729
|
lines.push(isLast ? ` return app.delete(${varName});` : ` app.delete(${varName});`);
|
|
3576
3730
|
return lines.join("\n");
|
|
3577
3731
|
}
|
|
3732
|
+
function generateOperationUpMigration(operation, collectionIdMap) {
|
|
3733
|
+
const lines = [];
|
|
3734
|
+
if (operation.type === "create") {
|
|
3735
|
+
const collection = operation.collection;
|
|
3736
|
+
const varName = `collection_${collection.name}`;
|
|
3737
|
+
lines.push(generateCollectionCreation(collection, varName, true, collectionIdMap));
|
|
3738
|
+
} else if (operation.type === "modify") {
|
|
3739
|
+
const modification = operation.modifications;
|
|
3740
|
+
const collectionName = typeof operation.collection === "string" ? operation.collection : operation.collection?.name ?? modification.collection;
|
|
3741
|
+
let operationCount = 0;
|
|
3742
|
+
const totalOperations = modification.fieldsToAdd.length + modification.fieldsToModify.length + modification.fieldsToRemove.length + modification.indexesToAdd.length + modification.indexesToRemove.length + modification.rulesToUpdate.length + modification.permissionsToUpdate.length;
|
|
3743
|
+
for (const field of modification.fieldsToAdd) {
|
|
3744
|
+
operationCount++;
|
|
3745
|
+
const varName = `collection_${collectionName}_add_${field.name}`;
|
|
3746
|
+
const isLast = operationCount === totalOperations;
|
|
3747
|
+
lines.push(generateFieldAddition(collectionName, field, varName, isLast, collectionIdMap));
|
|
3748
|
+
if (!isLast) lines.push("");
|
|
3749
|
+
}
|
|
3750
|
+
for (const fieldMod of modification.fieldsToModify) {
|
|
3751
|
+
operationCount++;
|
|
3752
|
+
const varName = `collection_${collectionName}_modify_${fieldMod.fieldName}`;
|
|
3753
|
+
const isLast = operationCount === totalOperations;
|
|
3754
|
+
lines.push(generateFieldModification(collectionName, fieldMod, varName, isLast));
|
|
3755
|
+
if (!isLast) lines.push("");
|
|
3756
|
+
}
|
|
3757
|
+
for (const field of modification.fieldsToRemove) {
|
|
3758
|
+
operationCount++;
|
|
3759
|
+
const varName = `collection_${collectionName}_remove_${field.name}`;
|
|
3760
|
+
const isLast = operationCount === totalOperations;
|
|
3761
|
+
lines.push(generateFieldDeletion(collectionName, field.name, varName, isLast));
|
|
3762
|
+
if (!isLast) lines.push("");
|
|
3763
|
+
}
|
|
3764
|
+
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
3765
|
+
operationCount++;
|
|
3766
|
+
const index = modification.indexesToAdd[i];
|
|
3767
|
+
const varName = `collection_${collectionName}_addidx_${i}`;
|
|
3768
|
+
const isLast = operationCount === totalOperations;
|
|
3769
|
+
lines.push(generateIndexAddition(collectionName, index, varName, isLast));
|
|
3770
|
+
if (!isLast) lines.push("");
|
|
3771
|
+
}
|
|
3772
|
+
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
3773
|
+
operationCount++;
|
|
3774
|
+
const index = modification.indexesToRemove[i];
|
|
3775
|
+
const varName = `collection_${collectionName}_rmidx_${i}`;
|
|
3776
|
+
const isLast = operationCount === totalOperations;
|
|
3777
|
+
lines.push(generateIndexRemoval(collectionName, index, varName, isLast));
|
|
3778
|
+
if (!isLast) lines.push("");
|
|
3779
|
+
}
|
|
3780
|
+
if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {
|
|
3781
|
+
for (const permission of modification.permissionsToUpdate) {
|
|
3782
|
+
operationCount++;
|
|
3783
|
+
const varName = `collection_${collectionName}_perm_${permission.ruleType}`;
|
|
3784
|
+
const isLast = operationCount === totalOperations;
|
|
3785
|
+
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.newValue, varName, isLast));
|
|
3786
|
+
if (!isLast) lines.push("");
|
|
3787
|
+
}
|
|
3788
|
+
} else if (modification.rulesToUpdate.length > 0) {
|
|
3789
|
+
for (const rule of modification.rulesToUpdate) {
|
|
3790
|
+
operationCount++;
|
|
3791
|
+
const varName = `collection_${collectionName}_rule_${rule.ruleType}`;
|
|
3792
|
+
const isLast = operationCount === totalOperations;
|
|
3793
|
+
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.newValue, varName, isLast));
|
|
3794
|
+
if (!isLast) lines.push("");
|
|
3795
|
+
}
|
|
3796
|
+
}
|
|
3797
|
+
} else if (operation.type === "delete") {
|
|
3798
|
+
const collectionName = typeof operation.collection === "string" ? operation.collection : operation.collection.name;
|
|
3799
|
+
const varName = `collection_${collectionName}`;
|
|
3800
|
+
lines.push(generateCollectionDeletion(collectionName, varName, true));
|
|
3801
|
+
}
|
|
3802
|
+
return lines.join("\n");
|
|
3803
|
+
}
|
|
3804
|
+
function generateOperationDownMigration(operation, collectionIdMap) {
|
|
3805
|
+
const lines = [];
|
|
3806
|
+
if (operation.type === "create") {
|
|
3807
|
+
const collection = operation.collection;
|
|
3808
|
+
const varName = `collection_${collection.name}`;
|
|
3809
|
+
lines.push(generateCollectionDeletion(collection.name, varName, true));
|
|
3810
|
+
} else if (operation.type === "modify") {
|
|
3811
|
+
const modification = operation.modifications;
|
|
3812
|
+
const collectionName = typeof operation.collection === "string" ? operation.collection : operation.collection?.name ?? modification.collection;
|
|
3813
|
+
let operationCount = 0;
|
|
3814
|
+
const totalOperations = modification.fieldsToAdd.length + modification.fieldsToModify.length + modification.fieldsToRemove.length + modification.indexesToAdd.length + modification.indexesToRemove.length + modification.rulesToUpdate.length + modification.permissionsToUpdate.length;
|
|
3815
|
+
if (modification.permissionsToUpdate && modification.permissionsToUpdate.length > 0) {
|
|
3816
|
+
for (const permission of modification.permissionsToUpdate) {
|
|
3817
|
+
operationCount++;
|
|
3818
|
+
const varName = `collection_${collectionName}_revert_perm_${permission.ruleType}`;
|
|
3819
|
+
const isLast = operationCount === totalOperations;
|
|
3820
|
+
lines.push(generatePermissionUpdate(collectionName, permission.ruleType, permission.oldValue, varName, isLast));
|
|
3821
|
+
if (!isLast) lines.push("");
|
|
3822
|
+
}
|
|
3823
|
+
} else if (modification.rulesToUpdate.length > 0) {
|
|
3824
|
+
for (const rule of modification.rulesToUpdate) {
|
|
3825
|
+
operationCount++;
|
|
3826
|
+
const varName = `collection_${collectionName}_revert_rule_${rule.ruleType}`;
|
|
3827
|
+
const isLast = operationCount === totalOperations;
|
|
3828
|
+
lines.push(generateRuleUpdate(collectionName, rule.ruleType, rule.oldValue, varName, isLast));
|
|
3829
|
+
if (!isLast) lines.push("");
|
|
3830
|
+
}
|
|
3831
|
+
}
|
|
3832
|
+
for (let i = 0; i < modification.indexesToRemove.length; i++) {
|
|
3833
|
+
operationCount++;
|
|
3834
|
+
const index = modification.indexesToRemove[i];
|
|
3835
|
+
const varName = `collection_${collectionName}_restore_idx_${i}`;
|
|
3836
|
+
const isLast = operationCount === totalOperations;
|
|
3837
|
+
lines.push(generateIndexAddition(collectionName, index, varName, isLast));
|
|
3838
|
+
if (!isLast) lines.push("");
|
|
3839
|
+
}
|
|
3840
|
+
for (let i = 0; i < modification.indexesToAdd.length; i++) {
|
|
3841
|
+
operationCount++;
|
|
3842
|
+
const index = modification.indexesToAdd[i];
|
|
3843
|
+
const varName = `collection_${collectionName}_revert_idx_${i}`;
|
|
3844
|
+
const isLast = operationCount === totalOperations;
|
|
3845
|
+
lines.push(generateIndexRemoval(collectionName, index, varName, isLast));
|
|
3846
|
+
if (!isLast) lines.push("");
|
|
3847
|
+
}
|
|
3848
|
+
for (const field of modification.fieldsToRemove) {
|
|
3849
|
+
operationCount++;
|
|
3850
|
+
const varName = `collection_${collectionName}_restore_${field.name}`;
|
|
3851
|
+
const isLast = operationCount === totalOperations;
|
|
3852
|
+
lines.push(generateFieldAddition(collectionName, field, varName, isLast, collectionIdMap));
|
|
3853
|
+
if (!isLast) lines.push("");
|
|
3854
|
+
}
|
|
3855
|
+
for (const fieldMod of modification.fieldsToModify) {
|
|
3856
|
+
operationCount++;
|
|
3857
|
+
const reverseChanges = fieldMod.changes.map((change) => ({
|
|
3858
|
+
property: change.property,
|
|
3859
|
+
oldValue: change.newValue,
|
|
3860
|
+
newValue: change.oldValue
|
|
3861
|
+
}));
|
|
3862
|
+
const reverseMod = {
|
|
3863
|
+
fieldName: fieldMod.fieldName,
|
|
3864
|
+
currentDefinition: fieldMod.newDefinition,
|
|
3865
|
+
newDefinition: fieldMod.currentDefinition,
|
|
3866
|
+
changes: reverseChanges
|
|
3867
|
+
};
|
|
3868
|
+
const varName = `collection_${collectionName}_revert_${fieldMod.fieldName}`;
|
|
3869
|
+
const isLast = operationCount === totalOperations;
|
|
3870
|
+
lines.push(generateFieldModification(collectionName, reverseMod, varName, isLast));
|
|
3871
|
+
if (!isLast) lines.push("");
|
|
3872
|
+
}
|
|
3873
|
+
for (const field of modification.fieldsToAdd) {
|
|
3874
|
+
operationCount++;
|
|
3875
|
+
const varName = `collection_${collectionName}_revert_add_${field.name}`;
|
|
3876
|
+
const isLast = operationCount === totalOperations;
|
|
3877
|
+
lines.push(generateFieldDeletion(collectionName, field.name, varName, isLast));
|
|
3878
|
+
if (!isLast) lines.push("");
|
|
3879
|
+
}
|
|
3880
|
+
} else if (operation.type === "delete") {
|
|
3881
|
+
const collection = operation.collection;
|
|
3882
|
+
if (typeof collection !== "string") {
|
|
3883
|
+
const varName = `collection_${collection.name}`;
|
|
3884
|
+
lines.push(generateCollectionCreation(collection, varName, true, collectionIdMap));
|
|
3885
|
+
}
|
|
3886
|
+
}
|
|
3887
|
+
return lines.join("\n");
|
|
3888
|
+
}
|
|
3578
3889
|
function generateUpMigration(diff) {
|
|
3579
3890
|
const lines = [];
|
|
3580
3891
|
lines.push(` // UP MIGRATION`);
|
|
3581
3892
|
lines.push(``);
|
|
3893
|
+
const collectionIdMap = /* @__PURE__ */ new Map();
|
|
3894
|
+
for (const collection of diff.collectionsToCreate) {
|
|
3895
|
+
if (collection.id) {
|
|
3896
|
+
collectionIdMap.set(collection.name, collection.id);
|
|
3897
|
+
}
|
|
3898
|
+
}
|
|
3582
3899
|
if (diff.collectionsToCreate.length > 0) {
|
|
3583
3900
|
lines.push(` // Create new collections`);
|
|
3584
3901
|
for (let i = 0; i < diff.collectionsToCreate.length; i++) {
|
|
3585
3902
|
const collection = diff.collectionsToCreate[i];
|
|
3586
3903
|
const varName = `collection_${collection.name}_create`;
|
|
3587
|
-
lines.push(generateCollectionCreation(collection, varName));
|
|
3904
|
+
lines.push(generateCollectionCreation(collection, varName, false, collectionIdMap));
|
|
3588
3905
|
lines.push(``);
|
|
3589
3906
|
}
|
|
3590
3907
|
}
|
|
@@ -3596,7 +3913,7 @@ function generateUpMigration(diff) {
|
|
|
3596
3913
|
lines.push(` // Add fields to ${collectionName}`);
|
|
3597
3914
|
for (const field of modification.fieldsToAdd) {
|
|
3598
3915
|
const varName = `collection_${collectionName}_add_${field.name}`;
|
|
3599
|
-
lines.push(generateFieldAddition(collectionName, field, varName));
|
|
3916
|
+
lines.push(generateFieldAddition(collectionName, field, varName, false, collectionIdMap));
|
|
3600
3917
|
lines.push(``);
|
|
3601
3918
|
}
|
|
3602
3919
|
}
|
|
@@ -3687,12 +4004,23 @@ function generateDownMigration(diff) {
|
|
|
3687
4004
|
const lines = [];
|
|
3688
4005
|
lines.push(` // DOWN MIGRATION (ROLLBACK)`);
|
|
3689
4006
|
lines.push(``);
|
|
4007
|
+
const collectionIdMap = /* @__PURE__ */ new Map();
|
|
4008
|
+
for (const collection of diff.collectionsToCreate) {
|
|
4009
|
+
if (collection.id) {
|
|
4010
|
+
collectionIdMap.set(collection.name, collection.id);
|
|
4011
|
+
}
|
|
4012
|
+
}
|
|
4013
|
+
for (const collection of diff.collectionsToDelete) {
|
|
4014
|
+
if (collection.id) {
|
|
4015
|
+
collectionIdMap.set(collection.name, collection.id);
|
|
4016
|
+
}
|
|
4017
|
+
}
|
|
3690
4018
|
if (diff.collectionsToDelete.length > 0) {
|
|
3691
4019
|
lines.push(` // Recreate deleted collections`);
|
|
3692
4020
|
for (let i = 0; i < diff.collectionsToDelete.length; i++) {
|
|
3693
4021
|
const collection = diff.collectionsToDelete[i];
|
|
3694
4022
|
const varName = `collection_${collection.name}_recreate`;
|
|
3695
|
-
lines.push(generateCollectionCreation(collection, varName));
|
|
4023
|
+
lines.push(generateCollectionCreation(collection, varName, false, collectionIdMap));
|
|
3696
4024
|
lines.push(``);
|
|
3697
4025
|
}
|
|
3698
4026
|
}
|
|
@@ -3737,7 +4065,7 @@ function generateDownMigration(diff) {
|
|
|
3737
4065
|
lines.push(` // Restore fields to ${collectionName}`);
|
|
3738
4066
|
for (const field of modification.fieldsToRemove) {
|
|
3739
4067
|
const varName = `collection_${collectionName}_restore_${field.name}`;
|
|
3740
|
-
lines.push(generateFieldAddition(collectionName, field, varName));
|
|
4068
|
+
lines.push(generateFieldAddition(collectionName, field, varName, false, collectionIdMap));
|
|
3741
4069
|
lines.push(``);
|
|
3742
4070
|
}
|
|
3743
4071
|
}
|
|
@@ -3806,12 +4134,33 @@ function generate(diff, config) {
|
|
|
3806
4134
|
const normalizedConfig = typeof config === "string" ? { migrationDir: config } : config;
|
|
3807
4135
|
try {
|
|
3808
4136
|
const migrationDir = resolveMigrationDir(normalizedConfig);
|
|
3809
|
-
const
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
const
|
|
3814
|
-
|
|
4137
|
+
const hasChanges2 = diff.collectionsToCreate.length > 0 || diff.collectionsToModify.length > 0 || diff.collectionsToDelete.length > 0;
|
|
4138
|
+
if (!hasChanges2) {
|
|
4139
|
+
return [];
|
|
4140
|
+
}
|
|
4141
|
+
const collectionIdMap = /* @__PURE__ */ new Map();
|
|
4142
|
+
for (const collection of diff.collectionsToCreate) {
|
|
4143
|
+
if (collection.id) {
|
|
4144
|
+
collectionIdMap.set(collection.name, collection.id);
|
|
4145
|
+
}
|
|
4146
|
+
}
|
|
4147
|
+
for (const collection of diff.collectionsToDelete) {
|
|
4148
|
+
if (collection.id) {
|
|
4149
|
+
collectionIdMap.set(collection.name, collection.id);
|
|
4150
|
+
}
|
|
4151
|
+
}
|
|
4152
|
+
const baseTimestamp = generateTimestamp(normalizedConfig);
|
|
4153
|
+
const operations = splitDiffByCollection(diff, baseTimestamp);
|
|
4154
|
+
const filePaths = [];
|
|
4155
|
+
for (const operation of operations) {
|
|
4156
|
+
const upCode = generateOperationUpMigration(operation, collectionIdMap);
|
|
4157
|
+
const downCode = generateOperationDownMigration(operation, collectionIdMap);
|
|
4158
|
+
const content = createMigrationFileStructure(upCode, downCode, normalizedConfig);
|
|
4159
|
+
const filename = generateCollectionMigrationFilename(operation);
|
|
4160
|
+
const filePath = writeMigrationFile(migrationDir, filename, content);
|
|
4161
|
+
filePaths.push(filePath);
|
|
4162
|
+
}
|
|
4163
|
+
return filePaths;
|
|
3815
4164
|
} catch (error) {
|
|
3816
4165
|
if (error instanceof MigrationGenerationError || error instanceof FileSystemError) {
|
|
3817
4166
|
throw error;
|
|
@@ -3829,7 +4178,8 @@ var MigrationGenerator = class {
|
|
|
3829
4178
|
this.config = mergeConfig4(config);
|
|
3830
4179
|
}
|
|
3831
4180
|
/**
|
|
3832
|
-
* Generates
|
|
4181
|
+
* Generates migration files from a schema diff
|
|
4182
|
+
* Returns array of file paths (one per collection operation)
|
|
3833
4183
|
*/
|
|
3834
4184
|
generate(diff) {
|
|
3835
4185
|
return generate(diff, this.config);
|