pocketbase-zod-schema 0.1.2 → 0.1.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 +15 -0
- package/README.md +329 -99
- package/dist/cli/index.cjs +577 -152
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +575 -150
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/migrate.cjs +595 -153
- package/dist/cli/migrate.cjs.map +1 -1
- package/dist/cli/migrate.js +592 -151
- package/dist/cli/migrate.js.map +1 -1
- package/dist/cli/utils/index.cjs +1 -1
- package/dist/cli/utils/index.cjs.map +1 -1
- package/dist/cli/utils/index.js +1 -1
- package/dist/cli/utils/index.js.map +1 -1
- package/dist/index.cjs +688 -231
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +685 -230
- package/dist/index.js.map +1 -1
- package/dist/migration/analyzer.cjs +101 -28
- package/dist/migration/analyzer.cjs.map +1 -1
- package/dist/migration/analyzer.js +101 -28
- package/dist/migration/analyzer.js.map +1 -1
- package/dist/migration/diff.cjs +21 -3
- package/dist/migration/diff.cjs.map +1 -1
- package/dist/migration/diff.js +21 -3
- package/dist/migration/diff.js.map +1 -1
- package/dist/migration/generator.cjs +60 -25
- package/dist/migration/generator.cjs.map +1 -1
- package/dist/migration/generator.d.cts +9 -5
- package/dist/migration/generator.d.ts +9 -5
- package/dist/migration/generator.js +60 -25
- package/dist/migration/generator.js.map +1 -1
- package/dist/migration/index.cjs +614 -171
- package/dist/migration/index.cjs.map +1 -1
- package/dist/migration/index.d.cts +1 -1
- package/dist/migration/index.d.ts +1 -1
- package/dist/migration/index.js +613 -171
- package/dist/migration/index.js.map +1 -1
- package/dist/migration/snapshot.cjs +432 -117
- package/dist/migration/snapshot.cjs.map +1 -1
- package/dist/migration/snapshot.d.cts +34 -12
- package/dist/migration/snapshot.d.ts +34 -12
- package/dist/migration/snapshot.js +430 -116
- package/dist/migration/snapshot.js.map +1 -1
- package/dist/migration/utils/index.cjs +19 -17
- package/dist/migration/utils/index.cjs.map +1 -1
- package/dist/migration/utils/index.d.cts +3 -1
- package/dist/migration/utils/index.d.ts +3 -1
- package/dist/migration/utils/index.js +19 -17
- package/dist/migration/utils/index.js.map +1 -1
- package/dist/mutator.cjs +9 -11
- package/dist/mutator.cjs.map +1 -1
- package/dist/mutator.d.cts +5 -9
- package/dist/mutator.d.ts +5 -9
- package/dist/mutator.js +9 -11
- package/dist/mutator.js.map +1 -1
- package/dist/schema.cjs +54 -23
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +94 -12
- package/dist/schema.d.ts +94 -12
- package/dist/schema.js +54 -24
- package/dist/schema.js.map +1 -1
- package/dist/types.d.cts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/{user-jS1aYoeD.d.cts → user-_AM523hb.d.cts} +6 -6
- package/dist/{user-jS1aYoeD.d.ts → user-_AM523hb.d.ts} +6 -6
- package/package.json +2 -4
package/dist/migration/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var fs3 = require('fs');
|
|
4
4
|
var path = require('path');
|
|
5
5
|
var zod = require('zod');
|
|
6
6
|
|
|
@@ -22,10 +22,39 @@ function _interopNamespace(e) {
|
|
|
22
22
|
return Object.freeze(n);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
var
|
|
25
|
+
var fs3__namespace = /*#__PURE__*/_interopNamespace(fs3);
|
|
26
26
|
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
27
27
|
|
|
28
28
|
// src/migration/analyzer.ts
|
|
29
|
+
({
|
|
30
|
+
id: zod.z.string().describe("unique id"),
|
|
31
|
+
collectionId: zod.z.string().describe("collection id"),
|
|
32
|
+
collectionName: zod.z.string().describe("collection name"),
|
|
33
|
+
expand: zod.z.record(zod.z.any()).describe("expandable fields")
|
|
34
|
+
});
|
|
35
|
+
({
|
|
36
|
+
created: zod.z.string().describe("creation timestamp"),
|
|
37
|
+
updated: zod.z.string().describe("last update timestamp")
|
|
38
|
+
});
|
|
39
|
+
({
|
|
40
|
+
thumbnailURL: zod.z.string().optional(),
|
|
41
|
+
imageFiles: zod.z.array(zod.z.string())
|
|
42
|
+
});
|
|
43
|
+
({
|
|
44
|
+
imageFiles: zod.z.array(zod.z.instanceof(File))
|
|
45
|
+
});
|
|
46
|
+
var RELATION_METADATA_KEY = "__pocketbase_relation__";
|
|
47
|
+
function extractRelationMetadata(description) {
|
|
48
|
+
if (!description) return null;
|
|
49
|
+
try {
|
|
50
|
+
const parsed = JSON.parse(description);
|
|
51
|
+
if (parsed[RELATION_METADATA_KEY]) {
|
|
52
|
+
return parsed[RELATION_METADATA_KEY];
|
|
53
|
+
}
|
|
54
|
+
} catch {
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
29
58
|
|
|
30
59
|
// src/migration/errors.ts
|
|
31
60
|
var MigrationError = class _MigrationError extends Error {
|
|
@@ -124,10 +153,10 @@ var FileSystemError = class _FileSystemError extends MigrationError {
|
|
|
124
153
|
operation;
|
|
125
154
|
code;
|
|
126
155
|
originalError;
|
|
127
|
-
constructor(message,
|
|
156
|
+
constructor(message, path5, operation, code, originalError) {
|
|
128
157
|
super(message);
|
|
129
158
|
this.name = "FileSystemError";
|
|
130
|
-
this.path =
|
|
159
|
+
this.path = path5;
|
|
131
160
|
this.operation = operation;
|
|
132
161
|
this.code = code;
|
|
133
162
|
this.originalError = originalError;
|
|
@@ -216,7 +245,7 @@ Suggestion: ${this.suggestion}`);
|
|
|
216
245
|
}
|
|
217
246
|
};
|
|
218
247
|
|
|
219
|
-
// src/
|
|
248
|
+
// src/utils/permission-templates.ts
|
|
220
249
|
var PermissionTemplates = {
|
|
221
250
|
/**
|
|
222
251
|
* Public access - anyone can perform all operations
|
|
@@ -896,26 +925,28 @@ function getMaxSelect(fieldName, zodType) {
|
|
|
896
925
|
return 1;
|
|
897
926
|
}
|
|
898
927
|
function getMinSelect(fieldName, zodType) {
|
|
899
|
-
if (
|
|
900
|
-
return
|
|
901
|
-
}
|
|
902
|
-
let unwrappedType = zodType;
|
|
903
|
-
if (zodType instanceof zod.z.ZodOptional) {
|
|
904
|
-
unwrappedType = zodType._def.innerType;
|
|
905
|
-
}
|
|
906
|
-
if (unwrappedType instanceof zod.z.ZodNullable) {
|
|
907
|
-
unwrappedType = unwrappedType._def.innerType;
|
|
908
|
-
}
|
|
909
|
-
if (unwrappedType instanceof zod.z.ZodDefault) {
|
|
910
|
-
unwrappedType = unwrappedType._def.innerType;
|
|
928
|
+
if (isSingleRelationField(fieldName, zodType)) {
|
|
929
|
+
return 0;
|
|
911
930
|
}
|
|
912
|
-
if (
|
|
913
|
-
|
|
914
|
-
if (
|
|
915
|
-
|
|
931
|
+
if (isMultipleRelationField(fieldName, zodType)) {
|
|
932
|
+
let unwrappedType = zodType;
|
|
933
|
+
if (zodType instanceof zod.z.ZodOptional) {
|
|
934
|
+
unwrappedType = zodType._def.innerType;
|
|
935
|
+
}
|
|
936
|
+
if (unwrappedType instanceof zod.z.ZodNullable) {
|
|
937
|
+
unwrappedType = unwrappedType._def.innerType;
|
|
938
|
+
}
|
|
939
|
+
if (unwrappedType instanceof zod.z.ZodDefault) {
|
|
940
|
+
unwrappedType = unwrappedType._def.innerType;
|
|
941
|
+
}
|
|
942
|
+
if (unwrappedType instanceof zod.z.ZodArray) {
|
|
943
|
+
const arrayDef = unwrappedType._def;
|
|
944
|
+
if (arrayDef.minLength) {
|
|
945
|
+
return arrayDef.minLength.value;
|
|
946
|
+
}
|
|
916
947
|
}
|
|
917
948
|
}
|
|
918
|
-
return
|
|
949
|
+
return 0;
|
|
919
950
|
}
|
|
920
951
|
var POCKETBASE_FIELD_TYPES = [
|
|
921
952
|
"text",
|
|
@@ -1348,10 +1379,10 @@ function discoverSchemaFiles(config) {
|
|
|
1348
1379
|
const mergedConfig = mergeConfig(normalizedConfig);
|
|
1349
1380
|
const schemaDir = resolveSchemaDir(normalizedConfig);
|
|
1350
1381
|
try {
|
|
1351
|
-
if (!
|
|
1382
|
+
if (!fs3__namespace.existsSync(schemaDir)) {
|
|
1352
1383
|
throw new FileSystemError(`Schema directory not found: ${schemaDir}`, schemaDir, "access", "ENOENT");
|
|
1353
1384
|
}
|
|
1354
|
-
const files =
|
|
1385
|
+
const files = fs3__namespace.readdirSync(schemaDir);
|
|
1355
1386
|
const schemaFiles = files.filter((file) => {
|
|
1356
1387
|
const hasValidExtension = mergedConfig.includeExtensions.some((ext) => file.endsWith(ext));
|
|
1357
1388
|
if (!hasValidExtension) return false;
|
|
@@ -1398,13 +1429,32 @@ async function importSchemaModule(filePath, config) {
|
|
|
1398
1429
|
if (config?.pathTransformer) {
|
|
1399
1430
|
importPath = config.pathTransformer(filePath);
|
|
1400
1431
|
}
|
|
1401
|
-
|
|
1402
|
-
|
|
1432
|
+
let resolvedPath = null;
|
|
1433
|
+
const jsPath = `${importPath}.js`;
|
|
1434
|
+
const tsPath = `${importPath}.ts`;
|
|
1435
|
+
if (fs3__namespace.existsSync(jsPath)) {
|
|
1436
|
+
resolvedPath = jsPath;
|
|
1437
|
+
} else if (fs3__namespace.existsSync(tsPath)) {
|
|
1438
|
+
resolvedPath = tsPath;
|
|
1439
|
+
} else {
|
|
1440
|
+
resolvedPath = jsPath;
|
|
1403
1441
|
}
|
|
1404
|
-
const fileUrl = new URL(`file://${path__namespace.resolve(
|
|
1442
|
+
const fileUrl = new URL(`file://${path__namespace.resolve(resolvedPath)}`);
|
|
1405
1443
|
const module = await import(fileUrl.href);
|
|
1406
1444
|
return module;
|
|
1407
1445
|
} catch (error) {
|
|
1446
|
+
const tsPath = `${filePath}.ts`;
|
|
1447
|
+
const isTypeScriptFile = fs3__namespace.existsSync(tsPath);
|
|
1448
|
+
if (isTypeScriptFile) {
|
|
1449
|
+
throw new SchemaParsingError(
|
|
1450
|
+
`Failed to import TypeScript schema file. Node.js cannot import TypeScript files directly.
|
|
1451
|
+
Please either:
|
|
1452
|
+
1. Compile your schema files to JavaScript first, or
|
|
1453
|
+
2. Use tsx to run the migration tool (e.g., "npx tsx package/dist/cli/migrate.js status" or "tsx package/dist/cli/migrate.js status")`,
|
|
1454
|
+
filePath,
|
|
1455
|
+
error
|
|
1456
|
+
);
|
|
1457
|
+
}
|
|
1408
1458
|
throw new SchemaParsingError(
|
|
1409
1459
|
`Failed to import schema module. Make sure the schema files are compiled to JavaScript.`,
|
|
1410
1460
|
filePath,
|
|
@@ -1467,7 +1517,17 @@ function buildFieldDefinition(fieldName, zodType) {
|
|
|
1467
1517
|
required,
|
|
1468
1518
|
options
|
|
1469
1519
|
};
|
|
1470
|
-
|
|
1520
|
+
const relationMetadata = extractRelationMetadata(zodType.description);
|
|
1521
|
+
if (relationMetadata) {
|
|
1522
|
+
fieldDef.type = "relation";
|
|
1523
|
+
fieldDef.relation = {
|
|
1524
|
+
collection: relationMetadata.collection,
|
|
1525
|
+
maxSelect: relationMetadata.maxSelect,
|
|
1526
|
+
minSelect: relationMetadata.minSelect,
|
|
1527
|
+
cascadeDelete: relationMetadata.cascadeDelete
|
|
1528
|
+
};
|
|
1529
|
+
fieldDef.options = void 0;
|
|
1530
|
+
} else if (isRelationField(fieldName, zodType)) {
|
|
1471
1531
|
fieldDef.type = "relation";
|
|
1472
1532
|
const targetCollection = resolveTargetCollection(fieldName);
|
|
1473
1533
|
const maxSelect = getMaxSelect(fieldName, zodType);
|
|
@@ -1479,6 +1539,13 @@ function buildFieldDefinition(fieldName, zodType) {
|
|
|
1479
1539
|
cascadeDelete: false
|
|
1480
1540
|
// Default to false, can be configured later
|
|
1481
1541
|
};
|
|
1542
|
+
if (fieldDef.options) {
|
|
1543
|
+
const { min, max, pattern, ...relationSafeOptions } = fieldDef.options;
|
|
1544
|
+
console.log("min", min);
|
|
1545
|
+
console.log("max", max);
|
|
1546
|
+
console.log("pattern", pattern);
|
|
1547
|
+
fieldDef.options = Object.keys(relationSafeOptions).length > 0 ? relationSafeOptions : void 0;
|
|
1548
|
+
}
|
|
1482
1549
|
}
|
|
1483
1550
|
return fieldDef;
|
|
1484
1551
|
}
|
|
@@ -1531,11 +1598,12 @@ function convertZodSchemaToCollectionSchema(collectionName, zodSchema) {
|
|
|
1531
1598
|
fields,
|
|
1532
1599
|
indexes,
|
|
1533
1600
|
rules: {
|
|
1534
|
-
listRule: null,
|
|
1535
|
-
viewRule: null,
|
|
1536
|
-
createRule: null,
|
|
1537
|
-
updateRule: null,
|
|
1538
|
-
deleteRule: null
|
|
1601
|
+
listRule: permissions?.listRule ?? null,
|
|
1602
|
+
viewRule: permissions?.viewRule ?? null,
|
|
1603
|
+
createRule: permissions?.createRule ?? null,
|
|
1604
|
+
updateRule: permissions?.updateRule ?? null,
|
|
1605
|
+
deleteRule: permissions?.deleteRule ?? null,
|
|
1606
|
+
manageRule: permissions?.manageRule ?? null
|
|
1539
1607
|
},
|
|
1540
1608
|
permissions
|
|
1541
1609
|
};
|
|
@@ -1559,7 +1627,12 @@ async function buildSchemaDefinition(config) {
|
|
|
1559
1627
|
if (normalizedConfig.pathTransformer) {
|
|
1560
1628
|
importPath = normalizedConfig.pathTransformer(filePath);
|
|
1561
1629
|
} else if (mergedConfig.useCompiledFiles) {
|
|
1562
|
-
|
|
1630
|
+
const distPath = filePath.replace(/\/src\//, "/dist/");
|
|
1631
|
+
if (fs3__namespace.existsSync(`${distPath}.js`) || fs3__namespace.existsSync(`${distPath}.mjs`)) {
|
|
1632
|
+
importPath = distPath;
|
|
1633
|
+
} else {
|
|
1634
|
+
importPath = filePath;
|
|
1635
|
+
}
|
|
1563
1636
|
}
|
|
1564
1637
|
const module = await importSchemaModule(importPath, normalizedConfig);
|
|
1565
1638
|
const schemas = extractSchemaDefinitions(module, mergedConfig.schemaPatterns);
|
|
@@ -1611,7 +1684,359 @@ var SchemaAnalyzer = class {
|
|
|
1611
1684
|
return convertZodSchemaToCollectionSchema(name, schema);
|
|
1612
1685
|
}
|
|
1613
1686
|
};
|
|
1687
|
+
|
|
1688
|
+
// src/migration/pocketbase-converter.ts
|
|
1614
1689
|
var SNAPSHOT_VERSION = "1.0.0";
|
|
1690
|
+
function resolveCollectionIdToName(collectionId) {
|
|
1691
|
+
if (collectionId === "_pb_users_auth_") {
|
|
1692
|
+
return "Users";
|
|
1693
|
+
}
|
|
1694
|
+
const nameMatch = collectionId.match(/app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\)/);
|
|
1695
|
+
if (nameMatch) {
|
|
1696
|
+
return nameMatch[1];
|
|
1697
|
+
}
|
|
1698
|
+
return collectionId;
|
|
1699
|
+
}
|
|
1700
|
+
function convertPocketBaseCollection(pbCollection) {
|
|
1701
|
+
const fields = [];
|
|
1702
|
+
const systemFieldNames = ["id", "created", "updated", "collectionId", "collectionName", "expand"];
|
|
1703
|
+
const authSystemFieldNames = ["email", "emailVisibility", "verified", "password", "tokenKey"];
|
|
1704
|
+
if (pbCollection.fields && Array.isArray(pbCollection.fields)) {
|
|
1705
|
+
for (const pbField of pbCollection.fields) {
|
|
1706
|
+
if (pbField.system || systemFieldNames.includes(pbField.name)) {
|
|
1707
|
+
continue;
|
|
1708
|
+
}
|
|
1709
|
+
if (pbCollection.type === "auth" && authSystemFieldNames.includes(pbField.name)) {
|
|
1710
|
+
continue;
|
|
1711
|
+
}
|
|
1712
|
+
const field = {
|
|
1713
|
+
name: pbField.name,
|
|
1714
|
+
type: pbField.type,
|
|
1715
|
+
required: pbField.required || false
|
|
1716
|
+
};
|
|
1717
|
+
field.options = pbField.options ? { ...pbField.options } : {};
|
|
1718
|
+
if (pbField.type === "select") {
|
|
1719
|
+
if (pbField.values && Array.isArray(pbField.values)) {
|
|
1720
|
+
field.options.values = pbField.values;
|
|
1721
|
+
} else if (pbField.options?.values && Array.isArray(pbField.options.values)) {
|
|
1722
|
+
field.options.values = pbField.options.values;
|
|
1723
|
+
}
|
|
1724
|
+
}
|
|
1725
|
+
if (pbField.type === "relation") {
|
|
1726
|
+
const collectionId = pbField.collectionId || pbField.options?.collectionId || "";
|
|
1727
|
+
const collectionName = resolveCollectionIdToName(collectionId);
|
|
1728
|
+
field.relation = {
|
|
1729
|
+
collection: collectionName,
|
|
1730
|
+
cascadeDelete: pbField.cascadeDelete ?? pbField.options?.cascadeDelete ?? false,
|
|
1731
|
+
maxSelect: pbField.maxSelect ?? pbField.options?.maxSelect,
|
|
1732
|
+
minSelect: pbField.minSelect ?? pbField.options?.minSelect
|
|
1733
|
+
};
|
|
1734
|
+
}
|
|
1735
|
+
const hasOnlyValues = Object.keys(field.options).length === 1 && field.options.values !== void 0;
|
|
1736
|
+
if (Object.keys(field.options).length === 0) {
|
|
1737
|
+
delete field.options;
|
|
1738
|
+
} else if (pbField.type === "select" && hasOnlyValues) ;
|
|
1739
|
+
fields.push(field);
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
const schema = {
|
|
1743
|
+
name: pbCollection.name,
|
|
1744
|
+
type: pbCollection.type || "base",
|
|
1745
|
+
fields
|
|
1746
|
+
};
|
|
1747
|
+
if (pbCollection.indexes && Array.isArray(pbCollection.indexes)) {
|
|
1748
|
+
schema.indexes = pbCollection.indexes;
|
|
1749
|
+
}
|
|
1750
|
+
const rules = {};
|
|
1751
|
+
if (pbCollection.listRule !== void 0) rules.listRule = pbCollection.listRule;
|
|
1752
|
+
if (pbCollection.viewRule !== void 0) rules.viewRule = pbCollection.viewRule;
|
|
1753
|
+
if (pbCollection.createRule !== void 0) rules.createRule = pbCollection.createRule;
|
|
1754
|
+
if (pbCollection.updateRule !== void 0) rules.updateRule = pbCollection.updateRule;
|
|
1755
|
+
if (pbCollection.deleteRule !== void 0) rules.deleteRule = pbCollection.deleteRule;
|
|
1756
|
+
if (pbCollection.manageRule !== void 0) rules.manageRule = pbCollection.manageRule;
|
|
1757
|
+
if (Object.keys(rules).length > 0) {
|
|
1758
|
+
schema.rules = rules;
|
|
1759
|
+
schema.permissions = { ...rules };
|
|
1760
|
+
}
|
|
1761
|
+
return schema;
|
|
1762
|
+
}
|
|
1763
|
+
function convertPocketBaseMigration(migrationContent) {
|
|
1764
|
+
try {
|
|
1765
|
+
const snapshotMatch = migrationContent.match(/const\s+snapshot\s*=\s*(\[[\s\S]*?\]);/);
|
|
1766
|
+
if (!snapshotMatch) {
|
|
1767
|
+
throw new Error("Could not find snapshot array in migration file");
|
|
1768
|
+
}
|
|
1769
|
+
const snapshotArrayStr = snapshotMatch[1];
|
|
1770
|
+
let snapshotArray;
|
|
1771
|
+
try {
|
|
1772
|
+
snapshotArray = new Function(`return ${snapshotArrayStr}`)();
|
|
1773
|
+
} catch (parseError) {
|
|
1774
|
+
throw new Error(`Failed to parse snapshot array: ${parseError}`);
|
|
1775
|
+
}
|
|
1776
|
+
if (!Array.isArray(snapshotArray)) {
|
|
1777
|
+
throw new Error("Snapshot is not an array");
|
|
1778
|
+
}
|
|
1779
|
+
const collections = /* @__PURE__ */ new Map();
|
|
1780
|
+
for (const pbCollection of snapshotArray) {
|
|
1781
|
+
if (!pbCollection.name) {
|
|
1782
|
+
console.warn("Skipping collection without name");
|
|
1783
|
+
continue;
|
|
1784
|
+
}
|
|
1785
|
+
const schema = convertPocketBaseCollection(pbCollection);
|
|
1786
|
+
collections.set(pbCollection.name, schema);
|
|
1787
|
+
}
|
|
1788
|
+
return {
|
|
1789
|
+
version: SNAPSHOT_VERSION,
|
|
1790
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1791
|
+
collections
|
|
1792
|
+
};
|
|
1793
|
+
} catch (error) {
|
|
1794
|
+
throw new SnapshotError(
|
|
1795
|
+
`Failed to convert PocketBase migration: ${error instanceof Error ? error.message : String(error)}`,
|
|
1796
|
+
void 0,
|
|
1797
|
+
"parse",
|
|
1798
|
+
error instanceof Error ? error : void 0
|
|
1799
|
+
);
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
// src/migration/migration-parser.ts
|
|
1804
|
+
function extractTimestampFromFilename(filename) {
|
|
1805
|
+
const match = filename.match(/^(\d+)_/);
|
|
1806
|
+
if (match) {
|
|
1807
|
+
return parseInt(match[1], 10);
|
|
1808
|
+
}
|
|
1809
|
+
return null;
|
|
1810
|
+
}
|
|
1811
|
+
function findMigrationsAfterSnapshot(migrationsPath, snapshotTimestamp) {
|
|
1812
|
+
try {
|
|
1813
|
+
if (!fs3__namespace.existsSync(migrationsPath)) {
|
|
1814
|
+
return [];
|
|
1815
|
+
}
|
|
1816
|
+
const files = fs3__namespace.readdirSync(migrationsPath);
|
|
1817
|
+
const migrationFiles = [];
|
|
1818
|
+
for (const file of files) {
|
|
1819
|
+
if (file.endsWith("_collections_snapshot.js") || file.endsWith("_snapshot.js")) {
|
|
1820
|
+
continue;
|
|
1821
|
+
}
|
|
1822
|
+
if (!file.endsWith(".js")) {
|
|
1823
|
+
continue;
|
|
1824
|
+
}
|
|
1825
|
+
const timestamp = extractTimestampFromFilename(file);
|
|
1826
|
+
if (timestamp && timestamp > snapshotTimestamp) {
|
|
1827
|
+
migrationFiles.push({
|
|
1828
|
+
path: path__namespace.join(migrationsPath, file),
|
|
1829
|
+
timestamp
|
|
1830
|
+
});
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
migrationFiles.sort((a, b) => a.timestamp - b.timestamp);
|
|
1834
|
+
return migrationFiles.map((f) => f.path);
|
|
1835
|
+
} catch (error) {
|
|
1836
|
+
console.warn(`Error finding migrations after snapshot: ${error}`);
|
|
1837
|
+
return [];
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1840
|
+
function parseMigrationOperationsFromContent(content) {
|
|
1841
|
+
const collectionsToCreate = [];
|
|
1842
|
+
const collectionsToDelete = [];
|
|
1843
|
+
try {
|
|
1844
|
+
let searchIndex = 0;
|
|
1845
|
+
while (true) {
|
|
1846
|
+
const collectionStart = content.indexOf("new Collection(", searchIndex);
|
|
1847
|
+
if (collectionStart === -1) {
|
|
1848
|
+
break;
|
|
1849
|
+
}
|
|
1850
|
+
const openParen = collectionStart + "new Collection(".length;
|
|
1851
|
+
let braceCount = 0;
|
|
1852
|
+
let parenCount = 1;
|
|
1853
|
+
let inString = false;
|
|
1854
|
+
let stringChar = null;
|
|
1855
|
+
let i = openParen;
|
|
1856
|
+
while (i < content.length && /\s/.test(content[i])) {
|
|
1857
|
+
i++;
|
|
1858
|
+
}
|
|
1859
|
+
if (content[i] !== "{") {
|
|
1860
|
+
searchIndex = i + 1;
|
|
1861
|
+
continue;
|
|
1862
|
+
}
|
|
1863
|
+
const objectStart = i;
|
|
1864
|
+
braceCount = 1;
|
|
1865
|
+
i++;
|
|
1866
|
+
while (i < content.length && (braceCount > 0 || parenCount > 0)) {
|
|
1867
|
+
const char = content[i];
|
|
1868
|
+
const prevChar = i > 0 ? content[i - 1] : "";
|
|
1869
|
+
if (!inString && (char === '"' || char === "'")) {
|
|
1870
|
+
inString = true;
|
|
1871
|
+
stringChar = char;
|
|
1872
|
+
} else if (inString && char === stringChar && prevChar !== "\\") {
|
|
1873
|
+
inString = false;
|
|
1874
|
+
stringChar = null;
|
|
1875
|
+
}
|
|
1876
|
+
if (!inString) {
|
|
1877
|
+
if (char === "{") braceCount++;
|
|
1878
|
+
if (char === "}") braceCount--;
|
|
1879
|
+
if (char === "(") parenCount++;
|
|
1880
|
+
if (char === ")") parenCount--;
|
|
1881
|
+
}
|
|
1882
|
+
i++;
|
|
1883
|
+
}
|
|
1884
|
+
if (braceCount === 0 && parenCount === 0) {
|
|
1885
|
+
const objectContent = content.substring(objectStart, i - 1);
|
|
1886
|
+
try {
|
|
1887
|
+
const collectionObj = new Function(`return ${objectContent}`)();
|
|
1888
|
+
if (collectionObj && collectionObj.name) {
|
|
1889
|
+
const schema = convertPocketBaseCollection(collectionObj);
|
|
1890
|
+
collectionsToCreate.push(schema);
|
|
1891
|
+
}
|
|
1892
|
+
} catch (error) {
|
|
1893
|
+
console.warn(`Failed to parse collection definition: ${error}`);
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
searchIndex = i;
|
|
1897
|
+
}
|
|
1898
|
+
const deleteMatches = content.matchAll(
|
|
1899
|
+
/app\.delete\s*\(\s*(?:collection_\w+|app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\))\s*\)/g
|
|
1900
|
+
);
|
|
1901
|
+
for (const match of deleteMatches) {
|
|
1902
|
+
if (match[1]) {
|
|
1903
|
+
collectionsToDelete.push(match[1]);
|
|
1904
|
+
} else {
|
|
1905
|
+
const varNameMatch = match[0].match(/collection_(\w+)/);
|
|
1906
|
+
if (varNameMatch) {
|
|
1907
|
+
const varName = `collection_${varNameMatch[1]}`;
|
|
1908
|
+
const deleteIndex = content.indexOf(match[0]);
|
|
1909
|
+
const beforeDelete = content.substring(0, deleteIndex);
|
|
1910
|
+
const varDefMatch = beforeDelete.match(
|
|
1911
|
+
new RegExp(`const\\s+${varName}\\s*=\\s*new\\s+Collection\\(\\s*(\\{[\\s\\S]*?\\})\\s*\\)`, "g")
|
|
1912
|
+
);
|
|
1913
|
+
if (varDefMatch && varDefMatch.length > 0) {
|
|
1914
|
+
const collectionDefMatch = beforeDelete.match(
|
|
1915
|
+
new RegExp(`const\\s+${varName}\\s*=\\s*new\\s+Collection\\(\\s*(\\{[\\s\\S]*?\\})\\s*\\)`)
|
|
1916
|
+
);
|
|
1917
|
+
if (collectionDefMatch) {
|
|
1918
|
+
try {
|
|
1919
|
+
const collectionDefStr = collectionDefMatch[1];
|
|
1920
|
+
const collectionObj = new Function(`return ${collectionDefStr}`)();
|
|
1921
|
+
if (collectionObj && collectionObj.name) {
|
|
1922
|
+
collectionsToDelete.push(collectionObj.name);
|
|
1923
|
+
}
|
|
1924
|
+
} catch {
|
|
1925
|
+
}
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
const findAndDeleteMatches = content.matchAll(
|
|
1932
|
+
/app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\)[\s\S]*?app\.delete/g
|
|
1933
|
+
);
|
|
1934
|
+
for (const match of findAndDeleteMatches) {
|
|
1935
|
+
collectionsToDelete.push(match[1]);
|
|
1936
|
+
}
|
|
1937
|
+
} catch (error) {
|
|
1938
|
+
console.warn(`Failed to parse migration operations from content: ${error}`);
|
|
1939
|
+
}
|
|
1940
|
+
return { collectionsToCreate, collectionsToDelete };
|
|
1941
|
+
}
|
|
1942
|
+
function parseMigrationOperations(migrationContent) {
|
|
1943
|
+
try {
|
|
1944
|
+
const migrateMatch = migrationContent.match(/migrate\s*\(\s*/);
|
|
1945
|
+
if (!migrateMatch) {
|
|
1946
|
+
return parseMigrationOperationsFromContent(migrationContent);
|
|
1947
|
+
}
|
|
1948
|
+
const startIndex = migrateMatch.index + migrateMatch[0].length;
|
|
1949
|
+
let i = startIndex;
|
|
1950
|
+
let parenCount = 0;
|
|
1951
|
+
let foundFirstParen = false;
|
|
1952
|
+
while (i < migrationContent.length) {
|
|
1953
|
+
const char = migrationContent[i];
|
|
1954
|
+
if (char === "(") {
|
|
1955
|
+
parenCount++;
|
|
1956
|
+
foundFirstParen = true;
|
|
1957
|
+
i++;
|
|
1958
|
+
break;
|
|
1959
|
+
}
|
|
1960
|
+
i++;
|
|
1961
|
+
}
|
|
1962
|
+
if (!foundFirstParen) {
|
|
1963
|
+
return parseMigrationOperationsFromContent(migrationContent);
|
|
1964
|
+
}
|
|
1965
|
+
let inString = false;
|
|
1966
|
+
let stringChar = null;
|
|
1967
|
+
let foundBrace = false;
|
|
1968
|
+
let braceStart = -1;
|
|
1969
|
+
while (i < migrationContent.length && !foundBrace) {
|
|
1970
|
+
const char = migrationContent[i];
|
|
1971
|
+
const prevChar = i > 0 ? migrationContent[i - 1] : "";
|
|
1972
|
+
if (!inString && (char === '"' || char === "'")) {
|
|
1973
|
+
inString = true;
|
|
1974
|
+
stringChar = char;
|
|
1975
|
+
} else if (inString && char === stringChar && prevChar !== "\\") {
|
|
1976
|
+
inString = false;
|
|
1977
|
+
stringChar = null;
|
|
1978
|
+
}
|
|
1979
|
+
if (!inString) {
|
|
1980
|
+
if (char === "(") parenCount++;
|
|
1981
|
+
if (char === ")") {
|
|
1982
|
+
parenCount--;
|
|
1983
|
+
if (parenCount === 0) {
|
|
1984
|
+
i++;
|
|
1985
|
+
while (i < migrationContent.length && /\s/.test(migrationContent[i])) {
|
|
1986
|
+
i++;
|
|
1987
|
+
}
|
|
1988
|
+
if (i < migrationContent.length - 1 && migrationContent[i] === "=" && migrationContent[i + 1] === ">") {
|
|
1989
|
+
i += 2;
|
|
1990
|
+
while (i < migrationContent.length && /\s/.test(migrationContent[i])) {
|
|
1991
|
+
i++;
|
|
1992
|
+
}
|
|
1993
|
+
if (i < migrationContent.length && migrationContent[i] === "{") {
|
|
1994
|
+
foundBrace = true;
|
|
1995
|
+
braceStart = i + 1;
|
|
1996
|
+
break;
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
i++;
|
|
2003
|
+
}
|
|
2004
|
+
if (!foundBrace || braceStart === -1) {
|
|
2005
|
+
return parseMigrationOperationsFromContent(migrationContent);
|
|
2006
|
+
}
|
|
2007
|
+
let braceCount = 1;
|
|
2008
|
+
i = braceStart;
|
|
2009
|
+
inString = false;
|
|
2010
|
+
stringChar = null;
|
|
2011
|
+
while (i < migrationContent.length && braceCount > 0) {
|
|
2012
|
+
const char = migrationContent[i];
|
|
2013
|
+
const prevChar = i > 0 ? migrationContent[i - 1] : "";
|
|
2014
|
+
if (!inString && (char === '"' || char === "'")) {
|
|
2015
|
+
inString = true;
|
|
2016
|
+
stringChar = char;
|
|
2017
|
+
} else if (inString && char === stringChar && prevChar !== "\\") {
|
|
2018
|
+
inString = false;
|
|
2019
|
+
stringChar = null;
|
|
2020
|
+
}
|
|
2021
|
+
if (!inString) {
|
|
2022
|
+
if (char === "{") braceCount++;
|
|
2023
|
+
if (char === "}") braceCount--;
|
|
2024
|
+
}
|
|
2025
|
+
i++;
|
|
2026
|
+
}
|
|
2027
|
+
if (braceCount === 0) {
|
|
2028
|
+
const upMigrationContent = migrationContent.substring(braceStart, i - 1);
|
|
2029
|
+
return parseMigrationOperationsFromContent(upMigrationContent);
|
|
2030
|
+
}
|
|
2031
|
+
return parseMigrationOperationsFromContent(migrationContent);
|
|
2032
|
+
} catch (error) {
|
|
2033
|
+
console.warn(`Failed to parse migration operations: ${error}`);
|
|
2034
|
+
return { collectionsToCreate: [], collectionsToDelete: [] };
|
|
2035
|
+
}
|
|
2036
|
+
}
|
|
2037
|
+
|
|
2038
|
+
// src/migration/snapshot.ts
|
|
2039
|
+
var SNAPSHOT_VERSION2 = "1.0.0";
|
|
1615
2040
|
var DEFAULT_SNAPSHOT_FILENAME = ".migration-snapshot.json";
|
|
1616
2041
|
var SNAPSHOT_MIGRATIONS = [
|
|
1617
2042
|
// Add migrations here as the format evolves
|
|
@@ -1626,7 +2051,7 @@ var DEFAULT_CONFIG2 = {
|
|
|
1626
2051
|
snapshotPath: DEFAULT_SNAPSHOT_FILENAME,
|
|
1627
2052
|
workspaceRoot: process.cwd(),
|
|
1628
2053
|
autoMigrate: true,
|
|
1629
|
-
version:
|
|
2054
|
+
version: SNAPSHOT_VERSION2
|
|
1630
2055
|
};
|
|
1631
2056
|
function mergeConfig2(config = {}) {
|
|
1632
2057
|
return {
|
|
@@ -1646,7 +2071,7 @@ function getSnapshotPath(config = {}) {
|
|
|
1646
2071
|
function snapshotExists(config = {}) {
|
|
1647
2072
|
try {
|
|
1648
2073
|
const snapshotPath = getSnapshotPath(config);
|
|
1649
|
-
return
|
|
2074
|
+
return fs3__namespace.existsSync(snapshotPath);
|
|
1650
2075
|
} catch {
|
|
1651
2076
|
return false;
|
|
1652
2077
|
}
|
|
@@ -1706,12 +2131,12 @@ function saveSnapshot(schema, config = {}) {
|
|
|
1706
2131
|
const snapshotPath = getSnapshotPath(config);
|
|
1707
2132
|
try {
|
|
1708
2133
|
const snapshotDir = path__namespace.dirname(snapshotPath);
|
|
1709
|
-
if (!
|
|
1710
|
-
|
|
2134
|
+
if (!fs3__namespace.existsSync(snapshotDir)) {
|
|
2135
|
+
fs3__namespace.mkdirSync(snapshotDir, { recursive: true });
|
|
1711
2136
|
}
|
|
1712
2137
|
const snapshotData = addSnapshotMetadata(schema, config);
|
|
1713
2138
|
const jsonContent = JSON.stringify(snapshotData, null, 2);
|
|
1714
|
-
|
|
2139
|
+
fs3__namespace.writeFileSync(snapshotPath, jsonContent, "utf-8");
|
|
1715
2140
|
} catch (error) {
|
|
1716
2141
|
handleFileSystemError(error, "write", snapshotPath);
|
|
1717
2142
|
}
|
|
@@ -1806,7 +2231,7 @@ function deserializeSnapshot(data) {
|
|
|
1806
2231
|
function loadSnapshot(config = {}) {
|
|
1807
2232
|
const snapshotPath = getSnapshotPath(config);
|
|
1808
2233
|
try {
|
|
1809
|
-
const jsonContent =
|
|
2234
|
+
const jsonContent = fs3__namespace.readFileSync(snapshotPath, "utf-8");
|
|
1810
2235
|
const data = parseAndValidateSnapshot(jsonContent, snapshotPath);
|
|
1811
2236
|
const migratedData = migrateSnapshotFormat(data, config);
|
|
1812
2237
|
return deserializeSnapshot(migratedData);
|
|
@@ -1841,10 +2266,10 @@ function mergeSnapshots(baseSnapshot, customSnapshot) {
|
|
|
1841
2266
|
}
|
|
1842
2267
|
function findLatestSnapshot(migrationsPath) {
|
|
1843
2268
|
try {
|
|
1844
|
-
if (!
|
|
2269
|
+
if (!fs3__namespace.existsSync(migrationsPath)) {
|
|
1845
2270
|
return null;
|
|
1846
2271
|
}
|
|
1847
|
-
const files =
|
|
2272
|
+
const files = fs3__namespace.readdirSync(migrationsPath);
|
|
1848
2273
|
const snapshotFiles = files.filter(
|
|
1849
2274
|
(file) => file.endsWith("_collections_snapshot.js") || file.endsWith("_snapshot.js")
|
|
1850
2275
|
);
|
|
@@ -1862,14 +2287,68 @@ function findLatestSnapshot(migrationsPath) {
|
|
|
1862
2287
|
return null;
|
|
1863
2288
|
}
|
|
1864
2289
|
}
|
|
2290
|
+
function applyMigrationOperations(snapshot, operations) {
|
|
2291
|
+
const updatedCollections = new Map(snapshot.collections);
|
|
2292
|
+
for (const collectionName of operations.collectionsToDelete) {
|
|
2293
|
+
updatedCollections.delete(collectionName);
|
|
2294
|
+
}
|
|
2295
|
+
for (const collection of operations.collectionsToCreate) {
|
|
2296
|
+
updatedCollections.set(collection.name, collection);
|
|
2297
|
+
}
|
|
2298
|
+
return {
|
|
2299
|
+
...snapshot,
|
|
2300
|
+
collections: updatedCollections
|
|
2301
|
+
};
|
|
2302
|
+
}
|
|
2303
|
+
function loadSnapshotWithMigrations(config = {}) {
|
|
2304
|
+
const migrationsPath = config.migrationsPath;
|
|
2305
|
+
if (!migrationsPath) {
|
|
2306
|
+
return null;
|
|
2307
|
+
}
|
|
2308
|
+
if (fs3__namespace.existsSync(migrationsPath) && fs3__namespace.statSync(migrationsPath).isFile()) {
|
|
2309
|
+
try {
|
|
2310
|
+
const migrationContent = fs3__namespace.readFileSync(migrationsPath, "utf-8");
|
|
2311
|
+
return convertPocketBaseMigration(migrationContent);
|
|
2312
|
+
} catch (error) {
|
|
2313
|
+
console.warn(`Failed to load snapshot from ${migrationsPath}: ${error}`);
|
|
2314
|
+
return null;
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
const latestSnapshotPath = findLatestSnapshot(migrationsPath);
|
|
2318
|
+
if (!latestSnapshotPath) {
|
|
2319
|
+
return null;
|
|
2320
|
+
}
|
|
2321
|
+
try {
|
|
2322
|
+
const migrationContent = fs3__namespace.readFileSync(latestSnapshotPath, "utf-8");
|
|
2323
|
+
let snapshot = convertPocketBaseMigration(migrationContent);
|
|
2324
|
+
const snapshotFilename = path__namespace.basename(latestSnapshotPath);
|
|
2325
|
+
const snapshotTimestamp = extractTimestampFromFilename(snapshotFilename);
|
|
2326
|
+
if (snapshotTimestamp) {
|
|
2327
|
+
const migrationFiles = findMigrationsAfterSnapshot(migrationsPath, snapshotTimestamp);
|
|
2328
|
+
for (const migrationFile of migrationFiles) {
|
|
2329
|
+
try {
|
|
2330
|
+
const migrationContent2 = fs3__namespace.readFileSync(migrationFile, "utf-8");
|
|
2331
|
+
const operations = parseMigrationOperations(migrationContent2);
|
|
2332
|
+
snapshot = applyMigrationOperations(snapshot, operations);
|
|
2333
|
+
} catch (error) {
|
|
2334
|
+
console.warn(`Failed to apply migration ${migrationFile}: ${error}`);
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
return snapshot;
|
|
2339
|
+
} catch (error) {
|
|
2340
|
+
console.warn(`Failed to load snapshot from ${latestSnapshotPath}: ${error}`);
|
|
2341
|
+
return null;
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
1865
2344
|
function loadSnapshotIfExists(config = {}) {
|
|
1866
2345
|
const migrationsPath = config.migrationsPath;
|
|
1867
2346
|
if (!migrationsPath) {
|
|
1868
2347
|
return null;
|
|
1869
2348
|
}
|
|
1870
|
-
if (
|
|
2349
|
+
if (fs3__namespace.existsSync(migrationsPath) && fs3__namespace.statSync(migrationsPath).isFile()) {
|
|
1871
2350
|
try {
|
|
1872
|
-
const migrationContent =
|
|
2351
|
+
const migrationContent = fs3__namespace.readFileSync(migrationsPath, "utf-8");
|
|
1873
2352
|
return convertPocketBaseMigration(migrationContent);
|
|
1874
2353
|
} catch (error) {
|
|
1875
2354
|
console.warn(`Failed to load snapshot from ${migrationsPath}: ${error}`);
|
|
@@ -1879,7 +2358,7 @@ function loadSnapshotIfExists(config = {}) {
|
|
|
1879
2358
|
const latestSnapshotPath = findLatestSnapshot(migrationsPath);
|
|
1880
2359
|
if (latestSnapshotPath) {
|
|
1881
2360
|
try {
|
|
1882
|
-
const migrationContent =
|
|
2361
|
+
const migrationContent = fs3__namespace.readFileSync(latestSnapshotPath, "utf-8");
|
|
1883
2362
|
return convertPocketBaseMigration(migrationContent);
|
|
1884
2363
|
} catch (error) {
|
|
1885
2364
|
console.warn(`Failed to load snapshot from ${latestSnapshotPath}: ${error}`);
|
|
@@ -1888,99 +2367,9 @@ function loadSnapshotIfExists(config = {}) {
|
|
|
1888
2367
|
}
|
|
1889
2368
|
return null;
|
|
1890
2369
|
}
|
|
1891
|
-
function convertPocketBaseCollection(pbCollection) {
|
|
1892
|
-
const fields = [];
|
|
1893
|
-
const systemFieldNames = ["id", "created", "updated", "collectionId", "collectionName", "expand"];
|
|
1894
|
-
const authSystemFieldNames = ["email", "emailVisibility", "verified", "password", "tokenKey"];
|
|
1895
|
-
if (pbCollection.fields && Array.isArray(pbCollection.fields)) {
|
|
1896
|
-
for (const pbField of pbCollection.fields) {
|
|
1897
|
-
if (pbField.system || systemFieldNames.includes(pbField.name)) {
|
|
1898
|
-
continue;
|
|
1899
|
-
}
|
|
1900
|
-
if (pbCollection.type === "auth" && authSystemFieldNames.includes(pbField.name)) {
|
|
1901
|
-
continue;
|
|
1902
|
-
}
|
|
1903
|
-
const field = {
|
|
1904
|
-
name: pbField.name,
|
|
1905
|
-
type: pbField.type,
|
|
1906
|
-
required: pbField.required || false
|
|
1907
|
-
};
|
|
1908
|
-
if (pbField.options) {
|
|
1909
|
-
field.options = pbField.options;
|
|
1910
|
-
}
|
|
1911
|
-
if (pbField.type === "relation") {
|
|
1912
|
-
field.relation = {
|
|
1913
|
-
collection: pbField.options?.collectionId || "",
|
|
1914
|
-
cascadeDelete: pbField.options?.cascadeDelete || false,
|
|
1915
|
-
maxSelect: pbField.options?.maxSelect,
|
|
1916
|
-
minSelect: pbField.options?.minSelect
|
|
1917
|
-
};
|
|
1918
|
-
}
|
|
1919
|
-
fields.push(field);
|
|
1920
|
-
}
|
|
1921
|
-
}
|
|
1922
|
-
const schema = {
|
|
1923
|
-
name: pbCollection.name,
|
|
1924
|
-
type: pbCollection.type || "base",
|
|
1925
|
-
fields
|
|
1926
|
-
};
|
|
1927
|
-
if (pbCollection.indexes && Array.isArray(pbCollection.indexes)) {
|
|
1928
|
-
schema.indexes = pbCollection.indexes;
|
|
1929
|
-
}
|
|
1930
|
-
const rules = {};
|
|
1931
|
-
if (pbCollection.listRule !== void 0) rules.listRule = pbCollection.listRule;
|
|
1932
|
-
if (pbCollection.viewRule !== void 0) rules.viewRule = pbCollection.viewRule;
|
|
1933
|
-
if (pbCollection.createRule !== void 0) rules.createRule = pbCollection.createRule;
|
|
1934
|
-
if (pbCollection.updateRule !== void 0) rules.updateRule = pbCollection.updateRule;
|
|
1935
|
-
if (pbCollection.deleteRule !== void 0) rules.deleteRule = pbCollection.deleteRule;
|
|
1936
|
-
if (pbCollection.manageRule !== void 0) rules.manageRule = pbCollection.manageRule;
|
|
1937
|
-
if (Object.keys(rules).length > 0) {
|
|
1938
|
-
schema.rules = rules;
|
|
1939
|
-
}
|
|
1940
|
-
return schema;
|
|
1941
|
-
}
|
|
1942
|
-
function convertPocketBaseMigration(migrationContent) {
|
|
1943
|
-
try {
|
|
1944
|
-
const snapshotMatch = migrationContent.match(/const\s+snapshot\s*=\s*(\[[\s\S]*?\]);/);
|
|
1945
|
-
if (!snapshotMatch) {
|
|
1946
|
-
throw new Error("Could not find snapshot array in migration file");
|
|
1947
|
-
}
|
|
1948
|
-
const snapshotArrayStr = snapshotMatch[1];
|
|
1949
|
-
let snapshotArray;
|
|
1950
|
-
try {
|
|
1951
|
-
snapshotArray = new Function(`return ${snapshotArrayStr}`)();
|
|
1952
|
-
} catch (parseError) {
|
|
1953
|
-
throw new Error(`Failed to parse snapshot array: ${parseError}`);
|
|
1954
|
-
}
|
|
1955
|
-
if (!Array.isArray(snapshotArray)) {
|
|
1956
|
-
throw new Error("Snapshot is not an array");
|
|
1957
|
-
}
|
|
1958
|
-
const collections = /* @__PURE__ */ new Map();
|
|
1959
|
-
for (const pbCollection of snapshotArray) {
|
|
1960
|
-
if (!pbCollection.name) {
|
|
1961
|
-
console.warn("Skipping collection without name");
|
|
1962
|
-
continue;
|
|
1963
|
-
}
|
|
1964
|
-
const schema = convertPocketBaseCollection(pbCollection);
|
|
1965
|
-
collections.set(pbCollection.name, schema);
|
|
1966
|
-
}
|
|
1967
|
-
return {
|
|
1968
|
-
version: SNAPSHOT_VERSION,
|
|
1969
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1970
|
-
collections
|
|
1971
|
-
};
|
|
1972
|
-
} catch (error) {
|
|
1973
|
-
throw new SnapshotError(
|
|
1974
|
-
`Failed to convert PocketBase migration: ${error instanceof Error ? error.message : String(error)}`,
|
|
1975
|
-
void 0,
|
|
1976
|
-
"parse",
|
|
1977
|
-
error instanceof Error ? error : void 0
|
|
1978
|
-
);
|
|
1979
|
-
}
|
|
1980
|
-
}
|
|
1981
2370
|
function loadBaseMigration(migrationPath) {
|
|
1982
2371
|
try {
|
|
1983
|
-
if (!
|
|
2372
|
+
if (!fs3__namespace.existsSync(migrationPath)) {
|
|
1984
2373
|
throw new SnapshotError(
|
|
1985
2374
|
`Base migration file not found: ${migrationPath}
|
|
1986
2375
|
|
|
@@ -1991,7 +2380,7 @@ If the file exists in a different location, update the configuration.`,
|
|
|
1991
2380
|
"read"
|
|
1992
2381
|
);
|
|
1993
2382
|
}
|
|
1994
|
-
const migrationContent =
|
|
2383
|
+
const migrationContent = fs3__namespace.readFileSync(migrationPath, "utf-8");
|
|
1995
2384
|
const snapshot = convertPocketBaseMigration(migrationContent);
|
|
1996
2385
|
return snapshot;
|
|
1997
2386
|
} catch (error) {
|
|
@@ -2027,14 +2416,14 @@ Please ensure PocketBase is properly set up by running 'yarn setup'.`,
|
|
|
2027
2416
|
}
|
|
2028
2417
|
}
|
|
2029
2418
|
function getSnapshotVersion() {
|
|
2030
|
-
return
|
|
2419
|
+
return SNAPSHOT_VERSION2;
|
|
2031
2420
|
}
|
|
2032
2421
|
function validateSnapshot(snapshot) {
|
|
2033
2422
|
const issues = [];
|
|
2034
2423
|
if (!snapshot.version) {
|
|
2035
2424
|
issues.push("Missing version field");
|
|
2036
|
-
} else if (compareVersions(snapshot.version,
|
|
2037
|
-
issues.push(`Snapshot version ${snapshot.version} is newer than supported version ${
|
|
2425
|
+
} else if (compareVersions(snapshot.version, SNAPSHOT_VERSION2) > 0) {
|
|
2426
|
+
issues.push(`Snapshot version ${snapshot.version} is newer than supported version ${SNAPSHOT_VERSION2}`);
|
|
2038
2427
|
}
|
|
2039
2428
|
if (!snapshot.timestamp) {
|
|
2040
2429
|
issues.push("Missing timestamp field");
|
|
@@ -2253,6 +2642,9 @@ function compareFieldOptions(currentField, previousField) {
|
|
|
2253
2642
|
for (const key of allKeys) {
|
|
2254
2643
|
const currentValue = currentOptions[key];
|
|
2255
2644
|
const previousValue = previousOptions[key];
|
|
2645
|
+
if (currentValue === void 0 && previousValue === void 0) {
|
|
2646
|
+
continue;
|
|
2647
|
+
}
|
|
2256
2648
|
if (!areValuesEqual(currentValue, previousValue)) {
|
|
2257
2649
|
changes.push({
|
|
2258
2650
|
property: `options.${key}`,
|
|
@@ -2273,11 +2665,26 @@ function compareRelationConfigurations(currentField, previousField) {
|
|
|
2273
2665
|
if (!currentRelation || !previousRelation) {
|
|
2274
2666
|
return changes;
|
|
2275
2667
|
}
|
|
2276
|
-
|
|
2668
|
+
const normalizeCollection = (collection) => {
|
|
2669
|
+
if (!collection) return collection;
|
|
2670
|
+
if (collection === "_pb_users_auth_") {
|
|
2671
|
+
return "Users";
|
|
2672
|
+
}
|
|
2673
|
+
const nameMatch = collection.match(/app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\)/);
|
|
2674
|
+
if (nameMatch) {
|
|
2675
|
+
return nameMatch[1];
|
|
2676
|
+
}
|
|
2677
|
+
return collection;
|
|
2678
|
+
};
|
|
2679
|
+
const normalizedCurrent = normalizeCollection(currentRelation.collection);
|
|
2680
|
+
const normalizedPrevious = normalizeCollection(previousRelation.collection);
|
|
2681
|
+
if (normalizedCurrent !== normalizedPrevious) {
|
|
2277
2682
|
changes.push({
|
|
2278
2683
|
property: "relation.collection",
|
|
2279
|
-
oldValue:
|
|
2280
|
-
|
|
2684
|
+
oldValue: normalizedPrevious,
|
|
2685
|
+
// Use normalized value for clarity
|
|
2686
|
+
newValue: normalizedCurrent
|
|
2687
|
+
// Use normalized value for clarity
|
|
2281
2688
|
});
|
|
2282
2689
|
}
|
|
2283
2690
|
if (currentRelation.cascadeDelete !== previousRelation.cascadeDelete) {
|
|
@@ -2631,10 +3038,8 @@ var DiffEngine = class {
|
|
|
2631
3038
|
var DEFAULT_TEMPLATE = `/// <reference path="{{TYPES_PATH}}" />
|
|
2632
3039
|
migrate((app) => {
|
|
2633
3040
|
{{UP_CODE}}
|
|
2634
|
-
return true;
|
|
2635
3041
|
}, (app) => {
|
|
2636
3042
|
{{DOWN_CODE}}
|
|
2637
|
-
return true;
|
|
2638
3043
|
});
|
|
2639
3044
|
`;
|
|
2640
3045
|
var DEFAULT_CONFIG4 = {
|
|
@@ -2713,9 +3118,9 @@ function createMigrationFileStructure(upCode, downCode, config) {
|
|
|
2713
3118
|
}
|
|
2714
3119
|
function writeMigrationFile(migrationDir, filename, content) {
|
|
2715
3120
|
try {
|
|
2716
|
-
if (!
|
|
3121
|
+
if (!fs3__namespace.existsSync(migrationDir)) {
|
|
2717
3122
|
try {
|
|
2718
|
-
|
|
3123
|
+
fs3__namespace.mkdirSync(migrationDir, { recursive: true });
|
|
2719
3124
|
} catch (error) {
|
|
2720
3125
|
const fsError = error;
|
|
2721
3126
|
if (fsError.code === "EACCES" || fsError.code === "EPERM") {
|
|
@@ -2737,7 +3142,7 @@ function writeMigrationFile(migrationDir, filename, content) {
|
|
|
2737
3142
|
}
|
|
2738
3143
|
}
|
|
2739
3144
|
const filePath = path__namespace.join(migrationDir, filename);
|
|
2740
|
-
|
|
3145
|
+
fs3__namespace.writeFileSync(filePath, content, "utf-8");
|
|
2741
3146
|
return filePath;
|
|
2742
3147
|
} catch (error) {
|
|
2743
3148
|
if (error instanceof FileSystemError) {
|
|
@@ -2799,7 +3204,8 @@ function generateFieldDefinitionObject(field) {
|
|
|
2799
3204
|
}
|
|
2800
3205
|
}
|
|
2801
3206
|
if (field.relation) {
|
|
2802
|
-
const
|
|
3207
|
+
const isUsersCollection = field.relation.collection.toLowerCase() === "users";
|
|
3208
|
+
const collectionIdPlaceholder = isUsersCollection ? '"_pb_users_auth_"' : `app.findCollectionByNameOrId("${field.relation.collection}").id`;
|
|
2803
3209
|
parts.push(` collectionId: ${collectionIdPlaceholder}`);
|
|
2804
3210
|
if (field.relation.maxSelect !== void 0) {
|
|
2805
3211
|
parts.push(` maxSelect: ${field.relation.maxSelect}`);
|
|
@@ -2883,7 +3289,7 @@ function generateIndexesArray(indexes) {
|
|
|
2883
3289
|
${indexStrings.join(",\n ")},
|
|
2884
3290
|
]`;
|
|
2885
3291
|
}
|
|
2886
|
-
function generateCollectionCreation(collection, varName = "collection") {
|
|
3292
|
+
function generateCollectionCreation(collection, varName = "collection", isLast = false) {
|
|
2887
3293
|
const lines = [];
|
|
2888
3294
|
lines.push(` const ${varName} = new Collection({`);
|
|
2889
3295
|
lines.push(` name: "${collection.name}",`);
|
|
@@ -2899,7 +3305,7 @@ function generateCollectionCreation(collection, varName = "collection") {
|
|
|
2899
3305
|
lines.push(` indexes: ${generateIndexesArray(collection.indexes)},`);
|
|
2900
3306
|
lines.push(` });`);
|
|
2901
3307
|
lines.push(``);
|
|
2902
|
-
lines.push(` app.save(${varName});`);
|
|
3308
|
+
lines.push(isLast ? ` return app.save(${varName});` : ` app.save(${varName});`);
|
|
2903
3309
|
return lines.join("\n");
|
|
2904
3310
|
}
|
|
2905
3311
|
function getFieldConstructorName(fieldType) {
|
|
@@ -2930,7 +3336,8 @@ function generateFieldConstructorOptions(field) {
|
|
|
2930
3336
|
}
|
|
2931
3337
|
}
|
|
2932
3338
|
if (field.relation && field.type === "relation") {
|
|
2933
|
-
const
|
|
3339
|
+
const isUsersCollection = field.relation.collection.toLowerCase() === "users";
|
|
3340
|
+
const collectionIdPlaceholder = isUsersCollection ? '"_pb_users_auth_"' : `app.findCollectionByNameOrId("${field.relation.collection}").id`;
|
|
2934
3341
|
parts.push(` collectionId: ${collectionIdPlaceholder}`);
|
|
2935
3342
|
if (field.relation.maxSelect !== void 0) {
|
|
2936
3343
|
parts.push(` maxSelect: ${field.relation.maxSelect}`);
|
|
@@ -2944,7 +3351,7 @@ function generateFieldConstructorOptions(field) {
|
|
|
2944
3351
|
}
|
|
2945
3352
|
return parts.join(",\n");
|
|
2946
3353
|
}
|
|
2947
|
-
function generateFieldAddition(collectionName, field, varName) {
|
|
3354
|
+
function generateFieldAddition(collectionName, field, varName, isLast = false) {
|
|
2948
3355
|
const lines = [];
|
|
2949
3356
|
const constructorName = getFieldConstructorName(field.type);
|
|
2950
3357
|
const collectionVar = varName || `collection_${collectionName}_${field.name}`;
|
|
@@ -2954,10 +3361,10 @@ function generateFieldAddition(collectionName, field, varName) {
|
|
|
2954
3361
|
lines.push(generateFieldConstructorOptions(field));
|
|
2955
3362
|
lines.push(` }));`);
|
|
2956
3363
|
lines.push(``);
|
|
2957
|
-
lines.push(` app.save(${collectionVar});`);
|
|
3364
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
2958
3365
|
return lines.join("\n");
|
|
2959
3366
|
}
|
|
2960
|
-
function generateFieldModification(collectionName, modification, varName) {
|
|
3367
|
+
function generateFieldModification(collectionName, modification, varName, isLast = false) {
|
|
2961
3368
|
const lines = [];
|
|
2962
3369
|
const collectionVar = varName || `collection_${collectionName}_${modification.fieldName}`;
|
|
2963
3370
|
const fieldVar = `${collectionVar}_field`;
|
|
@@ -2971,7 +3378,8 @@ function generateFieldModification(collectionName, modification, varName) {
|
|
|
2971
3378
|
} else if (change.property.startsWith("relation.")) {
|
|
2972
3379
|
const relationKey = change.property.replace("relation.", "");
|
|
2973
3380
|
if (relationKey === "collection") {
|
|
2974
|
-
const
|
|
3381
|
+
const isUsersCollection = String(change.newValue).toLowerCase() === "users";
|
|
3382
|
+
const collectionIdValue = isUsersCollection ? '"_pb_users_auth_"' : `app.findCollectionByNameOrId("${change.newValue}").id`;
|
|
2975
3383
|
lines.push(` ${fieldVar}.collectionId = ${collectionIdValue};`);
|
|
2976
3384
|
} else {
|
|
2977
3385
|
lines.push(` ${fieldVar}.${relationKey} = ${formatValue(change.newValue)};`);
|
|
@@ -2981,10 +3389,10 @@ function generateFieldModification(collectionName, modification, varName) {
|
|
|
2981
3389
|
}
|
|
2982
3390
|
}
|
|
2983
3391
|
lines.push(``);
|
|
2984
|
-
lines.push(` app.save(${collectionVar});`);
|
|
3392
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
2985
3393
|
return lines.join("\n");
|
|
2986
3394
|
}
|
|
2987
|
-
function generateFieldDeletion(collectionName, fieldName, varName) {
|
|
3395
|
+
function generateFieldDeletion(collectionName, fieldName, varName, isLast = false) {
|
|
2988
3396
|
const lines = [];
|
|
2989
3397
|
const collectionVar = varName || `collection_${collectionName}_${fieldName}`;
|
|
2990
3398
|
const fieldVar = `${collectionVar}_field`;
|
|
@@ -2993,18 +3401,18 @@ function generateFieldDeletion(collectionName, fieldName, varName) {
|
|
|
2993
3401
|
lines.push(``);
|
|
2994
3402
|
lines.push(` ${collectionVar}.fields.remove(${fieldVar}.id);`);
|
|
2995
3403
|
lines.push(``);
|
|
2996
|
-
lines.push(` app.save(${collectionVar});`);
|
|
3404
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
2997
3405
|
return lines.join("\n");
|
|
2998
3406
|
}
|
|
2999
|
-
function generateIndexAddition(collectionName, index, varName) {
|
|
3407
|
+
function generateIndexAddition(collectionName, index, varName, isLast = false) {
|
|
3000
3408
|
const lines = [];
|
|
3001
3409
|
const collectionVar = varName || `collection_${collectionName}_idx`;
|
|
3002
3410
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
3003
3411
|
lines.push(` ${collectionVar}.indexes.push("${index}");`);
|
|
3004
|
-
lines.push(` app.save(${collectionVar});`);
|
|
3412
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
3005
3413
|
return lines.join("\n");
|
|
3006
3414
|
}
|
|
3007
|
-
function generateIndexRemoval(collectionName, index, varName) {
|
|
3415
|
+
function generateIndexRemoval(collectionName, index, varName, isLast = false) {
|
|
3008
3416
|
const lines = [];
|
|
3009
3417
|
const collectionVar = varName || `collection_${collectionName}_idx`;
|
|
3010
3418
|
const indexVar = `${collectionVar}_indexToRemove`;
|
|
@@ -3013,29 +3421,29 @@ function generateIndexRemoval(collectionName, index, varName) {
|
|
|
3013
3421
|
lines.push(` if (${indexVar} !== -1) {`);
|
|
3014
3422
|
lines.push(` ${collectionVar}.indexes.splice(${indexVar}, 1);`);
|
|
3015
3423
|
lines.push(` }`);
|
|
3016
|
-
lines.push(` app.save(${collectionVar});`);
|
|
3424
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
3017
3425
|
return lines.join("\n");
|
|
3018
3426
|
}
|
|
3019
|
-
function generateRuleUpdate(collectionName, ruleType, newValue, varName) {
|
|
3427
|
+
function generateRuleUpdate(collectionName, ruleType, newValue, varName, isLast = false) {
|
|
3020
3428
|
const lines = [];
|
|
3021
3429
|
const collectionVar = varName || `collection_${collectionName}_${ruleType}`;
|
|
3022
3430
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
3023
3431
|
lines.push(` ${collectionVar}.${ruleType} = ${formatValue(newValue)};`);
|
|
3024
|
-
lines.push(` app.save(${collectionVar});`);
|
|
3432
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
3025
3433
|
return lines.join("\n");
|
|
3026
3434
|
}
|
|
3027
|
-
function generatePermissionUpdate(collectionName, ruleType, newValue, varName) {
|
|
3435
|
+
function generatePermissionUpdate(collectionName, ruleType, newValue, varName, isLast = false) {
|
|
3028
3436
|
const lines = [];
|
|
3029
3437
|
const collectionVar = varName || `collection_${collectionName}_${ruleType}`;
|
|
3030
3438
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
3031
3439
|
lines.push(` ${collectionVar}.${ruleType} = ${formatValue(newValue)};`);
|
|
3032
|
-
lines.push(` app.save(${collectionVar});`);
|
|
3440
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
3033
3441
|
return lines.join("\n");
|
|
3034
3442
|
}
|
|
3035
|
-
function generateCollectionDeletion(collectionName, varName = "collection") {
|
|
3443
|
+
function generateCollectionDeletion(collectionName, varName = "collection", isLast = false) {
|
|
3036
3444
|
const lines = [];
|
|
3037
3445
|
lines.push(` const ${varName} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
3038
|
-
lines.push(` app.delete(${varName});`);
|
|
3446
|
+
lines.push(isLast ? ` return app.delete(${varName});` : ` app.delete(${varName});`);
|
|
3039
3447
|
return lines.join("\n");
|
|
3040
3448
|
}
|
|
3041
3449
|
function generateUpMigration(diff) {
|
|
@@ -3127,7 +3535,24 @@ function generateUpMigration(diff) {
|
|
|
3127
3535
|
lines.push(` // No changes detected`);
|
|
3128
3536
|
lines.push(``);
|
|
3129
3537
|
}
|
|
3130
|
-
|
|
3538
|
+
let code = lines.join("\n");
|
|
3539
|
+
const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
|
|
3540
|
+
const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
|
|
3541
|
+
const saveMatches = [...code.matchAll(savePattern)];
|
|
3542
|
+
const deleteMatches = [...code.matchAll(deletePattern)];
|
|
3543
|
+
const allMatches = [
|
|
3544
|
+
...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
|
|
3545
|
+
...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
|
|
3546
|
+
].sort((a, b) => b.index - a.index);
|
|
3547
|
+
if (allMatches.length > 0) {
|
|
3548
|
+
const lastMatch = allMatches[0];
|
|
3549
|
+
if (lastMatch.type === "save") {
|
|
3550
|
+
code = code.substring(0, lastMatch.match.index) + lastMatch.match[1] + "return app.save(" + lastMatch.match[2] + ");" + code.substring(lastMatch.match.index + lastMatch.match[0].length);
|
|
3551
|
+
} else {
|
|
3552
|
+
code = code.substring(0, lastMatch.match.index) + lastMatch.match[1] + "return app.delete(" + lastMatch.match[2] + ");" + code.substring(lastMatch.match.index + lastMatch.match[0].length);
|
|
3553
|
+
}
|
|
3554
|
+
}
|
|
3555
|
+
return code;
|
|
3131
3556
|
}
|
|
3132
3557
|
function generateDownMigration(diff) {
|
|
3133
3558
|
const lines = [];
|
|
@@ -3229,7 +3654,24 @@ function generateDownMigration(diff) {
|
|
|
3229
3654
|
lines.push(` // No changes to revert`);
|
|
3230
3655
|
lines.push(``);
|
|
3231
3656
|
}
|
|
3232
|
-
|
|
3657
|
+
let code = lines.join("\n");
|
|
3658
|
+
const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
|
|
3659
|
+
const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
|
|
3660
|
+
const saveMatches = [...code.matchAll(savePattern)];
|
|
3661
|
+
const deleteMatches = [...code.matchAll(deletePattern)];
|
|
3662
|
+
const allMatches = [
|
|
3663
|
+
...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
|
|
3664
|
+
...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
|
|
3665
|
+
].sort((a, b) => b.index - a.index);
|
|
3666
|
+
if (allMatches.length > 0) {
|
|
3667
|
+
const lastMatch = allMatches[0];
|
|
3668
|
+
if (lastMatch.type === "save") {
|
|
3669
|
+
code = code.substring(0, lastMatch.match.index) + lastMatch.match[1] + "return app.save(" + lastMatch.match[2] + ");" + code.substring(lastMatch.match.index + lastMatch.match[0].length);
|
|
3670
|
+
} else {
|
|
3671
|
+
code = code.substring(0, lastMatch.match.index) + lastMatch.match[1] + "return app.delete(" + lastMatch.match[2] + ");" + code.substring(lastMatch.match.index + lastMatch.match[0].length);
|
|
3672
|
+
}
|
|
3673
|
+
}
|
|
3674
|
+
return code;
|
|
3233
3675
|
}
|
|
3234
3676
|
function generate(diff, config) {
|
|
3235
3677
|
const normalizedConfig = typeof config === "string" ? { migrationDir: config } : config;
|
|
@@ -3363,6 +3805,7 @@ exports.isSystemCollection = isSystemCollection;
|
|
|
3363
3805
|
exports.loadBaseMigration = loadBaseMigration;
|
|
3364
3806
|
exports.loadSnapshot = loadSnapshot;
|
|
3365
3807
|
exports.loadSnapshotIfExists = loadSnapshotIfExists;
|
|
3808
|
+
exports.loadSnapshotWithMigrations = loadSnapshotWithMigrations;
|
|
3366
3809
|
exports.mapZodArrayType = mapZodArrayType;
|
|
3367
3810
|
exports.mapZodBooleanType = mapZodBooleanType;
|
|
3368
3811
|
exports.mapZodDateType = mapZodDateType;
|