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.js
CHANGED
|
@@ -1,8 +1,37 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as fs3 from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
|
|
5
5
|
// src/migration/analyzer.ts
|
|
6
|
+
({
|
|
7
|
+
id: z.string().describe("unique id"),
|
|
8
|
+
collectionId: z.string().describe("collection id"),
|
|
9
|
+
collectionName: z.string().describe("collection name"),
|
|
10
|
+
expand: z.record(z.any()).describe("expandable fields")
|
|
11
|
+
});
|
|
12
|
+
({
|
|
13
|
+
created: z.string().describe("creation timestamp"),
|
|
14
|
+
updated: z.string().describe("last update timestamp")
|
|
15
|
+
});
|
|
16
|
+
({
|
|
17
|
+
thumbnailURL: z.string().optional(),
|
|
18
|
+
imageFiles: z.array(z.string())
|
|
19
|
+
});
|
|
20
|
+
({
|
|
21
|
+
imageFiles: z.array(z.instanceof(File))
|
|
22
|
+
});
|
|
23
|
+
var RELATION_METADATA_KEY = "__pocketbase_relation__";
|
|
24
|
+
function extractRelationMetadata(description) {
|
|
25
|
+
if (!description) return null;
|
|
26
|
+
try {
|
|
27
|
+
const parsed = JSON.parse(description);
|
|
28
|
+
if (parsed[RELATION_METADATA_KEY]) {
|
|
29
|
+
return parsed[RELATION_METADATA_KEY];
|
|
30
|
+
}
|
|
31
|
+
} catch {
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
6
35
|
|
|
7
36
|
// src/migration/errors.ts
|
|
8
37
|
var MigrationError = class _MigrationError extends Error {
|
|
@@ -101,10 +130,10 @@ var FileSystemError = class _FileSystemError extends MigrationError {
|
|
|
101
130
|
operation;
|
|
102
131
|
code;
|
|
103
132
|
originalError;
|
|
104
|
-
constructor(message,
|
|
133
|
+
constructor(message, path5, operation, code, originalError) {
|
|
105
134
|
super(message);
|
|
106
135
|
this.name = "FileSystemError";
|
|
107
|
-
this.path =
|
|
136
|
+
this.path = path5;
|
|
108
137
|
this.operation = operation;
|
|
109
138
|
this.code = code;
|
|
110
139
|
this.originalError = originalError;
|
|
@@ -193,7 +222,7 @@ Suggestion: ${this.suggestion}`);
|
|
|
193
222
|
}
|
|
194
223
|
};
|
|
195
224
|
|
|
196
|
-
// src/
|
|
225
|
+
// src/utils/permission-templates.ts
|
|
197
226
|
var PermissionTemplates = {
|
|
198
227
|
/**
|
|
199
228
|
* Public access - anyone can perform all operations
|
|
@@ -873,26 +902,28 @@ function getMaxSelect(fieldName, zodType) {
|
|
|
873
902
|
return 1;
|
|
874
903
|
}
|
|
875
904
|
function getMinSelect(fieldName, zodType) {
|
|
876
|
-
if (
|
|
877
|
-
return
|
|
878
|
-
}
|
|
879
|
-
let unwrappedType = zodType;
|
|
880
|
-
if (zodType instanceof z.ZodOptional) {
|
|
881
|
-
unwrappedType = zodType._def.innerType;
|
|
882
|
-
}
|
|
883
|
-
if (unwrappedType instanceof z.ZodNullable) {
|
|
884
|
-
unwrappedType = unwrappedType._def.innerType;
|
|
885
|
-
}
|
|
886
|
-
if (unwrappedType instanceof z.ZodDefault) {
|
|
887
|
-
unwrappedType = unwrappedType._def.innerType;
|
|
905
|
+
if (isSingleRelationField(fieldName, zodType)) {
|
|
906
|
+
return 0;
|
|
888
907
|
}
|
|
889
|
-
if (
|
|
890
|
-
|
|
891
|
-
if (
|
|
892
|
-
|
|
908
|
+
if (isMultipleRelationField(fieldName, zodType)) {
|
|
909
|
+
let unwrappedType = zodType;
|
|
910
|
+
if (zodType instanceof z.ZodOptional) {
|
|
911
|
+
unwrappedType = zodType._def.innerType;
|
|
912
|
+
}
|
|
913
|
+
if (unwrappedType instanceof z.ZodNullable) {
|
|
914
|
+
unwrappedType = unwrappedType._def.innerType;
|
|
915
|
+
}
|
|
916
|
+
if (unwrappedType instanceof z.ZodDefault) {
|
|
917
|
+
unwrappedType = unwrappedType._def.innerType;
|
|
918
|
+
}
|
|
919
|
+
if (unwrappedType instanceof z.ZodArray) {
|
|
920
|
+
const arrayDef = unwrappedType._def;
|
|
921
|
+
if (arrayDef.minLength) {
|
|
922
|
+
return arrayDef.minLength.value;
|
|
923
|
+
}
|
|
893
924
|
}
|
|
894
925
|
}
|
|
895
|
-
return
|
|
926
|
+
return 0;
|
|
896
927
|
}
|
|
897
928
|
var POCKETBASE_FIELD_TYPES = [
|
|
898
929
|
"text",
|
|
@@ -1325,10 +1356,10 @@ function discoverSchemaFiles(config) {
|
|
|
1325
1356
|
const mergedConfig = mergeConfig(normalizedConfig);
|
|
1326
1357
|
const schemaDir = resolveSchemaDir(normalizedConfig);
|
|
1327
1358
|
try {
|
|
1328
|
-
if (!
|
|
1359
|
+
if (!fs3.existsSync(schemaDir)) {
|
|
1329
1360
|
throw new FileSystemError(`Schema directory not found: ${schemaDir}`, schemaDir, "access", "ENOENT");
|
|
1330
1361
|
}
|
|
1331
|
-
const files =
|
|
1362
|
+
const files = fs3.readdirSync(schemaDir);
|
|
1332
1363
|
const schemaFiles = files.filter((file) => {
|
|
1333
1364
|
const hasValidExtension = mergedConfig.includeExtensions.some((ext) => file.endsWith(ext));
|
|
1334
1365
|
if (!hasValidExtension) return false;
|
|
@@ -1375,13 +1406,32 @@ async function importSchemaModule(filePath, config) {
|
|
|
1375
1406
|
if (config?.pathTransformer) {
|
|
1376
1407
|
importPath = config.pathTransformer(filePath);
|
|
1377
1408
|
}
|
|
1378
|
-
|
|
1379
|
-
|
|
1409
|
+
let resolvedPath = null;
|
|
1410
|
+
const jsPath = `${importPath}.js`;
|
|
1411
|
+
const tsPath = `${importPath}.ts`;
|
|
1412
|
+
if (fs3.existsSync(jsPath)) {
|
|
1413
|
+
resolvedPath = jsPath;
|
|
1414
|
+
} else if (fs3.existsSync(tsPath)) {
|
|
1415
|
+
resolvedPath = tsPath;
|
|
1416
|
+
} else {
|
|
1417
|
+
resolvedPath = jsPath;
|
|
1380
1418
|
}
|
|
1381
|
-
const fileUrl = new URL(`file://${path.resolve(
|
|
1419
|
+
const fileUrl = new URL(`file://${path.resolve(resolvedPath)}`);
|
|
1382
1420
|
const module = await import(fileUrl.href);
|
|
1383
1421
|
return module;
|
|
1384
1422
|
} catch (error) {
|
|
1423
|
+
const tsPath = `${filePath}.ts`;
|
|
1424
|
+
const isTypeScriptFile = fs3.existsSync(tsPath);
|
|
1425
|
+
if (isTypeScriptFile) {
|
|
1426
|
+
throw new SchemaParsingError(
|
|
1427
|
+
`Failed to import TypeScript schema file. Node.js cannot import TypeScript files directly.
|
|
1428
|
+
Please either:
|
|
1429
|
+
1. Compile your schema files to JavaScript first, or
|
|
1430
|
+
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")`,
|
|
1431
|
+
filePath,
|
|
1432
|
+
error
|
|
1433
|
+
);
|
|
1434
|
+
}
|
|
1385
1435
|
throw new SchemaParsingError(
|
|
1386
1436
|
`Failed to import schema module. Make sure the schema files are compiled to JavaScript.`,
|
|
1387
1437
|
filePath,
|
|
@@ -1444,7 +1494,17 @@ function buildFieldDefinition(fieldName, zodType) {
|
|
|
1444
1494
|
required,
|
|
1445
1495
|
options
|
|
1446
1496
|
};
|
|
1447
|
-
|
|
1497
|
+
const relationMetadata = extractRelationMetadata(zodType.description);
|
|
1498
|
+
if (relationMetadata) {
|
|
1499
|
+
fieldDef.type = "relation";
|
|
1500
|
+
fieldDef.relation = {
|
|
1501
|
+
collection: relationMetadata.collection,
|
|
1502
|
+
maxSelect: relationMetadata.maxSelect,
|
|
1503
|
+
minSelect: relationMetadata.minSelect,
|
|
1504
|
+
cascadeDelete: relationMetadata.cascadeDelete
|
|
1505
|
+
};
|
|
1506
|
+
fieldDef.options = void 0;
|
|
1507
|
+
} else if (isRelationField(fieldName, zodType)) {
|
|
1448
1508
|
fieldDef.type = "relation";
|
|
1449
1509
|
const targetCollection = resolveTargetCollection(fieldName);
|
|
1450
1510
|
const maxSelect = getMaxSelect(fieldName, zodType);
|
|
@@ -1456,6 +1516,13 @@ function buildFieldDefinition(fieldName, zodType) {
|
|
|
1456
1516
|
cascadeDelete: false
|
|
1457
1517
|
// Default to false, can be configured later
|
|
1458
1518
|
};
|
|
1519
|
+
if (fieldDef.options) {
|
|
1520
|
+
const { min, max, pattern, ...relationSafeOptions } = fieldDef.options;
|
|
1521
|
+
console.log("min", min);
|
|
1522
|
+
console.log("max", max);
|
|
1523
|
+
console.log("pattern", pattern);
|
|
1524
|
+
fieldDef.options = Object.keys(relationSafeOptions).length > 0 ? relationSafeOptions : void 0;
|
|
1525
|
+
}
|
|
1459
1526
|
}
|
|
1460
1527
|
return fieldDef;
|
|
1461
1528
|
}
|
|
@@ -1508,11 +1575,12 @@ function convertZodSchemaToCollectionSchema(collectionName, zodSchema) {
|
|
|
1508
1575
|
fields,
|
|
1509
1576
|
indexes,
|
|
1510
1577
|
rules: {
|
|
1511
|
-
listRule: null,
|
|
1512
|
-
viewRule: null,
|
|
1513
|
-
createRule: null,
|
|
1514
|
-
updateRule: null,
|
|
1515
|
-
deleteRule: null
|
|
1578
|
+
listRule: permissions?.listRule ?? null,
|
|
1579
|
+
viewRule: permissions?.viewRule ?? null,
|
|
1580
|
+
createRule: permissions?.createRule ?? null,
|
|
1581
|
+
updateRule: permissions?.updateRule ?? null,
|
|
1582
|
+
deleteRule: permissions?.deleteRule ?? null,
|
|
1583
|
+
manageRule: permissions?.manageRule ?? null
|
|
1516
1584
|
},
|
|
1517
1585
|
permissions
|
|
1518
1586
|
};
|
|
@@ -1536,7 +1604,12 @@ async function buildSchemaDefinition(config) {
|
|
|
1536
1604
|
if (normalizedConfig.pathTransformer) {
|
|
1537
1605
|
importPath = normalizedConfig.pathTransformer(filePath);
|
|
1538
1606
|
} else if (mergedConfig.useCompiledFiles) {
|
|
1539
|
-
|
|
1607
|
+
const distPath = filePath.replace(/\/src\//, "/dist/");
|
|
1608
|
+
if (fs3.existsSync(`${distPath}.js`) || fs3.existsSync(`${distPath}.mjs`)) {
|
|
1609
|
+
importPath = distPath;
|
|
1610
|
+
} else {
|
|
1611
|
+
importPath = filePath;
|
|
1612
|
+
}
|
|
1540
1613
|
}
|
|
1541
1614
|
const module = await importSchemaModule(importPath, normalizedConfig);
|
|
1542
1615
|
const schemas = extractSchemaDefinitions(module, mergedConfig.schemaPatterns);
|
|
@@ -1588,7 +1661,359 @@ var SchemaAnalyzer = class {
|
|
|
1588
1661
|
return convertZodSchemaToCollectionSchema(name, schema);
|
|
1589
1662
|
}
|
|
1590
1663
|
};
|
|
1664
|
+
|
|
1665
|
+
// src/migration/pocketbase-converter.ts
|
|
1591
1666
|
var SNAPSHOT_VERSION = "1.0.0";
|
|
1667
|
+
function resolveCollectionIdToName(collectionId) {
|
|
1668
|
+
if (collectionId === "_pb_users_auth_") {
|
|
1669
|
+
return "Users";
|
|
1670
|
+
}
|
|
1671
|
+
const nameMatch = collectionId.match(/app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\)/);
|
|
1672
|
+
if (nameMatch) {
|
|
1673
|
+
return nameMatch[1];
|
|
1674
|
+
}
|
|
1675
|
+
return collectionId;
|
|
1676
|
+
}
|
|
1677
|
+
function convertPocketBaseCollection(pbCollection) {
|
|
1678
|
+
const fields = [];
|
|
1679
|
+
const systemFieldNames = ["id", "created", "updated", "collectionId", "collectionName", "expand"];
|
|
1680
|
+
const authSystemFieldNames = ["email", "emailVisibility", "verified", "password", "tokenKey"];
|
|
1681
|
+
if (pbCollection.fields && Array.isArray(pbCollection.fields)) {
|
|
1682
|
+
for (const pbField of pbCollection.fields) {
|
|
1683
|
+
if (pbField.system || systemFieldNames.includes(pbField.name)) {
|
|
1684
|
+
continue;
|
|
1685
|
+
}
|
|
1686
|
+
if (pbCollection.type === "auth" && authSystemFieldNames.includes(pbField.name)) {
|
|
1687
|
+
continue;
|
|
1688
|
+
}
|
|
1689
|
+
const field = {
|
|
1690
|
+
name: pbField.name,
|
|
1691
|
+
type: pbField.type,
|
|
1692
|
+
required: pbField.required || false
|
|
1693
|
+
};
|
|
1694
|
+
field.options = pbField.options ? { ...pbField.options } : {};
|
|
1695
|
+
if (pbField.type === "select") {
|
|
1696
|
+
if (pbField.values && Array.isArray(pbField.values)) {
|
|
1697
|
+
field.options.values = pbField.values;
|
|
1698
|
+
} else if (pbField.options?.values && Array.isArray(pbField.options.values)) {
|
|
1699
|
+
field.options.values = pbField.options.values;
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
if (pbField.type === "relation") {
|
|
1703
|
+
const collectionId = pbField.collectionId || pbField.options?.collectionId || "";
|
|
1704
|
+
const collectionName = resolveCollectionIdToName(collectionId);
|
|
1705
|
+
field.relation = {
|
|
1706
|
+
collection: collectionName,
|
|
1707
|
+
cascadeDelete: pbField.cascadeDelete ?? pbField.options?.cascadeDelete ?? false,
|
|
1708
|
+
maxSelect: pbField.maxSelect ?? pbField.options?.maxSelect,
|
|
1709
|
+
minSelect: pbField.minSelect ?? pbField.options?.minSelect
|
|
1710
|
+
};
|
|
1711
|
+
}
|
|
1712
|
+
const hasOnlyValues = Object.keys(field.options).length === 1 && field.options.values !== void 0;
|
|
1713
|
+
if (Object.keys(field.options).length === 0) {
|
|
1714
|
+
delete field.options;
|
|
1715
|
+
} else if (pbField.type === "select" && hasOnlyValues) ;
|
|
1716
|
+
fields.push(field);
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
const schema = {
|
|
1720
|
+
name: pbCollection.name,
|
|
1721
|
+
type: pbCollection.type || "base",
|
|
1722
|
+
fields
|
|
1723
|
+
};
|
|
1724
|
+
if (pbCollection.indexes && Array.isArray(pbCollection.indexes)) {
|
|
1725
|
+
schema.indexes = pbCollection.indexes;
|
|
1726
|
+
}
|
|
1727
|
+
const rules = {};
|
|
1728
|
+
if (pbCollection.listRule !== void 0) rules.listRule = pbCollection.listRule;
|
|
1729
|
+
if (pbCollection.viewRule !== void 0) rules.viewRule = pbCollection.viewRule;
|
|
1730
|
+
if (pbCollection.createRule !== void 0) rules.createRule = pbCollection.createRule;
|
|
1731
|
+
if (pbCollection.updateRule !== void 0) rules.updateRule = pbCollection.updateRule;
|
|
1732
|
+
if (pbCollection.deleteRule !== void 0) rules.deleteRule = pbCollection.deleteRule;
|
|
1733
|
+
if (pbCollection.manageRule !== void 0) rules.manageRule = pbCollection.manageRule;
|
|
1734
|
+
if (Object.keys(rules).length > 0) {
|
|
1735
|
+
schema.rules = rules;
|
|
1736
|
+
schema.permissions = { ...rules };
|
|
1737
|
+
}
|
|
1738
|
+
return schema;
|
|
1739
|
+
}
|
|
1740
|
+
function convertPocketBaseMigration(migrationContent) {
|
|
1741
|
+
try {
|
|
1742
|
+
const snapshotMatch = migrationContent.match(/const\s+snapshot\s*=\s*(\[[\s\S]*?\]);/);
|
|
1743
|
+
if (!snapshotMatch) {
|
|
1744
|
+
throw new Error("Could not find snapshot array in migration file");
|
|
1745
|
+
}
|
|
1746
|
+
const snapshotArrayStr = snapshotMatch[1];
|
|
1747
|
+
let snapshotArray;
|
|
1748
|
+
try {
|
|
1749
|
+
snapshotArray = new Function(`return ${snapshotArrayStr}`)();
|
|
1750
|
+
} catch (parseError) {
|
|
1751
|
+
throw new Error(`Failed to parse snapshot array: ${parseError}`);
|
|
1752
|
+
}
|
|
1753
|
+
if (!Array.isArray(snapshotArray)) {
|
|
1754
|
+
throw new Error("Snapshot is not an array");
|
|
1755
|
+
}
|
|
1756
|
+
const collections = /* @__PURE__ */ new Map();
|
|
1757
|
+
for (const pbCollection of snapshotArray) {
|
|
1758
|
+
if (!pbCollection.name) {
|
|
1759
|
+
console.warn("Skipping collection without name");
|
|
1760
|
+
continue;
|
|
1761
|
+
}
|
|
1762
|
+
const schema = convertPocketBaseCollection(pbCollection);
|
|
1763
|
+
collections.set(pbCollection.name, schema);
|
|
1764
|
+
}
|
|
1765
|
+
return {
|
|
1766
|
+
version: SNAPSHOT_VERSION,
|
|
1767
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1768
|
+
collections
|
|
1769
|
+
};
|
|
1770
|
+
} catch (error) {
|
|
1771
|
+
throw new SnapshotError(
|
|
1772
|
+
`Failed to convert PocketBase migration: ${error instanceof Error ? error.message : String(error)}`,
|
|
1773
|
+
void 0,
|
|
1774
|
+
"parse",
|
|
1775
|
+
error instanceof Error ? error : void 0
|
|
1776
|
+
);
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
// src/migration/migration-parser.ts
|
|
1781
|
+
function extractTimestampFromFilename(filename) {
|
|
1782
|
+
const match = filename.match(/^(\d+)_/);
|
|
1783
|
+
if (match) {
|
|
1784
|
+
return parseInt(match[1], 10);
|
|
1785
|
+
}
|
|
1786
|
+
return null;
|
|
1787
|
+
}
|
|
1788
|
+
function findMigrationsAfterSnapshot(migrationsPath, snapshotTimestamp) {
|
|
1789
|
+
try {
|
|
1790
|
+
if (!fs3.existsSync(migrationsPath)) {
|
|
1791
|
+
return [];
|
|
1792
|
+
}
|
|
1793
|
+
const files = fs3.readdirSync(migrationsPath);
|
|
1794
|
+
const migrationFiles = [];
|
|
1795
|
+
for (const file of files) {
|
|
1796
|
+
if (file.endsWith("_collections_snapshot.js") || file.endsWith("_snapshot.js")) {
|
|
1797
|
+
continue;
|
|
1798
|
+
}
|
|
1799
|
+
if (!file.endsWith(".js")) {
|
|
1800
|
+
continue;
|
|
1801
|
+
}
|
|
1802
|
+
const timestamp = extractTimestampFromFilename(file);
|
|
1803
|
+
if (timestamp && timestamp > snapshotTimestamp) {
|
|
1804
|
+
migrationFiles.push({
|
|
1805
|
+
path: path.join(migrationsPath, file),
|
|
1806
|
+
timestamp
|
|
1807
|
+
});
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
migrationFiles.sort((a, b) => a.timestamp - b.timestamp);
|
|
1811
|
+
return migrationFiles.map((f) => f.path);
|
|
1812
|
+
} catch (error) {
|
|
1813
|
+
console.warn(`Error finding migrations after snapshot: ${error}`);
|
|
1814
|
+
return [];
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
function parseMigrationOperationsFromContent(content) {
|
|
1818
|
+
const collectionsToCreate = [];
|
|
1819
|
+
const collectionsToDelete = [];
|
|
1820
|
+
try {
|
|
1821
|
+
let searchIndex = 0;
|
|
1822
|
+
while (true) {
|
|
1823
|
+
const collectionStart = content.indexOf("new Collection(", searchIndex);
|
|
1824
|
+
if (collectionStart === -1) {
|
|
1825
|
+
break;
|
|
1826
|
+
}
|
|
1827
|
+
const openParen = collectionStart + "new Collection(".length;
|
|
1828
|
+
let braceCount = 0;
|
|
1829
|
+
let parenCount = 1;
|
|
1830
|
+
let inString = false;
|
|
1831
|
+
let stringChar = null;
|
|
1832
|
+
let i = openParen;
|
|
1833
|
+
while (i < content.length && /\s/.test(content[i])) {
|
|
1834
|
+
i++;
|
|
1835
|
+
}
|
|
1836
|
+
if (content[i] !== "{") {
|
|
1837
|
+
searchIndex = i + 1;
|
|
1838
|
+
continue;
|
|
1839
|
+
}
|
|
1840
|
+
const objectStart = i;
|
|
1841
|
+
braceCount = 1;
|
|
1842
|
+
i++;
|
|
1843
|
+
while (i < content.length && (braceCount > 0 || parenCount > 0)) {
|
|
1844
|
+
const char = content[i];
|
|
1845
|
+
const prevChar = i > 0 ? content[i - 1] : "";
|
|
1846
|
+
if (!inString && (char === '"' || char === "'")) {
|
|
1847
|
+
inString = true;
|
|
1848
|
+
stringChar = char;
|
|
1849
|
+
} else if (inString && char === stringChar && prevChar !== "\\") {
|
|
1850
|
+
inString = false;
|
|
1851
|
+
stringChar = null;
|
|
1852
|
+
}
|
|
1853
|
+
if (!inString) {
|
|
1854
|
+
if (char === "{") braceCount++;
|
|
1855
|
+
if (char === "}") braceCount--;
|
|
1856
|
+
if (char === "(") parenCount++;
|
|
1857
|
+
if (char === ")") parenCount--;
|
|
1858
|
+
}
|
|
1859
|
+
i++;
|
|
1860
|
+
}
|
|
1861
|
+
if (braceCount === 0 && parenCount === 0) {
|
|
1862
|
+
const objectContent = content.substring(objectStart, i - 1);
|
|
1863
|
+
try {
|
|
1864
|
+
const collectionObj = new Function(`return ${objectContent}`)();
|
|
1865
|
+
if (collectionObj && collectionObj.name) {
|
|
1866
|
+
const schema = convertPocketBaseCollection(collectionObj);
|
|
1867
|
+
collectionsToCreate.push(schema);
|
|
1868
|
+
}
|
|
1869
|
+
} catch (error) {
|
|
1870
|
+
console.warn(`Failed to parse collection definition: ${error}`);
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
searchIndex = i;
|
|
1874
|
+
}
|
|
1875
|
+
const deleteMatches = content.matchAll(
|
|
1876
|
+
/app\.delete\s*\(\s*(?:collection_\w+|app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\))\s*\)/g
|
|
1877
|
+
);
|
|
1878
|
+
for (const match of deleteMatches) {
|
|
1879
|
+
if (match[1]) {
|
|
1880
|
+
collectionsToDelete.push(match[1]);
|
|
1881
|
+
} else {
|
|
1882
|
+
const varNameMatch = match[0].match(/collection_(\w+)/);
|
|
1883
|
+
if (varNameMatch) {
|
|
1884
|
+
const varName = `collection_${varNameMatch[1]}`;
|
|
1885
|
+
const deleteIndex = content.indexOf(match[0]);
|
|
1886
|
+
const beforeDelete = content.substring(0, deleteIndex);
|
|
1887
|
+
const varDefMatch = beforeDelete.match(
|
|
1888
|
+
new RegExp(`const\\s+${varName}\\s*=\\s*new\\s+Collection\\(\\s*(\\{[\\s\\S]*?\\})\\s*\\)`, "g")
|
|
1889
|
+
);
|
|
1890
|
+
if (varDefMatch && varDefMatch.length > 0) {
|
|
1891
|
+
const collectionDefMatch = beforeDelete.match(
|
|
1892
|
+
new RegExp(`const\\s+${varName}\\s*=\\s*new\\s+Collection\\(\\s*(\\{[\\s\\S]*?\\})\\s*\\)`)
|
|
1893
|
+
);
|
|
1894
|
+
if (collectionDefMatch) {
|
|
1895
|
+
try {
|
|
1896
|
+
const collectionDefStr = collectionDefMatch[1];
|
|
1897
|
+
const collectionObj = new Function(`return ${collectionDefStr}`)();
|
|
1898
|
+
if (collectionObj && collectionObj.name) {
|
|
1899
|
+
collectionsToDelete.push(collectionObj.name);
|
|
1900
|
+
}
|
|
1901
|
+
} catch {
|
|
1902
|
+
}
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
const findAndDeleteMatches = content.matchAll(
|
|
1909
|
+
/app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\)[\s\S]*?app\.delete/g
|
|
1910
|
+
);
|
|
1911
|
+
for (const match of findAndDeleteMatches) {
|
|
1912
|
+
collectionsToDelete.push(match[1]);
|
|
1913
|
+
}
|
|
1914
|
+
} catch (error) {
|
|
1915
|
+
console.warn(`Failed to parse migration operations from content: ${error}`);
|
|
1916
|
+
}
|
|
1917
|
+
return { collectionsToCreate, collectionsToDelete };
|
|
1918
|
+
}
|
|
1919
|
+
function parseMigrationOperations(migrationContent) {
|
|
1920
|
+
try {
|
|
1921
|
+
const migrateMatch = migrationContent.match(/migrate\s*\(\s*/);
|
|
1922
|
+
if (!migrateMatch) {
|
|
1923
|
+
return parseMigrationOperationsFromContent(migrationContent);
|
|
1924
|
+
}
|
|
1925
|
+
const startIndex = migrateMatch.index + migrateMatch[0].length;
|
|
1926
|
+
let i = startIndex;
|
|
1927
|
+
let parenCount = 0;
|
|
1928
|
+
let foundFirstParen = false;
|
|
1929
|
+
while (i < migrationContent.length) {
|
|
1930
|
+
const char = migrationContent[i];
|
|
1931
|
+
if (char === "(") {
|
|
1932
|
+
parenCount++;
|
|
1933
|
+
foundFirstParen = true;
|
|
1934
|
+
i++;
|
|
1935
|
+
break;
|
|
1936
|
+
}
|
|
1937
|
+
i++;
|
|
1938
|
+
}
|
|
1939
|
+
if (!foundFirstParen) {
|
|
1940
|
+
return parseMigrationOperationsFromContent(migrationContent);
|
|
1941
|
+
}
|
|
1942
|
+
let inString = false;
|
|
1943
|
+
let stringChar = null;
|
|
1944
|
+
let foundBrace = false;
|
|
1945
|
+
let braceStart = -1;
|
|
1946
|
+
while (i < migrationContent.length && !foundBrace) {
|
|
1947
|
+
const char = migrationContent[i];
|
|
1948
|
+
const prevChar = i > 0 ? migrationContent[i - 1] : "";
|
|
1949
|
+
if (!inString && (char === '"' || char === "'")) {
|
|
1950
|
+
inString = true;
|
|
1951
|
+
stringChar = char;
|
|
1952
|
+
} else if (inString && char === stringChar && prevChar !== "\\") {
|
|
1953
|
+
inString = false;
|
|
1954
|
+
stringChar = null;
|
|
1955
|
+
}
|
|
1956
|
+
if (!inString) {
|
|
1957
|
+
if (char === "(") parenCount++;
|
|
1958
|
+
if (char === ")") {
|
|
1959
|
+
parenCount--;
|
|
1960
|
+
if (parenCount === 0) {
|
|
1961
|
+
i++;
|
|
1962
|
+
while (i < migrationContent.length && /\s/.test(migrationContent[i])) {
|
|
1963
|
+
i++;
|
|
1964
|
+
}
|
|
1965
|
+
if (i < migrationContent.length - 1 && migrationContent[i] === "=" && migrationContent[i + 1] === ">") {
|
|
1966
|
+
i += 2;
|
|
1967
|
+
while (i < migrationContent.length && /\s/.test(migrationContent[i])) {
|
|
1968
|
+
i++;
|
|
1969
|
+
}
|
|
1970
|
+
if (i < migrationContent.length && migrationContent[i] === "{") {
|
|
1971
|
+
foundBrace = true;
|
|
1972
|
+
braceStart = i + 1;
|
|
1973
|
+
break;
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
}
|
|
1978
|
+
}
|
|
1979
|
+
i++;
|
|
1980
|
+
}
|
|
1981
|
+
if (!foundBrace || braceStart === -1) {
|
|
1982
|
+
return parseMigrationOperationsFromContent(migrationContent);
|
|
1983
|
+
}
|
|
1984
|
+
let braceCount = 1;
|
|
1985
|
+
i = braceStart;
|
|
1986
|
+
inString = false;
|
|
1987
|
+
stringChar = null;
|
|
1988
|
+
while (i < migrationContent.length && braceCount > 0) {
|
|
1989
|
+
const char = migrationContent[i];
|
|
1990
|
+
const prevChar = i > 0 ? migrationContent[i - 1] : "";
|
|
1991
|
+
if (!inString && (char === '"' || char === "'")) {
|
|
1992
|
+
inString = true;
|
|
1993
|
+
stringChar = char;
|
|
1994
|
+
} else if (inString && char === stringChar && prevChar !== "\\") {
|
|
1995
|
+
inString = false;
|
|
1996
|
+
stringChar = null;
|
|
1997
|
+
}
|
|
1998
|
+
if (!inString) {
|
|
1999
|
+
if (char === "{") braceCount++;
|
|
2000
|
+
if (char === "}") braceCount--;
|
|
2001
|
+
}
|
|
2002
|
+
i++;
|
|
2003
|
+
}
|
|
2004
|
+
if (braceCount === 0) {
|
|
2005
|
+
const upMigrationContent = migrationContent.substring(braceStart, i - 1);
|
|
2006
|
+
return parseMigrationOperationsFromContent(upMigrationContent);
|
|
2007
|
+
}
|
|
2008
|
+
return parseMigrationOperationsFromContent(migrationContent);
|
|
2009
|
+
} catch (error) {
|
|
2010
|
+
console.warn(`Failed to parse migration operations: ${error}`);
|
|
2011
|
+
return { collectionsToCreate: [], collectionsToDelete: [] };
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
// src/migration/snapshot.ts
|
|
2016
|
+
var SNAPSHOT_VERSION2 = "1.0.0";
|
|
1592
2017
|
var DEFAULT_SNAPSHOT_FILENAME = ".migration-snapshot.json";
|
|
1593
2018
|
var SNAPSHOT_MIGRATIONS = [
|
|
1594
2019
|
// Add migrations here as the format evolves
|
|
@@ -1603,7 +2028,7 @@ var DEFAULT_CONFIG2 = {
|
|
|
1603
2028
|
snapshotPath: DEFAULT_SNAPSHOT_FILENAME,
|
|
1604
2029
|
workspaceRoot: process.cwd(),
|
|
1605
2030
|
autoMigrate: true,
|
|
1606
|
-
version:
|
|
2031
|
+
version: SNAPSHOT_VERSION2
|
|
1607
2032
|
};
|
|
1608
2033
|
function mergeConfig2(config = {}) {
|
|
1609
2034
|
return {
|
|
@@ -1623,7 +2048,7 @@ function getSnapshotPath(config = {}) {
|
|
|
1623
2048
|
function snapshotExists(config = {}) {
|
|
1624
2049
|
try {
|
|
1625
2050
|
const snapshotPath = getSnapshotPath(config);
|
|
1626
|
-
return
|
|
2051
|
+
return fs3.existsSync(snapshotPath);
|
|
1627
2052
|
} catch {
|
|
1628
2053
|
return false;
|
|
1629
2054
|
}
|
|
@@ -1683,12 +2108,12 @@ function saveSnapshot(schema, config = {}) {
|
|
|
1683
2108
|
const snapshotPath = getSnapshotPath(config);
|
|
1684
2109
|
try {
|
|
1685
2110
|
const snapshotDir = path.dirname(snapshotPath);
|
|
1686
|
-
if (!
|
|
1687
|
-
|
|
2111
|
+
if (!fs3.existsSync(snapshotDir)) {
|
|
2112
|
+
fs3.mkdirSync(snapshotDir, { recursive: true });
|
|
1688
2113
|
}
|
|
1689
2114
|
const snapshotData = addSnapshotMetadata(schema, config);
|
|
1690
2115
|
const jsonContent = JSON.stringify(snapshotData, null, 2);
|
|
1691
|
-
|
|
2116
|
+
fs3.writeFileSync(snapshotPath, jsonContent, "utf-8");
|
|
1692
2117
|
} catch (error) {
|
|
1693
2118
|
handleFileSystemError(error, "write", snapshotPath);
|
|
1694
2119
|
}
|
|
@@ -1783,7 +2208,7 @@ function deserializeSnapshot(data) {
|
|
|
1783
2208
|
function loadSnapshot(config = {}) {
|
|
1784
2209
|
const snapshotPath = getSnapshotPath(config);
|
|
1785
2210
|
try {
|
|
1786
|
-
const jsonContent =
|
|
2211
|
+
const jsonContent = fs3.readFileSync(snapshotPath, "utf-8");
|
|
1787
2212
|
const data = parseAndValidateSnapshot(jsonContent, snapshotPath);
|
|
1788
2213
|
const migratedData = migrateSnapshotFormat(data, config);
|
|
1789
2214
|
return deserializeSnapshot(migratedData);
|
|
@@ -1818,10 +2243,10 @@ function mergeSnapshots(baseSnapshot, customSnapshot) {
|
|
|
1818
2243
|
}
|
|
1819
2244
|
function findLatestSnapshot(migrationsPath) {
|
|
1820
2245
|
try {
|
|
1821
|
-
if (!
|
|
2246
|
+
if (!fs3.existsSync(migrationsPath)) {
|
|
1822
2247
|
return null;
|
|
1823
2248
|
}
|
|
1824
|
-
const files =
|
|
2249
|
+
const files = fs3.readdirSync(migrationsPath);
|
|
1825
2250
|
const snapshotFiles = files.filter(
|
|
1826
2251
|
(file) => file.endsWith("_collections_snapshot.js") || file.endsWith("_snapshot.js")
|
|
1827
2252
|
);
|
|
@@ -1839,14 +2264,68 @@ function findLatestSnapshot(migrationsPath) {
|
|
|
1839
2264
|
return null;
|
|
1840
2265
|
}
|
|
1841
2266
|
}
|
|
2267
|
+
function applyMigrationOperations(snapshot, operations) {
|
|
2268
|
+
const updatedCollections = new Map(snapshot.collections);
|
|
2269
|
+
for (const collectionName of operations.collectionsToDelete) {
|
|
2270
|
+
updatedCollections.delete(collectionName);
|
|
2271
|
+
}
|
|
2272
|
+
for (const collection of operations.collectionsToCreate) {
|
|
2273
|
+
updatedCollections.set(collection.name, collection);
|
|
2274
|
+
}
|
|
2275
|
+
return {
|
|
2276
|
+
...snapshot,
|
|
2277
|
+
collections: updatedCollections
|
|
2278
|
+
};
|
|
2279
|
+
}
|
|
2280
|
+
function loadSnapshotWithMigrations(config = {}) {
|
|
2281
|
+
const migrationsPath = config.migrationsPath;
|
|
2282
|
+
if (!migrationsPath) {
|
|
2283
|
+
return null;
|
|
2284
|
+
}
|
|
2285
|
+
if (fs3.existsSync(migrationsPath) && fs3.statSync(migrationsPath).isFile()) {
|
|
2286
|
+
try {
|
|
2287
|
+
const migrationContent = fs3.readFileSync(migrationsPath, "utf-8");
|
|
2288
|
+
return convertPocketBaseMigration(migrationContent);
|
|
2289
|
+
} catch (error) {
|
|
2290
|
+
console.warn(`Failed to load snapshot from ${migrationsPath}: ${error}`);
|
|
2291
|
+
return null;
|
|
2292
|
+
}
|
|
2293
|
+
}
|
|
2294
|
+
const latestSnapshotPath = findLatestSnapshot(migrationsPath);
|
|
2295
|
+
if (!latestSnapshotPath) {
|
|
2296
|
+
return null;
|
|
2297
|
+
}
|
|
2298
|
+
try {
|
|
2299
|
+
const migrationContent = fs3.readFileSync(latestSnapshotPath, "utf-8");
|
|
2300
|
+
let snapshot = convertPocketBaseMigration(migrationContent);
|
|
2301
|
+
const snapshotFilename = path.basename(latestSnapshotPath);
|
|
2302
|
+
const snapshotTimestamp = extractTimestampFromFilename(snapshotFilename);
|
|
2303
|
+
if (snapshotTimestamp) {
|
|
2304
|
+
const migrationFiles = findMigrationsAfterSnapshot(migrationsPath, snapshotTimestamp);
|
|
2305
|
+
for (const migrationFile of migrationFiles) {
|
|
2306
|
+
try {
|
|
2307
|
+
const migrationContent2 = fs3.readFileSync(migrationFile, "utf-8");
|
|
2308
|
+
const operations = parseMigrationOperations(migrationContent2);
|
|
2309
|
+
snapshot = applyMigrationOperations(snapshot, operations);
|
|
2310
|
+
} catch (error) {
|
|
2311
|
+
console.warn(`Failed to apply migration ${migrationFile}: ${error}`);
|
|
2312
|
+
}
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2315
|
+
return snapshot;
|
|
2316
|
+
} catch (error) {
|
|
2317
|
+
console.warn(`Failed to load snapshot from ${latestSnapshotPath}: ${error}`);
|
|
2318
|
+
return null;
|
|
2319
|
+
}
|
|
2320
|
+
}
|
|
1842
2321
|
function loadSnapshotIfExists(config = {}) {
|
|
1843
2322
|
const migrationsPath = config.migrationsPath;
|
|
1844
2323
|
if (!migrationsPath) {
|
|
1845
2324
|
return null;
|
|
1846
2325
|
}
|
|
1847
|
-
if (
|
|
2326
|
+
if (fs3.existsSync(migrationsPath) && fs3.statSync(migrationsPath).isFile()) {
|
|
1848
2327
|
try {
|
|
1849
|
-
const migrationContent =
|
|
2328
|
+
const migrationContent = fs3.readFileSync(migrationsPath, "utf-8");
|
|
1850
2329
|
return convertPocketBaseMigration(migrationContent);
|
|
1851
2330
|
} catch (error) {
|
|
1852
2331
|
console.warn(`Failed to load snapshot from ${migrationsPath}: ${error}`);
|
|
@@ -1856,7 +2335,7 @@ function loadSnapshotIfExists(config = {}) {
|
|
|
1856
2335
|
const latestSnapshotPath = findLatestSnapshot(migrationsPath);
|
|
1857
2336
|
if (latestSnapshotPath) {
|
|
1858
2337
|
try {
|
|
1859
|
-
const migrationContent =
|
|
2338
|
+
const migrationContent = fs3.readFileSync(latestSnapshotPath, "utf-8");
|
|
1860
2339
|
return convertPocketBaseMigration(migrationContent);
|
|
1861
2340
|
} catch (error) {
|
|
1862
2341
|
console.warn(`Failed to load snapshot from ${latestSnapshotPath}: ${error}`);
|
|
@@ -1865,99 +2344,9 @@ function loadSnapshotIfExists(config = {}) {
|
|
|
1865
2344
|
}
|
|
1866
2345
|
return null;
|
|
1867
2346
|
}
|
|
1868
|
-
function convertPocketBaseCollection(pbCollection) {
|
|
1869
|
-
const fields = [];
|
|
1870
|
-
const systemFieldNames = ["id", "created", "updated", "collectionId", "collectionName", "expand"];
|
|
1871
|
-
const authSystemFieldNames = ["email", "emailVisibility", "verified", "password", "tokenKey"];
|
|
1872
|
-
if (pbCollection.fields && Array.isArray(pbCollection.fields)) {
|
|
1873
|
-
for (const pbField of pbCollection.fields) {
|
|
1874
|
-
if (pbField.system || systemFieldNames.includes(pbField.name)) {
|
|
1875
|
-
continue;
|
|
1876
|
-
}
|
|
1877
|
-
if (pbCollection.type === "auth" && authSystemFieldNames.includes(pbField.name)) {
|
|
1878
|
-
continue;
|
|
1879
|
-
}
|
|
1880
|
-
const field = {
|
|
1881
|
-
name: pbField.name,
|
|
1882
|
-
type: pbField.type,
|
|
1883
|
-
required: pbField.required || false
|
|
1884
|
-
};
|
|
1885
|
-
if (pbField.options) {
|
|
1886
|
-
field.options = pbField.options;
|
|
1887
|
-
}
|
|
1888
|
-
if (pbField.type === "relation") {
|
|
1889
|
-
field.relation = {
|
|
1890
|
-
collection: pbField.options?.collectionId || "",
|
|
1891
|
-
cascadeDelete: pbField.options?.cascadeDelete || false,
|
|
1892
|
-
maxSelect: pbField.options?.maxSelect,
|
|
1893
|
-
minSelect: pbField.options?.minSelect
|
|
1894
|
-
};
|
|
1895
|
-
}
|
|
1896
|
-
fields.push(field);
|
|
1897
|
-
}
|
|
1898
|
-
}
|
|
1899
|
-
const schema = {
|
|
1900
|
-
name: pbCollection.name,
|
|
1901
|
-
type: pbCollection.type || "base",
|
|
1902
|
-
fields
|
|
1903
|
-
};
|
|
1904
|
-
if (pbCollection.indexes && Array.isArray(pbCollection.indexes)) {
|
|
1905
|
-
schema.indexes = pbCollection.indexes;
|
|
1906
|
-
}
|
|
1907
|
-
const rules = {};
|
|
1908
|
-
if (pbCollection.listRule !== void 0) rules.listRule = pbCollection.listRule;
|
|
1909
|
-
if (pbCollection.viewRule !== void 0) rules.viewRule = pbCollection.viewRule;
|
|
1910
|
-
if (pbCollection.createRule !== void 0) rules.createRule = pbCollection.createRule;
|
|
1911
|
-
if (pbCollection.updateRule !== void 0) rules.updateRule = pbCollection.updateRule;
|
|
1912
|
-
if (pbCollection.deleteRule !== void 0) rules.deleteRule = pbCollection.deleteRule;
|
|
1913
|
-
if (pbCollection.manageRule !== void 0) rules.manageRule = pbCollection.manageRule;
|
|
1914
|
-
if (Object.keys(rules).length > 0) {
|
|
1915
|
-
schema.rules = rules;
|
|
1916
|
-
}
|
|
1917
|
-
return schema;
|
|
1918
|
-
}
|
|
1919
|
-
function convertPocketBaseMigration(migrationContent) {
|
|
1920
|
-
try {
|
|
1921
|
-
const snapshotMatch = migrationContent.match(/const\s+snapshot\s*=\s*(\[[\s\S]*?\]);/);
|
|
1922
|
-
if (!snapshotMatch) {
|
|
1923
|
-
throw new Error("Could not find snapshot array in migration file");
|
|
1924
|
-
}
|
|
1925
|
-
const snapshotArrayStr = snapshotMatch[1];
|
|
1926
|
-
let snapshotArray;
|
|
1927
|
-
try {
|
|
1928
|
-
snapshotArray = new Function(`return ${snapshotArrayStr}`)();
|
|
1929
|
-
} catch (parseError) {
|
|
1930
|
-
throw new Error(`Failed to parse snapshot array: ${parseError}`);
|
|
1931
|
-
}
|
|
1932
|
-
if (!Array.isArray(snapshotArray)) {
|
|
1933
|
-
throw new Error("Snapshot is not an array");
|
|
1934
|
-
}
|
|
1935
|
-
const collections = /* @__PURE__ */ new Map();
|
|
1936
|
-
for (const pbCollection of snapshotArray) {
|
|
1937
|
-
if (!pbCollection.name) {
|
|
1938
|
-
console.warn("Skipping collection without name");
|
|
1939
|
-
continue;
|
|
1940
|
-
}
|
|
1941
|
-
const schema = convertPocketBaseCollection(pbCollection);
|
|
1942
|
-
collections.set(pbCollection.name, schema);
|
|
1943
|
-
}
|
|
1944
|
-
return {
|
|
1945
|
-
version: SNAPSHOT_VERSION,
|
|
1946
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1947
|
-
collections
|
|
1948
|
-
};
|
|
1949
|
-
} catch (error) {
|
|
1950
|
-
throw new SnapshotError(
|
|
1951
|
-
`Failed to convert PocketBase migration: ${error instanceof Error ? error.message : String(error)}`,
|
|
1952
|
-
void 0,
|
|
1953
|
-
"parse",
|
|
1954
|
-
error instanceof Error ? error : void 0
|
|
1955
|
-
);
|
|
1956
|
-
}
|
|
1957
|
-
}
|
|
1958
2347
|
function loadBaseMigration(migrationPath) {
|
|
1959
2348
|
try {
|
|
1960
|
-
if (!
|
|
2349
|
+
if (!fs3.existsSync(migrationPath)) {
|
|
1961
2350
|
throw new SnapshotError(
|
|
1962
2351
|
`Base migration file not found: ${migrationPath}
|
|
1963
2352
|
|
|
@@ -1968,7 +2357,7 @@ If the file exists in a different location, update the configuration.`,
|
|
|
1968
2357
|
"read"
|
|
1969
2358
|
);
|
|
1970
2359
|
}
|
|
1971
|
-
const migrationContent =
|
|
2360
|
+
const migrationContent = fs3.readFileSync(migrationPath, "utf-8");
|
|
1972
2361
|
const snapshot = convertPocketBaseMigration(migrationContent);
|
|
1973
2362
|
return snapshot;
|
|
1974
2363
|
} catch (error) {
|
|
@@ -2004,14 +2393,14 @@ Please ensure PocketBase is properly set up by running 'yarn setup'.`,
|
|
|
2004
2393
|
}
|
|
2005
2394
|
}
|
|
2006
2395
|
function getSnapshotVersion() {
|
|
2007
|
-
return
|
|
2396
|
+
return SNAPSHOT_VERSION2;
|
|
2008
2397
|
}
|
|
2009
2398
|
function validateSnapshot(snapshot) {
|
|
2010
2399
|
const issues = [];
|
|
2011
2400
|
if (!snapshot.version) {
|
|
2012
2401
|
issues.push("Missing version field");
|
|
2013
|
-
} else if (compareVersions(snapshot.version,
|
|
2014
|
-
issues.push(`Snapshot version ${snapshot.version} is newer than supported version ${
|
|
2402
|
+
} else if (compareVersions(snapshot.version, SNAPSHOT_VERSION2) > 0) {
|
|
2403
|
+
issues.push(`Snapshot version ${snapshot.version} is newer than supported version ${SNAPSHOT_VERSION2}`);
|
|
2015
2404
|
}
|
|
2016
2405
|
if (!snapshot.timestamp) {
|
|
2017
2406
|
issues.push("Missing timestamp field");
|
|
@@ -2230,6 +2619,9 @@ function compareFieldOptions(currentField, previousField) {
|
|
|
2230
2619
|
for (const key of allKeys) {
|
|
2231
2620
|
const currentValue = currentOptions[key];
|
|
2232
2621
|
const previousValue = previousOptions[key];
|
|
2622
|
+
if (currentValue === void 0 && previousValue === void 0) {
|
|
2623
|
+
continue;
|
|
2624
|
+
}
|
|
2233
2625
|
if (!areValuesEqual(currentValue, previousValue)) {
|
|
2234
2626
|
changes.push({
|
|
2235
2627
|
property: `options.${key}`,
|
|
@@ -2250,11 +2642,26 @@ function compareRelationConfigurations(currentField, previousField) {
|
|
|
2250
2642
|
if (!currentRelation || !previousRelation) {
|
|
2251
2643
|
return changes;
|
|
2252
2644
|
}
|
|
2253
|
-
|
|
2645
|
+
const normalizeCollection = (collection) => {
|
|
2646
|
+
if (!collection) return collection;
|
|
2647
|
+
if (collection === "_pb_users_auth_") {
|
|
2648
|
+
return "Users";
|
|
2649
|
+
}
|
|
2650
|
+
const nameMatch = collection.match(/app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\)/);
|
|
2651
|
+
if (nameMatch) {
|
|
2652
|
+
return nameMatch[1];
|
|
2653
|
+
}
|
|
2654
|
+
return collection;
|
|
2655
|
+
};
|
|
2656
|
+
const normalizedCurrent = normalizeCollection(currentRelation.collection);
|
|
2657
|
+
const normalizedPrevious = normalizeCollection(previousRelation.collection);
|
|
2658
|
+
if (normalizedCurrent !== normalizedPrevious) {
|
|
2254
2659
|
changes.push({
|
|
2255
2660
|
property: "relation.collection",
|
|
2256
|
-
oldValue:
|
|
2257
|
-
|
|
2661
|
+
oldValue: normalizedPrevious,
|
|
2662
|
+
// Use normalized value for clarity
|
|
2663
|
+
newValue: normalizedCurrent
|
|
2664
|
+
// Use normalized value for clarity
|
|
2258
2665
|
});
|
|
2259
2666
|
}
|
|
2260
2667
|
if (currentRelation.cascadeDelete !== previousRelation.cascadeDelete) {
|
|
@@ -2608,10 +3015,8 @@ var DiffEngine = class {
|
|
|
2608
3015
|
var DEFAULT_TEMPLATE = `/// <reference path="{{TYPES_PATH}}" />
|
|
2609
3016
|
migrate((app) => {
|
|
2610
3017
|
{{UP_CODE}}
|
|
2611
|
-
return true;
|
|
2612
3018
|
}, (app) => {
|
|
2613
3019
|
{{DOWN_CODE}}
|
|
2614
|
-
return true;
|
|
2615
3020
|
});
|
|
2616
3021
|
`;
|
|
2617
3022
|
var DEFAULT_CONFIG4 = {
|
|
@@ -2690,9 +3095,9 @@ function createMigrationFileStructure(upCode, downCode, config) {
|
|
|
2690
3095
|
}
|
|
2691
3096
|
function writeMigrationFile(migrationDir, filename, content) {
|
|
2692
3097
|
try {
|
|
2693
|
-
if (!
|
|
3098
|
+
if (!fs3.existsSync(migrationDir)) {
|
|
2694
3099
|
try {
|
|
2695
|
-
|
|
3100
|
+
fs3.mkdirSync(migrationDir, { recursive: true });
|
|
2696
3101
|
} catch (error) {
|
|
2697
3102
|
const fsError = error;
|
|
2698
3103
|
if (fsError.code === "EACCES" || fsError.code === "EPERM") {
|
|
@@ -2714,7 +3119,7 @@ function writeMigrationFile(migrationDir, filename, content) {
|
|
|
2714
3119
|
}
|
|
2715
3120
|
}
|
|
2716
3121
|
const filePath = path.join(migrationDir, filename);
|
|
2717
|
-
|
|
3122
|
+
fs3.writeFileSync(filePath, content, "utf-8");
|
|
2718
3123
|
return filePath;
|
|
2719
3124
|
} catch (error) {
|
|
2720
3125
|
if (error instanceof FileSystemError) {
|
|
@@ -2776,7 +3181,8 @@ function generateFieldDefinitionObject(field) {
|
|
|
2776
3181
|
}
|
|
2777
3182
|
}
|
|
2778
3183
|
if (field.relation) {
|
|
2779
|
-
const
|
|
3184
|
+
const isUsersCollection = field.relation.collection.toLowerCase() === "users";
|
|
3185
|
+
const collectionIdPlaceholder = isUsersCollection ? '"_pb_users_auth_"' : `app.findCollectionByNameOrId("${field.relation.collection}").id`;
|
|
2780
3186
|
parts.push(` collectionId: ${collectionIdPlaceholder}`);
|
|
2781
3187
|
if (field.relation.maxSelect !== void 0) {
|
|
2782
3188
|
parts.push(` maxSelect: ${field.relation.maxSelect}`);
|
|
@@ -2860,7 +3266,7 @@ function generateIndexesArray(indexes) {
|
|
|
2860
3266
|
${indexStrings.join(",\n ")},
|
|
2861
3267
|
]`;
|
|
2862
3268
|
}
|
|
2863
|
-
function generateCollectionCreation(collection, varName = "collection") {
|
|
3269
|
+
function generateCollectionCreation(collection, varName = "collection", isLast = false) {
|
|
2864
3270
|
const lines = [];
|
|
2865
3271
|
lines.push(` const ${varName} = new Collection({`);
|
|
2866
3272
|
lines.push(` name: "${collection.name}",`);
|
|
@@ -2876,7 +3282,7 @@ function generateCollectionCreation(collection, varName = "collection") {
|
|
|
2876
3282
|
lines.push(` indexes: ${generateIndexesArray(collection.indexes)},`);
|
|
2877
3283
|
lines.push(` });`);
|
|
2878
3284
|
lines.push(``);
|
|
2879
|
-
lines.push(` app.save(${varName});`);
|
|
3285
|
+
lines.push(isLast ? ` return app.save(${varName});` : ` app.save(${varName});`);
|
|
2880
3286
|
return lines.join("\n");
|
|
2881
3287
|
}
|
|
2882
3288
|
function getFieldConstructorName(fieldType) {
|
|
@@ -2907,7 +3313,8 @@ function generateFieldConstructorOptions(field) {
|
|
|
2907
3313
|
}
|
|
2908
3314
|
}
|
|
2909
3315
|
if (field.relation && field.type === "relation") {
|
|
2910
|
-
const
|
|
3316
|
+
const isUsersCollection = field.relation.collection.toLowerCase() === "users";
|
|
3317
|
+
const collectionIdPlaceholder = isUsersCollection ? '"_pb_users_auth_"' : `app.findCollectionByNameOrId("${field.relation.collection}").id`;
|
|
2911
3318
|
parts.push(` collectionId: ${collectionIdPlaceholder}`);
|
|
2912
3319
|
if (field.relation.maxSelect !== void 0) {
|
|
2913
3320
|
parts.push(` maxSelect: ${field.relation.maxSelect}`);
|
|
@@ -2921,7 +3328,7 @@ function generateFieldConstructorOptions(field) {
|
|
|
2921
3328
|
}
|
|
2922
3329
|
return parts.join(",\n");
|
|
2923
3330
|
}
|
|
2924
|
-
function generateFieldAddition(collectionName, field, varName) {
|
|
3331
|
+
function generateFieldAddition(collectionName, field, varName, isLast = false) {
|
|
2925
3332
|
const lines = [];
|
|
2926
3333
|
const constructorName = getFieldConstructorName(field.type);
|
|
2927
3334
|
const collectionVar = varName || `collection_${collectionName}_${field.name}`;
|
|
@@ -2931,10 +3338,10 @@ function generateFieldAddition(collectionName, field, varName) {
|
|
|
2931
3338
|
lines.push(generateFieldConstructorOptions(field));
|
|
2932
3339
|
lines.push(` }));`);
|
|
2933
3340
|
lines.push(``);
|
|
2934
|
-
lines.push(` app.save(${collectionVar});`);
|
|
3341
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
2935
3342
|
return lines.join("\n");
|
|
2936
3343
|
}
|
|
2937
|
-
function generateFieldModification(collectionName, modification, varName) {
|
|
3344
|
+
function generateFieldModification(collectionName, modification, varName, isLast = false) {
|
|
2938
3345
|
const lines = [];
|
|
2939
3346
|
const collectionVar = varName || `collection_${collectionName}_${modification.fieldName}`;
|
|
2940
3347
|
const fieldVar = `${collectionVar}_field`;
|
|
@@ -2948,7 +3355,8 @@ function generateFieldModification(collectionName, modification, varName) {
|
|
|
2948
3355
|
} else if (change.property.startsWith("relation.")) {
|
|
2949
3356
|
const relationKey = change.property.replace("relation.", "");
|
|
2950
3357
|
if (relationKey === "collection") {
|
|
2951
|
-
const
|
|
3358
|
+
const isUsersCollection = String(change.newValue).toLowerCase() === "users";
|
|
3359
|
+
const collectionIdValue = isUsersCollection ? '"_pb_users_auth_"' : `app.findCollectionByNameOrId("${change.newValue}").id`;
|
|
2952
3360
|
lines.push(` ${fieldVar}.collectionId = ${collectionIdValue};`);
|
|
2953
3361
|
} else {
|
|
2954
3362
|
lines.push(` ${fieldVar}.${relationKey} = ${formatValue(change.newValue)};`);
|
|
@@ -2958,10 +3366,10 @@ function generateFieldModification(collectionName, modification, varName) {
|
|
|
2958
3366
|
}
|
|
2959
3367
|
}
|
|
2960
3368
|
lines.push(``);
|
|
2961
|
-
lines.push(` app.save(${collectionVar});`);
|
|
3369
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
2962
3370
|
return lines.join("\n");
|
|
2963
3371
|
}
|
|
2964
|
-
function generateFieldDeletion(collectionName, fieldName, varName) {
|
|
3372
|
+
function generateFieldDeletion(collectionName, fieldName, varName, isLast = false) {
|
|
2965
3373
|
const lines = [];
|
|
2966
3374
|
const collectionVar = varName || `collection_${collectionName}_${fieldName}`;
|
|
2967
3375
|
const fieldVar = `${collectionVar}_field`;
|
|
@@ -2970,18 +3378,18 @@ function generateFieldDeletion(collectionName, fieldName, varName) {
|
|
|
2970
3378
|
lines.push(``);
|
|
2971
3379
|
lines.push(` ${collectionVar}.fields.remove(${fieldVar}.id);`);
|
|
2972
3380
|
lines.push(``);
|
|
2973
|
-
lines.push(` app.save(${collectionVar});`);
|
|
3381
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
2974
3382
|
return lines.join("\n");
|
|
2975
3383
|
}
|
|
2976
|
-
function generateIndexAddition(collectionName, index, varName) {
|
|
3384
|
+
function generateIndexAddition(collectionName, index, varName, isLast = false) {
|
|
2977
3385
|
const lines = [];
|
|
2978
3386
|
const collectionVar = varName || `collection_${collectionName}_idx`;
|
|
2979
3387
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
2980
3388
|
lines.push(` ${collectionVar}.indexes.push("${index}");`);
|
|
2981
|
-
lines.push(` app.save(${collectionVar});`);
|
|
3389
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
2982
3390
|
return lines.join("\n");
|
|
2983
3391
|
}
|
|
2984
|
-
function generateIndexRemoval(collectionName, index, varName) {
|
|
3392
|
+
function generateIndexRemoval(collectionName, index, varName, isLast = false) {
|
|
2985
3393
|
const lines = [];
|
|
2986
3394
|
const collectionVar = varName || `collection_${collectionName}_idx`;
|
|
2987
3395
|
const indexVar = `${collectionVar}_indexToRemove`;
|
|
@@ -2990,29 +3398,29 @@ function generateIndexRemoval(collectionName, index, varName) {
|
|
|
2990
3398
|
lines.push(` if (${indexVar} !== -1) {`);
|
|
2991
3399
|
lines.push(` ${collectionVar}.indexes.splice(${indexVar}, 1);`);
|
|
2992
3400
|
lines.push(` }`);
|
|
2993
|
-
lines.push(` app.save(${collectionVar});`);
|
|
3401
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
2994
3402
|
return lines.join("\n");
|
|
2995
3403
|
}
|
|
2996
|
-
function generateRuleUpdate(collectionName, ruleType, newValue, varName) {
|
|
3404
|
+
function generateRuleUpdate(collectionName, ruleType, newValue, varName, isLast = false) {
|
|
2997
3405
|
const lines = [];
|
|
2998
3406
|
const collectionVar = varName || `collection_${collectionName}_${ruleType}`;
|
|
2999
3407
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
3000
3408
|
lines.push(` ${collectionVar}.${ruleType} = ${formatValue(newValue)};`);
|
|
3001
|
-
lines.push(` app.save(${collectionVar});`);
|
|
3409
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
3002
3410
|
return lines.join("\n");
|
|
3003
3411
|
}
|
|
3004
|
-
function generatePermissionUpdate(collectionName, ruleType, newValue, varName) {
|
|
3412
|
+
function generatePermissionUpdate(collectionName, ruleType, newValue, varName, isLast = false) {
|
|
3005
3413
|
const lines = [];
|
|
3006
3414
|
const collectionVar = varName || `collection_${collectionName}_${ruleType}`;
|
|
3007
3415
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
3008
3416
|
lines.push(` ${collectionVar}.${ruleType} = ${formatValue(newValue)};`);
|
|
3009
|
-
lines.push(` app.save(${collectionVar});`);
|
|
3417
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
3010
3418
|
return lines.join("\n");
|
|
3011
3419
|
}
|
|
3012
|
-
function generateCollectionDeletion(collectionName, varName = "collection") {
|
|
3420
|
+
function generateCollectionDeletion(collectionName, varName = "collection", isLast = false) {
|
|
3013
3421
|
const lines = [];
|
|
3014
3422
|
lines.push(` const ${varName} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
3015
|
-
lines.push(` app.delete(${varName});`);
|
|
3423
|
+
lines.push(isLast ? ` return app.delete(${varName});` : ` app.delete(${varName});`);
|
|
3016
3424
|
return lines.join("\n");
|
|
3017
3425
|
}
|
|
3018
3426
|
function generateUpMigration(diff) {
|
|
@@ -3104,7 +3512,24 @@ function generateUpMigration(diff) {
|
|
|
3104
3512
|
lines.push(` // No changes detected`);
|
|
3105
3513
|
lines.push(``);
|
|
3106
3514
|
}
|
|
3107
|
-
|
|
3515
|
+
let code = lines.join("\n");
|
|
3516
|
+
const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
|
|
3517
|
+
const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
|
|
3518
|
+
const saveMatches = [...code.matchAll(savePattern)];
|
|
3519
|
+
const deleteMatches = [...code.matchAll(deletePattern)];
|
|
3520
|
+
const allMatches = [
|
|
3521
|
+
...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
|
|
3522
|
+
...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
|
|
3523
|
+
].sort((a, b) => b.index - a.index);
|
|
3524
|
+
if (allMatches.length > 0) {
|
|
3525
|
+
const lastMatch = allMatches[0];
|
|
3526
|
+
if (lastMatch.type === "save") {
|
|
3527
|
+
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);
|
|
3528
|
+
} else {
|
|
3529
|
+
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);
|
|
3530
|
+
}
|
|
3531
|
+
}
|
|
3532
|
+
return code;
|
|
3108
3533
|
}
|
|
3109
3534
|
function generateDownMigration(diff) {
|
|
3110
3535
|
const lines = [];
|
|
@@ -3206,7 +3631,24 @@ function generateDownMigration(diff) {
|
|
|
3206
3631
|
lines.push(` // No changes to revert`);
|
|
3207
3632
|
lines.push(``);
|
|
3208
3633
|
}
|
|
3209
|
-
|
|
3634
|
+
let code = lines.join("\n");
|
|
3635
|
+
const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
|
|
3636
|
+
const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
|
|
3637
|
+
const saveMatches = [...code.matchAll(savePattern)];
|
|
3638
|
+
const deleteMatches = [...code.matchAll(deletePattern)];
|
|
3639
|
+
const allMatches = [
|
|
3640
|
+
...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
|
|
3641
|
+
...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
|
|
3642
|
+
].sort((a, b) => b.index - a.index);
|
|
3643
|
+
if (allMatches.length > 0) {
|
|
3644
|
+
const lastMatch = allMatches[0];
|
|
3645
|
+
if (lastMatch.type === "save") {
|
|
3646
|
+
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);
|
|
3647
|
+
} else {
|
|
3648
|
+
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);
|
|
3649
|
+
}
|
|
3650
|
+
}
|
|
3651
|
+
return code;
|
|
3210
3652
|
}
|
|
3211
3653
|
function generate(diff, config) {
|
|
3212
3654
|
const normalizedConfig = typeof config === "string" ? { migrationDir: config } : config;
|
|
@@ -3260,6 +3702,6 @@ var MigrationGenerator = class {
|
|
|
3260
3702
|
}
|
|
3261
3703
|
};
|
|
3262
3704
|
|
|
3263
|
-
export { CLIUsageError, ConfigurationError, DiffEngine, FIELD_TYPE_INFO, FileSystemError, MigrationError, MigrationGenerationError, MigrationGenerator, POCKETBASE_FIELD_TYPES, SchemaAnalyzer, SchemaParsingError, SnapshotError, SnapshotManager, aggregateChanges, buildFieldDefinition, buildSchemaDefinition, categorizeChangesBySeverity, compare, compareFieldConstraints, compareFieldOptions, compareFieldTypes, comparePermissions, compareRelationConfigurations, convertPocketBaseMigration, convertZodSchemaToCollectionSchema, createMigrationFileStructure, detectDestructiveChanges, detectFieldChanges, discoverSchemaFiles, extractComprehensiveFieldOptions, extractFieldDefinitions, extractFieldOptions, extractIndexes, extractSchemaDefinitions, filterSystemCollections, findLatestSnapshot, findNewCollections, findNewFields, findRemovedCollections, findRemovedFields, generate, generateChangeSummary, generateCollectionCreation, generateCollectionPermissions, generateCollectionRules, generateDownMigration, generateFieldAddition, generateFieldDefinitionObject, generateFieldDeletion, generateFieldModification, generateFieldsArray, generateIndexesArray, generateMigrationDescription, generateMigrationFilename, generatePermissionUpdate, generateTimestamp, generateUpMigration, getArrayElementType, getCollectionNameFromFile, getDefaultValue, getFieldTypeInfo, getMaxSelect, getMinSelect, getSnapshotPath, getSnapshotVersion, getUsersSystemFields, importSchemaModule, isArrayType, isAuthCollection, isEditorField, isFieldRequired, isFileFieldByName, isGeoPointType, isMultipleRelationField, isRelationField, isSingleRelationField, isSystemCollection, loadBaseMigration, loadSnapshot, loadSnapshotIfExists, mapZodArrayType, mapZodBooleanType, mapZodDateType, mapZodEnumType, mapZodNumberType, mapZodRecordType, mapZodStringType, mapZodTypeToPocketBase, matchCollectionsByName, matchFieldsByName, mergeSnapshots, parseSchemaFiles, pluralize, requiresForceFlag, resolveTargetCollection, saveSnapshot, selectSchemaForCollection, singularize, snapshotExists, toCollectionName, unwrapZodType, validateSnapshot, writeMigrationFile };
|
|
3705
|
+
export { CLIUsageError, ConfigurationError, DiffEngine, FIELD_TYPE_INFO, FileSystemError, MigrationError, MigrationGenerationError, MigrationGenerator, POCKETBASE_FIELD_TYPES, SchemaAnalyzer, SchemaParsingError, SnapshotError, SnapshotManager, aggregateChanges, buildFieldDefinition, buildSchemaDefinition, categorizeChangesBySeverity, compare, compareFieldConstraints, compareFieldOptions, compareFieldTypes, comparePermissions, compareRelationConfigurations, convertPocketBaseMigration, convertZodSchemaToCollectionSchema, createMigrationFileStructure, detectDestructiveChanges, detectFieldChanges, discoverSchemaFiles, extractComprehensiveFieldOptions, extractFieldDefinitions, extractFieldOptions, extractIndexes, extractSchemaDefinitions, filterSystemCollections, findLatestSnapshot, findNewCollections, findNewFields, findRemovedCollections, findRemovedFields, generate, generateChangeSummary, generateCollectionCreation, generateCollectionPermissions, generateCollectionRules, generateDownMigration, generateFieldAddition, generateFieldDefinitionObject, generateFieldDeletion, generateFieldModification, generateFieldsArray, generateIndexesArray, generateMigrationDescription, generateMigrationFilename, generatePermissionUpdate, generateTimestamp, generateUpMigration, getArrayElementType, getCollectionNameFromFile, getDefaultValue, getFieldTypeInfo, getMaxSelect, getMinSelect, getSnapshotPath, getSnapshotVersion, getUsersSystemFields, importSchemaModule, isArrayType, isAuthCollection, isEditorField, isFieldRequired, isFileFieldByName, isGeoPointType, isMultipleRelationField, isRelationField, isSingleRelationField, isSystemCollection, loadBaseMigration, loadSnapshot, loadSnapshotIfExists, loadSnapshotWithMigrations, mapZodArrayType, mapZodBooleanType, mapZodDateType, mapZodEnumType, mapZodNumberType, mapZodRecordType, mapZodStringType, mapZodTypeToPocketBase, matchCollectionsByName, matchFieldsByName, mergeSnapshots, parseSchemaFiles, pluralize, requiresForceFlag, resolveTargetCollection, saveSnapshot, selectSchemaForCollection, singularize, snapshotExists, toCollectionName, unwrapZodType, validateSnapshot, writeMigrationFile };
|
|
3264
3706
|
//# sourceMappingURL=index.js.map
|
|
3265
3707
|
//# sourceMappingURL=index.js.map
|