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/cli/migrate.cjs
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
var chalk = require('chalk');
|
|
5
5
|
var commander = require('commander');
|
|
6
|
-
var
|
|
7
|
-
var
|
|
6
|
+
var fs5 = require('fs');
|
|
7
|
+
var path5 = require('path');
|
|
8
|
+
var url = require('url');
|
|
8
9
|
var zod = require('zod');
|
|
9
10
|
var ora = require('ora');
|
|
10
11
|
|
|
@@ -29,10 +30,43 @@ function _interopNamespace(e) {
|
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
var chalk__default = /*#__PURE__*/_interopDefault(chalk);
|
|
32
|
-
var
|
|
33
|
-
var
|
|
33
|
+
var fs5__namespace = /*#__PURE__*/_interopNamespace(fs5);
|
|
34
|
+
var path5__namespace = /*#__PURE__*/_interopNamespace(path5);
|
|
34
35
|
var ora__default = /*#__PURE__*/_interopDefault(ora);
|
|
35
36
|
|
|
37
|
+
// ../node_modules/tsup/assets/cjs_shims.js
|
|
38
|
+
var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
|
|
39
|
+
var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
40
|
+
({
|
|
41
|
+
id: zod.z.string().describe("unique id"),
|
|
42
|
+
collectionId: zod.z.string().describe("collection id"),
|
|
43
|
+
collectionName: zod.z.string().describe("collection name"),
|
|
44
|
+
expand: zod.z.record(zod.z.any()).describe("expandable fields")
|
|
45
|
+
});
|
|
46
|
+
({
|
|
47
|
+
created: zod.z.string().describe("creation timestamp"),
|
|
48
|
+
updated: zod.z.string().describe("last update timestamp")
|
|
49
|
+
});
|
|
50
|
+
({
|
|
51
|
+
thumbnailURL: zod.z.string().optional(),
|
|
52
|
+
imageFiles: zod.z.array(zod.z.string())
|
|
53
|
+
});
|
|
54
|
+
({
|
|
55
|
+
imageFiles: zod.z.array(zod.z.instanceof(File))
|
|
56
|
+
});
|
|
57
|
+
var RELATION_METADATA_KEY = "__pocketbase_relation__";
|
|
58
|
+
function extractRelationMetadata(description) {
|
|
59
|
+
if (!description) return null;
|
|
60
|
+
try {
|
|
61
|
+
const parsed = JSON.parse(description);
|
|
62
|
+
if (parsed[RELATION_METADATA_KEY]) {
|
|
63
|
+
return parsed[RELATION_METADATA_KEY];
|
|
64
|
+
}
|
|
65
|
+
} catch {
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
|
|
36
70
|
// src/migration/errors.ts
|
|
37
71
|
var MigrationError = class _MigrationError extends Error {
|
|
38
72
|
constructor(message) {
|
|
@@ -130,10 +164,10 @@ var FileSystemError = class _FileSystemError extends MigrationError {
|
|
|
130
164
|
operation;
|
|
131
165
|
code;
|
|
132
166
|
originalError;
|
|
133
|
-
constructor(message,
|
|
167
|
+
constructor(message, path7, operation, code, originalError) {
|
|
134
168
|
super(message);
|
|
135
169
|
this.name = "FileSystemError";
|
|
136
|
-
this.path =
|
|
170
|
+
this.path = path7;
|
|
137
171
|
this.operation = operation;
|
|
138
172
|
this.code = code;
|
|
139
173
|
this.originalError = originalError;
|
|
@@ -196,7 +230,7 @@ Cause: ${this.originalError.message}`);
|
|
|
196
230
|
}
|
|
197
231
|
};
|
|
198
232
|
|
|
199
|
-
// src/
|
|
233
|
+
// src/utils/permission-templates.ts
|
|
200
234
|
var PermissionTemplates = {
|
|
201
235
|
/**
|
|
202
236
|
* Public access - anyone can perform all operations
|
|
@@ -855,26 +889,28 @@ function getMaxSelect(fieldName, zodType) {
|
|
|
855
889
|
return 1;
|
|
856
890
|
}
|
|
857
891
|
function getMinSelect(fieldName, zodType) {
|
|
858
|
-
if (
|
|
859
|
-
return
|
|
860
|
-
}
|
|
861
|
-
let unwrappedType = zodType;
|
|
862
|
-
if (zodType instanceof zod.z.ZodOptional) {
|
|
863
|
-
unwrappedType = zodType._def.innerType;
|
|
864
|
-
}
|
|
865
|
-
if (unwrappedType instanceof zod.z.ZodNullable) {
|
|
866
|
-
unwrappedType = unwrappedType._def.innerType;
|
|
867
|
-
}
|
|
868
|
-
if (unwrappedType instanceof zod.z.ZodDefault) {
|
|
869
|
-
unwrappedType = unwrappedType._def.innerType;
|
|
892
|
+
if (isSingleRelationField(fieldName, zodType)) {
|
|
893
|
+
return 0;
|
|
870
894
|
}
|
|
871
|
-
if (
|
|
872
|
-
|
|
873
|
-
if (
|
|
874
|
-
|
|
895
|
+
if (isMultipleRelationField(fieldName, zodType)) {
|
|
896
|
+
let unwrappedType = zodType;
|
|
897
|
+
if (zodType instanceof zod.z.ZodOptional) {
|
|
898
|
+
unwrappedType = zodType._def.innerType;
|
|
899
|
+
}
|
|
900
|
+
if (unwrappedType instanceof zod.z.ZodNullable) {
|
|
901
|
+
unwrappedType = unwrappedType._def.innerType;
|
|
902
|
+
}
|
|
903
|
+
if (unwrappedType instanceof zod.z.ZodDefault) {
|
|
904
|
+
unwrappedType = unwrappedType._def.innerType;
|
|
905
|
+
}
|
|
906
|
+
if (unwrappedType instanceof zod.z.ZodArray) {
|
|
907
|
+
const arrayDef = unwrappedType._def;
|
|
908
|
+
if (arrayDef.minLength) {
|
|
909
|
+
return arrayDef.minLength.value;
|
|
910
|
+
}
|
|
875
911
|
}
|
|
876
912
|
}
|
|
877
|
-
return
|
|
913
|
+
return 0;
|
|
878
914
|
}
|
|
879
915
|
function mapZodStringType(zodType) {
|
|
880
916
|
const checks = zodType._def.checks || [];
|
|
@@ -1072,20 +1108,20 @@ function mergeConfig(config) {
|
|
|
1072
1108
|
}
|
|
1073
1109
|
function resolveSchemaDir(config) {
|
|
1074
1110
|
const workspaceRoot = config.workspaceRoot || process.cwd();
|
|
1075
|
-
if (
|
|
1111
|
+
if (path5__namespace.isAbsolute(config.schemaDir)) {
|
|
1076
1112
|
return config.schemaDir;
|
|
1077
1113
|
}
|
|
1078
|
-
return
|
|
1114
|
+
return path5__namespace.join(workspaceRoot, config.schemaDir);
|
|
1079
1115
|
}
|
|
1080
1116
|
function discoverSchemaFiles(config) {
|
|
1081
1117
|
const normalizedConfig = typeof config === "string" ? { schemaDir: config } : config;
|
|
1082
1118
|
const mergedConfig = mergeConfig(normalizedConfig);
|
|
1083
1119
|
const schemaDir = resolveSchemaDir(normalizedConfig);
|
|
1084
1120
|
try {
|
|
1085
|
-
if (!
|
|
1121
|
+
if (!fs5__namespace.existsSync(schemaDir)) {
|
|
1086
1122
|
throw new FileSystemError(`Schema directory not found: ${schemaDir}`, schemaDir, "access", "ENOENT");
|
|
1087
1123
|
}
|
|
1088
|
-
const files =
|
|
1124
|
+
const files = fs5__namespace.readdirSync(schemaDir);
|
|
1089
1125
|
const schemaFiles = files.filter((file) => {
|
|
1090
1126
|
const hasValidExtension = mergedConfig.includeExtensions.some((ext) => file.endsWith(ext));
|
|
1091
1127
|
if (!hasValidExtension) return false;
|
|
@@ -1101,7 +1137,7 @@ function discoverSchemaFiles(config) {
|
|
|
1101
1137
|
});
|
|
1102
1138
|
return schemaFiles.map((file) => {
|
|
1103
1139
|
const ext = mergedConfig.includeExtensions.find((ext2) => file.endsWith(ext2)) || ".ts";
|
|
1104
|
-
return
|
|
1140
|
+
return path5__namespace.join(schemaDir, file.replace(new RegExp(`\\${ext}$`), ""));
|
|
1105
1141
|
});
|
|
1106
1142
|
} catch (error) {
|
|
1107
1143
|
if (error instanceof FileSystemError) {
|
|
@@ -1132,13 +1168,32 @@ async function importSchemaModule(filePath, config) {
|
|
|
1132
1168
|
if (config?.pathTransformer) {
|
|
1133
1169
|
importPath = config.pathTransformer(filePath);
|
|
1134
1170
|
}
|
|
1135
|
-
|
|
1136
|
-
|
|
1171
|
+
let resolvedPath = null;
|
|
1172
|
+
const jsPath = `${importPath}.js`;
|
|
1173
|
+
const tsPath = `${importPath}.ts`;
|
|
1174
|
+
if (fs5__namespace.existsSync(jsPath)) {
|
|
1175
|
+
resolvedPath = jsPath;
|
|
1176
|
+
} else if (fs5__namespace.existsSync(tsPath)) {
|
|
1177
|
+
resolvedPath = tsPath;
|
|
1178
|
+
} else {
|
|
1179
|
+
resolvedPath = jsPath;
|
|
1137
1180
|
}
|
|
1138
|
-
const fileUrl = new URL(`file://${
|
|
1181
|
+
const fileUrl = new URL(`file://${path5__namespace.resolve(resolvedPath)}`);
|
|
1139
1182
|
const module = await import(fileUrl.href);
|
|
1140
1183
|
return module;
|
|
1141
1184
|
} catch (error) {
|
|
1185
|
+
const tsPath = `${filePath}.ts`;
|
|
1186
|
+
const isTypeScriptFile = fs5__namespace.existsSync(tsPath);
|
|
1187
|
+
if (isTypeScriptFile) {
|
|
1188
|
+
throw new SchemaParsingError(
|
|
1189
|
+
`Failed to import TypeScript schema file. Node.js cannot import TypeScript files directly.
|
|
1190
|
+
Please either:
|
|
1191
|
+
1. Compile your schema files to JavaScript first, or
|
|
1192
|
+
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")`,
|
|
1193
|
+
filePath,
|
|
1194
|
+
error
|
|
1195
|
+
);
|
|
1196
|
+
}
|
|
1142
1197
|
throw new SchemaParsingError(
|
|
1143
1198
|
`Failed to import schema module. Make sure the schema files are compiled to JavaScript.`,
|
|
1144
1199
|
filePath,
|
|
@@ -1147,7 +1202,7 @@ async function importSchemaModule(filePath, config) {
|
|
|
1147
1202
|
}
|
|
1148
1203
|
}
|
|
1149
1204
|
function getCollectionNameFromFile(filePath) {
|
|
1150
|
-
const filename =
|
|
1205
|
+
const filename = path5__namespace.basename(filePath).replace(/\.(ts|js)$/, "");
|
|
1151
1206
|
return toCollectionName(filename);
|
|
1152
1207
|
}
|
|
1153
1208
|
function extractSchemaDefinitions(module, patterns = ["Schema", "InputSchema"]) {
|
|
@@ -1201,7 +1256,17 @@ function buildFieldDefinition(fieldName, zodType) {
|
|
|
1201
1256
|
required,
|
|
1202
1257
|
options
|
|
1203
1258
|
};
|
|
1204
|
-
|
|
1259
|
+
const relationMetadata = extractRelationMetadata(zodType.description);
|
|
1260
|
+
if (relationMetadata) {
|
|
1261
|
+
fieldDef.type = "relation";
|
|
1262
|
+
fieldDef.relation = {
|
|
1263
|
+
collection: relationMetadata.collection,
|
|
1264
|
+
maxSelect: relationMetadata.maxSelect,
|
|
1265
|
+
minSelect: relationMetadata.minSelect,
|
|
1266
|
+
cascadeDelete: relationMetadata.cascadeDelete
|
|
1267
|
+
};
|
|
1268
|
+
fieldDef.options = void 0;
|
|
1269
|
+
} else if (isRelationField(fieldName, zodType)) {
|
|
1205
1270
|
fieldDef.type = "relation";
|
|
1206
1271
|
const targetCollection = resolveTargetCollection(fieldName);
|
|
1207
1272
|
const maxSelect = getMaxSelect(fieldName, zodType);
|
|
@@ -1213,6 +1278,13 @@ function buildFieldDefinition(fieldName, zodType) {
|
|
|
1213
1278
|
cascadeDelete: false
|
|
1214
1279
|
// Default to false, can be configured later
|
|
1215
1280
|
};
|
|
1281
|
+
if (fieldDef.options) {
|
|
1282
|
+
const { min, max, pattern, ...relationSafeOptions } = fieldDef.options;
|
|
1283
|
+
console.log("min", min);
|
|
1284
|
+
console.log("max", max);
|
|
1285
|
+
console.log("pattern", pattern);
|
|
1286
|
+
fieldDef.options = Object.keys(relationSafeOptions).length > 0 ? relationSafeOptions : void 0;
|
|
1287
|
+
}
|
|
1216
1288
|
}
|
|
1217
1289
|
return fieldDef;
|
|
1218
1290
|
}
|
|
@@ -1265,11 +1337,12 @@ function convertZodSchemaToCollectionSchema(collectionName, zodSchema) {
|
|
|
1265
1337
|
fields,
|
|
1266
1338
|
indexes,
|
|
1267
1339
|
rules: {
|
|
1268
|
-
listRule: null,
|
|
1269
|
-
viewRule: null,
|
|
1270
|
-
createRule: null,
|
|
1271
|
-
updateRule: null,
|
|
1272
|
-
deleteRule: null
|
|
1340
|
+
listRule: permissions?.listRule ?? null,
|
|
1341
|
+
viewRule: permissions?.viewRule ?? null,
|
|
1342
|
+
createRule: permissions?.createRule ?? null,
|
|
1343
|
+
updateRule: permissions?.updateRule ?? null,
|
|
1344
|
+
deleteRule: permissions?.deleteRule ?? null,
|
|
1345
|
+
manageRule: permissions?.manageRule ?? null
|
|
1273
1346
|
},
|
|
1274
1347
|
permissions
|
|
1275
1348
|
};
|
|
@@ -1293,7 +1366,12 @@ async function buildSchemaDefinition(config) {
|
|
|
1293
1366
|
if (normalizedConfig.pathTransformer) {
|
|
1294
1367
|
importPath = normalizedConfig.pathTransformer(filePath);
|
|
1295
1368
|
} else if (mergedConfig.useCompiledFiles) {
|
|
1296
|
-
|
|
1369
|
+
const distPath = filePath.replace(/\/src\//, "/dist/");
|
|
1370
|
+
if (fs5__namespace.existsSync(`${distPath}.js`) || fs5__namespace.existsSync(`${distPath}.mjs`)) {
|
|
1371
|
+
importPath = distPath;
|
|
1372
|
+
} else {
|
|
1373
|
+
importPath = filePath;
|
|
1374
|
+
}
|
|
1297
1375
|
}
|
|
1298
1376
|
const module = await importSchemaModule(importPath, normalizedConfig);
|
|
1299
1377
|
const schemas = extractSchemaDefinitions(module, mergedConfig.schemaPatterns);
|
|
@@ -1466,6 +1544,9 @@ function compareFieldOptions(currentField, previousField) {
|
|
|
1466
1544
|
for (const key of allKeys) {
|
|
1467
1545
|
const currentValue = currentOptions[key];
|
|
1468
1546
|
const previousValue = previousOptions[key];
|
|
1547
|
+
if (currentValue === void 0 && previousValue === void 0) {
|
|
1548
|
+
continue;
|
|
1549
|
+
}
|
|
1469
1550
|
if (!areValuesEqual(currentValue, previousValue)) {
|
|
1470
1551
|
changes.push({
|
|
1471
1552
|
property: `options.${key}`,
|
|
@@ -1486,11 +1567,26 @@ function compareRelationConfigurations(currentField, previousField) {
|
|
|
1486
1567
|
if (!currentRelation || !previousRelation) {
|
|
1487
1568
|
return changes;
|
|
1488
1569
|
}
|
|
1489
|
-
|
|
1570
|
+
const normalizeCollection = (collection) => {
|
|
1571
|
+
if (!collection) return collection;
|
|
1572
|
+
if (collection === "_pb_users_auth_") {
|
|
1573
|
+
return "Users";
|
|
1574
|
+
}
|
|
1575
|
+
const nameMatch = collection.match(/app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\)/);
|
|
1576
|
+
if (nameMatch) {
|
|
1577
|
+
return nameMatch[1];
|
|
1578
|
+
}
|
|
1579
|
+
return collection;
|
|
1580
|
+
};
|
|
1581
|
+
const normalizedCurrent = normalizeCollection(currentRelation.collection);
|
|
1582
|
+
const normalizedPrevious = normalizeCollection(previousRelation.collection);
|
|
1583
|
+
if (normalizedCurrent !== normalizedPrevious) {
|
|
1490
1584
|
changes.push({
|
|
1491
1585
|
property: "relation.collection",
|
|
1492
|
-
oldValue:
|
|
1493
|
-
|
|
1586
|
+
oldValue: normalizedPrevious,
|
|
1587
|
+
// Use normalized value for clarity
|
|
1588
|
+
newValue: normalizedCurrent
|
|
1589
|
+
// Use normalized value for clarity
|
|
1494
1590
|
});
|
|
1495
1591
|
}
|
|
1496
1592
|
if (currentRelation.cascadeDelete !== previousRelation.cascadeDelete) {
|
|
@@ -1691,10 +1787,8 @@ function compare(currentSchema, previousSnapshot, config) {
|
|
|
1691
1787
|
var DEFAULT_TEMPLATE = `/// <reference path="{{TYPES_PATH}}" />
|
|
1692
1788
|
migrate((app) => {
|
|
1693
1789
|
{{UP_CODE}}
|
|
1694
|
-
return true;
|
|
1695
1790
|
}, (app) => {
|
|
1696
1791
|
{{DOWN_CODE}}
|
|
1697
|
-
return true;
|
|
1698
1792
|
});
|
|
1699
1793
|
`;
|
|
1700
1794
|
var DEFAULT_CONFIG3 = {
|
|
@@ -1712,10 +1806,10 @@ function mergeConfig3(config) {
|
|
|
1712
1806
|
}
|
|
1713
1807
|
function resolveMigrationDir(config) {
|
|
1714
1808
|
const workspaceRoot = config.workspaceRoot || process.cwd();
|
|
1715
|
-
if (
|
|
1809
|
+
if (path5__namespace.isAbsolute(config.migrationDir)) {
|
|
1716
1810
|
return config.migrationDir;
|
|
1717
1811
|
}
|
|
1718
|
-
return
|
|
1812
|
+
return path5__namespace.join(workspaceRoot, config.migrationDir);
|
|
1719
1813
|
}
|
|
1720
1814
|
function generateTimestamp(config) {
|
|
1721
1815
|
if (config?.timestampGenerator) {
|
|
@@ -1773,9 +1867,9 @@ function createMigrationFileStructure(upCode, downCode, config) {
|
|
|
1773
1867
|
}
|
|
1774
1868
|
function writeMigrationFile(migrationDir, filename, content) {
|
|
1775
1869
|
try {
|
|
1776
|
-
if (!
|
|
1870
|
+
if (!fs5__namespace.existsSync(migrationDir)) {
|
|
1777
1871
|
try {
|
|
1778
|
-
|
|
1872
|
+
fs5__namespace.mkdirSync(migrationDir, { recursive: true });
|
|
1779
1873
|
} catch (error) {
|
|
1780
1874
|
const fsError = error;
|
|
1781
1875
|
if (fsError.code === "EACCES" || fsError.code === "EPERM") {
|
|
@@ -1796,15 +1890,15 @@ function writeMigrationFile(migrationDir, filename, content) {
|
|
|
1796
1890
|
);
|
|
1797
1891
|
}
|
|
1798
1892
|
}
|
|
1799
|
-
const filePath =
|
|
1800
|
-
|
|
1893
|
+
const filePath = path5__namespace.join(migrationDir, filename);
|
|
1894
|
+
fs5__namespace.writeFileSync(filePath, content, "utf-8");
|
|
1801
1895
|
return filePath;
|
|
1802
1896
|
} catch (error) {
|
|
1803
1897
|
if (error instanceof FileSystemError) {
|
|
1804
1898
|
throw error;
|
|
1805
1899
|
}
|
|
1806
1900
|
const fsError = error;
|
|
1807
|
-
const filePath =
|
|
1901
|
+
const filePath = path5__namespace.join(migrationDir, filename);
|
|
1808
1902
|
if (fsError.code === "EACCES" || fsError.code === "EPERM") {
|
|
1809
1903
|
throw new FileSystemError(
|
|
1810
1904
|
`Permission denied writing migration file. Check file and directory permissions.`,
|
|
@@ -1859,7 +1953,8 @@ function generateFieldDefinitionObject(field) {
|
|
|
1859
1953
|
}
|
|
1860
1954
|
}
|
|
1861
1955
|
if (field.relation) {
|
|
1862
|
-
const
|
|
1956
|
+
const isUsersCollection = field.relation.collection.toLowerCase() === "users";
|
|
1957
|
+
const collectionIdPlaceholder = isUsersCollection ? '"_pb_users_auth_"' : `app.findCollectionByNameOrId("${field.relation.collection}").id`;
|
|
1863
1958
|
parts.push(` collectionId: ${collectionIdPlaceholder}`);
|
|
1864
1959
|
if (field.relation.maxSelect !== void 0) {
|
|
1865
1960
|
parts.push(` maxSelect: ${field.relation.maxSelect}`);
|
|
@@ -1943,7 +2038,7 @@ function generateIndexesArray(indexes) {
|
|
|
1943
2038
|
${indexStrings.join(",\n ")},
|
|
1944
2039
|
]`;
|
|
1945
2040
|
}
|
|
1946
|
-
function generateCollectionCreation(collection, varName = "collection") {
|
|
2041
|
+
function generateCollectionCreation(collection, varName = "collection", isLast = false) {
|
|
1947
2042
|
const lines = [];
|
|
1948
2043
|
lines.push(` const ${varName} = new Collection({`);
|
|
1949
2044
|
lines.push(` name: "${collection.name}",`);
|
|
@@ -1959,7 +2054,7 @@ function generateCollectionCreation(collection, varName = "collection") {
|
|
|
1959
2054
|
lines.push(` indexes: ${generateIndexesArray(collection.indexes)},`);
|
|
1960
2055
|
lines.push(` });`);
|
|
1961
2056
|
lines.push(``);
|
|
1962
|
-
lines.push(` app.save(${varName});`);
|
|
2057
|
+
lines.push(isLast ? ` return app.save(${varName});` : ` app.save(${varName});`);
|
|
1963
2058
|
return lines.join("\n");
|
|
1964
2059
|
}
|
|
1965
2060
|
function getFieldConstructorName(fieldType) {
|
|
@@ -1990,7 +2085,8 @@ function generateFieldConstructorOptions(field) {
|
|
|
1990
2085
|
}
|
|
1991
2086
|
}
|
|
1992
2087
|
if (field.relation && field.type === "relation") {
|
|
1993
|
-
const
|
|
2088
|
+
const isUsersCollection = field.relation.collection.toLowerCase() === "users";
|
|
2089
|
+
const collectionIdPlaceholder = isUsersCollection ? '"_pb_users_auth_"' : `app.findCollectionByNameOrId("${field.relation.collection}").id`;
|
|
1994
2090
|
parts.push(` collectionId: ${collectionIdPlaceholder}`);
|
|
1995
2091
|
if (field.relation.maxSelect !== void 0) {
|
|
1996
2092
|
parts.push(` maxSelect: ${field.relation.maxSelect}`);
|
|
@@ -2004,7 +2100,7 @@ function generateFieldConstructorOptions(field) {
|
|
|
2004
2100
|
}
|
|
2005
2101
|
return parts.join(",\n");
|
|
2006
2102
|
}
|
|
2007
|
-
function generateFieldAddition(collectionName, field, varName) {
|
|
2103
|
+
function generateFieldAddition(collectionName, field, varName, isLast = false) {
|
|
2008
2104
|
const lines = [];
|
|
2009
2105
|
const constructorName = getFieldConstructorName(field.type);
|
|
2010
2106
|
const collectionVar = varName || `collection_${collectionName}_${field.name}`;
|
|
@@ -2014,10 +2110,10 @@ function generateFieldAddition(collectionName, field, varName) {
|
|
|
2014
2110
|
lines.push(generateFieldConstructorOptions(field));
|
|
2015
2111
|
lines.push(` }));`);
|
|
2016
2112
|
lines.push(``);
|
|
2017
|
-
lines.push(` app.save(${collectionVar});`);
|
|
2113
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
2018
2114
|
return lines.join("\n");
|
|
2019
2115
|
}
|
|
2020
|
-
function generateFieldModification(collectionName, modification, varName) {
|
|
2116
|
+
function generateFieldModification(collectionName, modification, varName, isLast = false) {
|
|
2021
2117
|
const lines = [];
|
|
2022
2118
|
const collectionVar = varName || `collection_${collectionName}_${modification.fieldName}`;
|
|
2023
2119
|
const fieldVar = `${collectionVar}_field`;
|
|
@@ -2031,7 +2127,8 @@ function generateFieldModification(collectionName, modification, varName) {
|
|
|
2031
2127
|
} else if (change.property.startsWith("relation.")) {
|
|
2032
2128
|
const relationKey = change.property.replace("relation.", "");
|
|
2033
2129
|
if (relationKey === "collection") {
|
|
2034
|
-
const
|
|
2130
|
+
const isUsersCollection = String(change.newValue).toLowerCase() === "users";
|
|
2131
|
+
const collectionIdValue = isUsersCollection ? '"_pb_users_auth_"' : `app.findCollectionByNameOrId("${change.newValue}").id`;
|
|
2035
2132
|
lines.push(` ${fieldVar}.collectionId = ${collectionIdValue};`);
|
|
2036
2133
|
} else {
|
|
2037
2134
|
lines.push(` ${fieldVar}.${relationKey} = ${formatValue(change.newValue)};`);
|
|
@@ -2041,10 +2138,10 @@ function generateFieldModification(collectionName, modification, varName) {
|
|
|
2041
2138
|
}
|
|
2042
2139
|
}
|
|
2043
2140
|
lines.push(``);
|
|
2044
|
-
lines.push(` app.save(${collectionVar});`);
|
|
2141
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
2045
2142
|
return lines.join("\n");
|
|
2046
2143
|
}
|
|
2047
|
-
function generateFieldDeletion(collectionName, fieldName, varName) {
|
|
2144
|
+
function generateFieldDeletion(collectionName, fieldName, varName, isLast = false) {
|
|
2048
2145
|
const lines = [];
|
|
2049
2146
|
const collectionVar = varName || `collection_${collectionName}_${fieldName}`;
|
|
2050
2147
|
const fieldVar = `${collectionVar}_field`;
|
|
@@ -2053,18 +2150,18 @@ function generateFieldDeletion(collectionName, fieldName, varName) {
|
|
|
2053
2150
|
lines.push(``);
|
|
2054
2151
|
lines.push(` ${collectionVar}.fields.remove(${fieldVar}.id);`);
|
|
2055
2152
|
lines.push(``);
|
|
2056
|
-
lines.push(` app.save(${collectionVar});`);
|
|
2153
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
2057
2154
|
return lines.join("\n");
|
|
2058
2155
|
}
|
|
2059
|
-
function generateIndexAddition(collectionName, index, varName) {
|
|
2156
|
+
function generateIndexAddition(collectionName, index, varName, isLast = false) {
|
|
2060
2157
|
const lines = [];
|
|
2061
2158
|
const collectionVar = varName || `collection_${collectionName}_idx`;
|
|
2062
2159
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
2063
2160
|
lines.push(` ${collectionVar}.indexes.push("${index}");`);
|
|
2064
|
-
lines.push(` app.save(${collectionVar});`);
|
|
2161
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
2065
2162
|
return lines.join("\n");
|
|
2066
2163
|
}
|
|
2067
|
-
function generateIndexRemoval(collectionName, index, varName) {
|
|
2164
|
+
function generateIndexRemoval(collectionName, index, varName, isLast = false) {
|
|
2068
2165
|
const lines = [];
|
|
2069
2166
|
const collectionVar = varName || `collection_${collectionName}_idx`;
|
|
2070
2167
|
const indexVar = `${collectionVar}_indexToRemove`;
|
|
@@ -2073,29 +2170,29 @@ function generateIndexRemoval(collectionName, index, varName) {
|
|
|
2073
2170
|
lines.push(` if (${indexVar} !== -1) {`);
|
|
2074
2171
|
lines.push(` ${collectionVar}.indexes.splice(${indexVar}, 1);`);
|
|
2075
2172
|
lines.push(` }`);
|
|
2076
|
-
lines.push(` app.save(${collectionVar});`);
|
|
2173
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
2077
2174
|
return lines.join("\n");
|
|
2078
2175
|
}
|
|
2079
|
-
function generateRuleUpdate(collectionName, ruleType, newValue, varName) {
|
|
2176
|
+
function generateRuleUpdate(collectionName, ruleType, newValue, varName, isLast = false) {
|
|
2080
2177
|
const lines = [];
|
|
2081
2178
|
const collectionVar = varName || `collection_${collectionName}_${ruleType}`;
|
|
2082
2179
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
2083
2180
|
lines.push(` ${collectionVar}.${ruleType} = ${formatValue(newValue)};`);
|
|
2084
|
-
lines.push(` app.save(${collectionVar});`);
|
|
2181
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
2085
2182
|
return lines.join("\n");
|
|
2086
2183
|
}
|
|
2087
|
-
function generatePermissionUpdate(collectionName, ruleType, newValue, varName) {
|
|
2184
|
+
function generatePermissionUpdate(collectionName, ruleType, newValue, varName, isLast = false) {
|
|
2088
2185
|
const lines = [];
|
|
2089
2186
|
const collectionVar = varName || `collection_${collectionName}_${ruleType}`;
|
|
2090
2187
|
lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
2091
2188
|
lines.push(` ${collectionVar}.${ruleType} = ${formatValue(newValue)};`);
|
|
2092
|
-
lines.push(` app.save(${collectionVar});`);
|
|
2189
|
+
lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
|
|
2093
2190
|
return lines.join("\n");
|
|
2094
2191
|
}
|
|
2095
|
-
function generateCollectionDeletion(collectionName, varName = "collection") {
|
|
2192
|
+
function generateCollectionDeletion(collectionName, varName = "collection", isLast = false) {
|
|
2096
2193
|
const lines = [];
|
|
2097
2194
|
lines.push(` const ${varName} = app.findCollectionByNameOrId("${collectionName}");`);
|
|
2098
|
-
lines.push(` app.delete(${varName});`);
|
|
2195
|
+
lines.push(isLast ? ` return app.delete(${varName});` : ` app.delete(${varName});`);
|
|
2099
2196
|
return lines.join("\n");
|
|
2100
2197
|
}
|
|
2101
2198
|
function generateUpMigration(diff) {
|
|
@@ -2187,7 +2284,24 @@ function generateUpMigration(diff) {
|
|
|
2187
2284
|
lines.push(` // No changes detected`);
|
|
2188
2285
|
lines.push(``);
|
|
2189
2286
|
}
|
|
2190
|
-
|
|
2287
|
+
let code = lines.join("\n");
|
|
2288
|
+
const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
|
|
2289
|
+
const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
|
|
2290
|
+
const saveMatches = [...code.matchAll(savePattern)];
|
|
2291
|
+
const deleteMatches = [...code.matchAll(deletePattern)];
|
|
2292
|
+
const allMatches = [
|
|
2293
|
+
...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
|
|
2294
|
+
...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
|
|
2295
|
+
].sort((a, b) => b.index - a.index);
|
|
2296
|
+
if (allMatches.length > 0) {
|
|
2297
|
+
const lastMatch = allMatches[0];
|
|
2298
|
+
if (lastMatch.type === "save") {
|
|
2299
|
+
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);
|
|
2300
|
+
} else {
|
|
2301
|
+
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);
|
|
2302
|
+
}
|
|
2303
|
+
}
|
|
2304
|
+
return code;
|
|
2191
2305
|
}
|
|
2192
2306
|
function generateDownMigration(diff) {
|
|
2193
2307
|
const lines = [];
|
|
@@ -2289,7 +2403,24 @@ function generateDownMigration(diff) {
|
|
|
2289
2403
|
lines.push(` // No changes to revert`);
|
|
2290
2404
|
lines.push(``);
|
|
2291
2405
|
}
|
|
2292
|
-
|
|
2406
|
+
let code = lines.join("\n");
|
|
2407
|
+
const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
|
|
2408
|
+
const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
|
|
2409
|
+
const saveMatches = [...code.matchAll(savePattern)];
|
|
2410
|
+
const deleteMatches = [...code.matchAll(deletePattern)];
|
|
2411
|
+
const allMatches = [
|
|
2412
|
+
...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
|
|
2413
|
+
...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
|
|
2414
|
+
].sort((a, b) => b.index - a.index);
|
|
2415
|
+
if (allMatches.length > 0) {
|
|
2416
|
+
const lastMatch = allMatches[0];
|
|
2417
|
+
if (lastMatch.type === "save") {
|
|
2418
|
+
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);
|
|
2419
|
+
} else {
|
|
2420
|
+
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);
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2423
|
+
return code;
|
|
2293
2424
|
}
|
|
2294
2425
|
function generate(diff, config) {
|
|
2295
2426
|
const normalizedConfig = typeof config === "string" ? { migrationDir: config } : config;
|
|
@@ -2312,57 +2443,18 @@ function generate(diff, config) {
|
|
|
2312
2443
|
);
|
|
2313
2444
|
}
|
|
2314
2445
|
}
|
|
2446
|
+
|
|
2447
|
+
// src/migration/pocketbase-converter.ts
|
|
2315
2448
|
var SNAPSHOT_VERSION = "1.0.0";
|
|
2316
|
-
({
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
try {
|
|
2320
|
-
if (!fs4__namespace.existsSync(migrationsPath)) {
|
|
2321
|
-
return null;
|
|
2322
|
-
}
|
|
2323
|
-
const files = fs4__namespace.readdirSync(migrationsPath);
|
|
2324
|
-
const snapshotFiles = files.filter(
|
|
2325
|
-
(file) => file.endsWith("_collections_snapshot.js") || file.endsWith("_snapshot.js")
|
|
2326
|
-
);
|
|
2327
|
-
if (snapshotFiles.length === 0) {
|
|
2328
|
-
return null;
|
|
2329
|
-
}
|
|
2330
|
-
snapshotFiles.sort().reverse();
|
|
2331
|
-
const latestSnapshot = snapshotFiles[0];
|
|
2332
|
-
if (!latestSnapshot) {
|
|
2333
|
-
return null;
|
|
2334
|
-
}
|
|
2335
|
-
return path4__namespace.join(migrationsPath, latestSnapshot);
|
|
2336
|
-
} catch (error) {
|
|
2337
|
-
console.warn(`Error finding latest snapshot: ${error}`);
|
|
2338
|
-
return null;
|
|
2449
|
+
function resolveCollectionIdToName(collectionId) {
|
|
2450
|
+
if (collectionId === "_pb_users_auth_") {
|
|
2451
|
+
return "Users";
|
|
2339
2452
|
}
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
if (!migrationsPath) {
|
|
2344
|
-
return null;
|
|
2453
|
+
const nameMatch = collectionId.match(/app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\)/);
|
|
2454
|
+
if (nameMatch) {
|
|
2455
|
+
return nameMatch[1];
|
|
2345
2456
|
}
|
|
2346
|
-
|
|
2347
|
-
try {
|
|
2348
|
-
const migrationContent = fs4__namespace.readFileSync(migrationsPath, "utf-8");
|
|
2349
|
-
return convertPocketBaseMigration(migrationContent);
|
|
2350
|
-
} catch (error) {
|
|
2351
|
-
console.warn(`Failed to load snapshot from ${migrationsPath}: ${error}`);
|
|
2352
|
-
return null;
|
|
2353
|
-
}
|
|
2354
|
-
}
|
|
2355
|
-
const latestSnapshotPath = findLatestSnapshot(migrationsPath);
|
|
2356
|
-
if (latestSnapshotPath) {
|
|
2357
|
-
try {
|
|
2358
|
-
const migrationContent = fs4__namespace.readFileSync(latestSnapshotPath, "utf-8");
|
|
2359
|
-
return convertPocketBaseMigration(migrationContent);
|
|
2360
|
-
} catch (error) {
|
|
2361
|
-
console.warn(`Failed to load snapshot from ${latestSnapshotPath}: ${error}`);
|
|
2362
|
-
return null;
|
|
2363
|
-
}
|
|
2364
|
-
}
|
|
2365
|
-
return null;
|
|
2457
|
+
return collectionId;
|
|
2366
2458
|
}
|
|
2367
2459
|
function convertPocketBaseCollection(pbCollection) {
|
|
2368
2460
|
const fields = [];
|
|
@@ -2381,17 +2473,28 @@ function convertPocketBaseCollection(pbCollection) {
|
|
|
2381
2473
|
type: pbField.type,
|
|
2382
2474
|
required: pbField.required || false
|
|
2383
2475
|
};
|
|
2384
|
-
|
|
2385
|
-
|
|
2476
|
+
field.options = pbField.options ? { ...pbField.options } : {};
|
|
2477
|
+
if (pbField.type === "select") {
|
|
2478
|
+
if (pbField.values && Array.isArray(pbField.values)) {
|
|
2479
|
+
field.options.values = pbField.values;
|
|
2480
|
+
} else if (pbField.options?.values && Array.isArray(pbField.options.values)) {
|
|
2481
|
+
field.options.values = pbField.options.values;
|
|
2482
|
+
}
|
|
2386
2483
|
}
|
|
2387
2484
|
if (pbField.type === "relation") {
|
|
2485
|
+
const collectionId = pbField.collectionId || pbField.options?.collectionId || "";
|
|
2486
|
+
const collectionName = resolveCollectionIdToName(collectionId);
|
|
2388
2487
|
field.relation = {
|
|
2389
|
-
collection:
|
|
2390
|
-
cascadeDelete: pbField.options?.cascadeDelete
|
|
2391
|
-
maxSelect: pbField.options?.maxSelect,
|
|
2392
|
-
minSelect: pbField.options?.minSelect
|
|
2488
|
+
collection: collectionName,
|
|
2489
|
+
cascadeDelete: pbField.cascadeDelete ?? pbField.options?.cascadeDelete ?? false,
|
|
2490
|
+
maxSelect: pbField.maxSelect ?? pbField.options?.maxSelect,
|
|
2491
|
+
minSelect: pbField.minSelect ?? pbField.options?.minSelect
|
|
2393
2492
|
};
|
|
2394
2493
|
}
|
|
2494
|
+
const hasOnlyValues = Object.keys(field.options).length === 1 && field.options.values !== void 0;
|
|
2495
|
+
if (Object.keys(field.options).length === 0) {
|
|
2496
|
+
delete field.options;
|
|
2497
|
+
} else if (pbField.type === "select" && hasOnlyValues) ;
|
|
2395
2498
|
fields.push(field);
|
|
2396
2499
|
}
|
|
2397
2500
|
}
|
|
@@ -2412,6 +2515,7 @@ function convertPocketBaseCollection(pbCollection) {
|
|
|
2412
2515
|
if (pbCollection.manageRule !== void 0) rules.manageRule = pbCollection.manageRule;
|
|
2413
2516
|
if (Object.keys(rules).length > 0) {
|
|
2414
2517
|
schema.rules = rules;
|
|
2518
|
+
schema.permissions = { ...rules };
|
|
2415
2519
|
}
|
|
2416
2520
|
return schema;
|
|
2417
2521
|
}
|
|
@@ -2455,6 +2559,320 @@ function convertPocketBaseMigration(migrationContent) {
|
|
|
2455
2559
|
}
|
|
2456
2560
|
}
|
|
2457
2561
|
|
|
2562
|
+
// src/migration/migration-parser.ts
|
|
2563
|
+
function extractTimestampFromFilename(filename) {
|
|
2564
|
+
const match = filename.match(/^(\d+)_/);
|
|
2565
|
+
if (match) {
|
|
2566
|
+
return parseInt(match[1], 10);
|
|
2567
|
+
}
|
|
2568
|
+
return null;
|
|
2569
|
+
}
|
|
2570
|
+
function findMigrationsAfterSnapshot(migrationsPath, snapshotTimestamp) {
|
|
2571
|
+
try {
|
|
2572
|
+
if (!fs5__namespace.existsSync(migrationsPath)) {
|
|
2573
|
+
return [];
|
|
2574
|
+
}
|
|
2575
|
+
const files = fs5__namespace.readdirSync(migrationsPath);
|
|
2576
|
+
const migrationFiles = [];
|
|
2577
|
+
for (const file of files) {
|
|
2578
|
+
if (file.endsWith("_collections_snapshot.js") || file.endsWith("_snapshot.js")) {
|
|
2579
|
+
continue;
|
|
2580
|
+
}
|
|
2581
|
+
if (!file.endsWith(".js")) {
|
|
2582
|
+
continue;
|
|
2583
|
+
}
|
|
2584
|
+
const timestamp = extractTimestampFromFilename(file);
|
|
2585
|
+
if (timestamp && timestamp > snapshotTimestamp) {
|
|
2586
|
+
migrationFiles.push({
|
|
2587
|
+
path: path5__namespace.join(migrationsPath, file),
|
|
2588
|
+
timestamp
|
|
2589
|
+
});
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2592
|
+
migrationFiles.sort((a, b) => a.timestamp - b.timestamp);
|
|
2593
|
+
return migrationFiles.map((f) => f.path);
|
|
2594
|
+
} catch (error) {
|
|
2595
|
+
console.warn(`Error finding migrations after snapshot: ${error}`);
|
|
2596
|
+
return [];
|
|
2597
|
+
}
|
|
2598
|
+
}
|
|
2599
|
+
function parseMigrationOperationsFromContent(content) {
|
|
2600
|
+
const collectionsToCreate = [];
|
|
2601
|
+
const collectionsToDelete = [];
|
|
2602
|
+
try {
|
|
2603
|
+
let searchIndex = 0;
|
|
2604
|
+
while (true) {
|
|
2605
|
+
const collectionStart = content.indexOf("new Collection(", searchIndex);
|
|
2606
|
+
if (collectionStart === -1) {
|
|
2607
|
+
break;
|
|
2608
|
+
}
|
|
2609
|
+
const openParen = collectionStart + "new Collection(".length;
|
|
2610
|
+
let braceCount = 0;
|
|
2611
|
+
let parenCount = 1;
|
|
2612
|
+
let inString = false;
|
|
2613
|
+
let stringChar = null;
|
|
2614
|
+
let i = openParen;
|
|
2615
|
+
while (i < content.length && /\s/.test(content[i])) {
|
|
2616
|
+
i++;
|
|
2617
|
+
}
|
|
2618
|
+
if (content[i] !== "{") {
|
|
2619
|
+
searchIndex = i + 1;
|
|
2620
|
+
continue;
|
|
2621
|
+
}
|
|
2622
|
+
const objectStart = i;
|
|
2623
|
+
braceCount = 1;
|
|
2624
|
+
i++;
|
|
2625
|
+
while (i < content.length && (braceCount > 0 || parenCount > 0)) {
|
|
2626
|
+
const char = content[i];
|
|
2627
|
+
const prevChar = i > 0 ? content[i - 1] : "";
|
|
2628
|
+
if (!inString && (char === '"' || char === "'")) {
|
|
2629
|
+
inString = true;
|
|
2630
|
+
stringChar = char;
|
|
2631
|
+
} else if (inString && char === stringChar && prevChar !== "\\") {
|
|
2632
|
+
inString = false;
|
|
2633
|
+
stringChar = null;
|
|
2634
|
+
}
|
|
2635
|
+
if (!inString) {
|
|
2636
|
+
if (char === "{") braceCount++;
|
|
2637
|
+
if (char === "}") braceCount--;
|
|
2638
|
+
if (char === "(") parenCount++;
|
|
2639
|
+
if (char === ")") parenCount--;
|
|
2640
|
+
}
|
|
2641
|
+
i++;
|
|
2642
|
+
}
|
|
2643
|
+
if (braceCount === 0 && parenCount === 0) {
|
|
2644
|
+
const objectContent = content.substring(objectStart, i - 1);
|
|
2645
|
+
try {
|
|
2646
|
+
const collectionObj = new Function(`return ${objectContent}`)();
|
|
2647
|
+
if (collectionObj && collectionObj.name) {
|
|
2648
|
+
const schema = convertPocketBaseCollection(collectionObj);
|
|
2649
|
+
collectionsToCreate.push(schema);
|
|
2650
|
+
}
|
|
2651
|
+
} catch (error) {
|
|
2652
|
+
console.warn(`Failed to parse collection definition: ${error}`);
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2655
|
+
searchIndex = i;
|
|
2656
|
+
}
|
|
2657
|
+
const deleteMatches = content.matchAll(
|
|
2658
|
+
/app\.delete\s*\(\s*(?:collection_\w+|app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\))\s*\)/g
|
|
2659
|
+
);
|
|
2660
|
+
for (const match of deleteMatches) {
|
|
2661
|
+
if (match[1]) {
|
|
2662
|
+
collectionsToDelete.push(match[1]);
|
|
2663
|
+
} else {
|
|
2664
|
+
const varNameMatch = match[0].match(/collection_(\w+)/);
|
|
2665
|
+
if (varNameMatch) {
|
|
2666
|
+
const varName = `collection_${varNameMatch[1]}`;
|
|
2667
|
+
const deleteIndex = content.indexOf(match[0]);
|
|
2668
|
+
const beforeDelete = content.substring(0, deleteIndex);
|
|
2669
|
+
const varDefMatch = beforeDelete.match(
|
|
2670
|
+
new RegExp(`const\\s+${varName}\\s*=\\s*new\\s+Collection\\(\\s*(\\{[\\s\\S]*?\\})\\s*\\)`, "g")
|
|
2671
|
+
);
|
|
2672
|
+
if (varDefMatch && varDefMatch.length > 0) {
|
|
2673
|
+
const collectionDefMatch = beforeDelete.match(
|
|
2674
|
+
new RegExp(`const\\s+${varName}\\s*=\\s*new\\s+Collection\\(\\s*(\\{[\\s\\S]*?\\})\\s*\\)`)
|
|
2675
|
+
);
|
|
2676
|
+
if (collectionDefMatch) {
|
|
2677
|
+
try {
|
|
2678
|
+
const collectionDefStr = collectionDefMatch[1];
|
|
2679
|
+
const collectionObj = new Function(`return ${collectionDefStr}`)();
|
|
2680
|
+
if (collectionObj && collectionObj.name) {
|
|
2681
|
+
collectionsToDelete.push(collectionObj.name);
|
|
2682
|
+
}
|
|
2683
|
+
} catch {
|
|
2684
|
+
}
|
|
2685
|
+
}
|
|
2686
|
+
}
|
|
2687
|
+
}
|
|
2688
|
+
}
|
|
2689
|
+
}
|
|
2690
|
+
const findAndDeleteMatches = content.matchAll(
|
|
2691
|
+
/app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\)[\s\S]*?app\.delete/g
|
|
2692
|
+
);
|
|
2693
|
+
for (const match of findAndDeleteMatches) {
|
|
2694
|
+
collectionsToDelete.push(match[1]);
|
|
2695
|
+
}
|
|
2696
|
+
} catch (error) {
|
|
2697
|
+
console.warn(`Failed to parse migration operations from content: ${error}`);
|
|
2698
|
+
}
|
|
2699
|
+
return { collectionsToCreate, collectionsToDelete };
|
|
2700
|
+
}
|
|
2701
|
+
function parseMigrationOperations(migrationContent) {
|
|
2702
|
+
try {
|
|
2703
|
+
const migrateMatch = migrationContent.match(/migrate\s*\(\s*/);
|
|
2704
|
+
if (!migrateMatch) {
|
|
2705
|
+
return parseMigrationOperationsFromContent(migrationContent);
|
|
2706
|
+
}
|
|
2707
|
+
const startIndex = migrateMatch.index + migrateMatch[0].length;
|
|
2708
|
+
let i = startIndex;
|
|
2709
|
+
let parenCount = 0;
|
|
2710
|
+
let foundFirstParen = false;
|
|
2711
|
+
while (i < migrationContent.length) {
|
|
2712
|
+
const char = migrationContent[i];
|
|
2713
|
+
if (char === "(") {
|
|
2714
|
+
parenCount++;
|
|
2715
|
+
foundFirstParen = true;
|
|
2716
|
+
i++;
|
|
2717
|
+
break;
|
|
2718
|
+
}
|
|
2719
|
+
i++;
|
|
2720
|
+
}
|
|
2721
|
+
if (!foundFirstParen) {
|
|
2722
|
+
return parseMigrationOperationsFromContent(migrationContent);
|
|
2723
|
+
}
|
|
2724
|
+
let inString = false;
|
|
2725
|
+
let stringChar = null;
|
|
2726
|
+
let foundBrace = false;
|
|
2727
|
+
let braceStart = -1;
|
|
2728
|
+
while (i < migrationContent.length && !foundBrace) {
|
|
2729
|
+
const char = migrationContent[i];
|
|
2730
|
+
const prevChar = i > 0 ? migrationContent[i - 1] : "";
|
|
2731
|
+
if (!inString && (char === '"' || char === "'")) {
|
|
2732
|
+
inString = true;
|
|
2733
|
+
stringChar = char;
|
|
2734
|
+
} else if (inString && char === stringChar && prevChar !== "\\") {
|
|
2735
|
+
inString = false;
|
|
2736
|
+
stringChar = null;
|
|
2737
|
+
}
|
|
2738
|
+
if (!inString) {
|
|
2739
|
+
if (char === "(") parenCount++;
|
|
2740
|
+
if (char === ")") {
|
|
2741
|
+
parenCount--;
|
|
2742
|
+
if (parenCount === 0) {
|
|
2743
|
+
i++;
|
|
2744
|
+
while (i < migrationContent.length && /\s/.test(migrationContent[i])) {
|
|
2745
|
+
i++;
|
|
2746
|
+
}
|
|
2747
|
+
if (i < migrationContent.length - 1 && migrationContent[i] === "=" && migrationContent[i + 1] === ">") {
|
|
2748
|
+
i += 2;
|
|
2749
|
+
while (i < migrationContent.length && /\s/.test(migrationContent[i])) {
|
|
2750
|
+
i++;
|
|
2751
|
+
}
|
|
2752
|
+
if (i < migrationContent.length && migrationContent[i] === "{") {
|
|
2753
|
+
foundBrace = true;
|
|
2754
|
+
braceStart = i + 1;
|
|
2755
|
+
break;
|
|
2756
|
+
}
|
|
2757
|
+
}
|
|
2758
|
+
}
|
|
2759
|
+
}
|
|
2760
|
+
}
|
|
2761
|
+
i++;
|
|
2762
|
+
}
|
|
2763
|
+
if (!foundBrace || braceStart === -1) {
|
|
2764
|
+
return parseMigrationOperationsFromContent(migrationContent);
|
|
2765
|
+
}
|
|
2766
|
+
let braceCount = 1;
|
|
2767
|
+
i = braceStart;
|
|
2768
|
+
inString = false;
|
|
2769
|
+
stringChar = null;
|
|
2770
|
+
while (i < migrationContent.length && braceCount > 0) {
|
|
2771
|
+
const char = migrationContent[i];
|
|
2772
|
+
const prevChar = i > 0 ? migrationContent[i - 1] : "";
|
|
2773
|
+
if (!inString && (char === '"' || char === "'")) {
|
|
2774
|
+
inString = true;
|
|
2775
|
+
stringChar = char;
|
|
2776
|
+
} else if (inString && char === stringChar && prevChar !== "\\") {
|
|
2777
|
+
inString = false;
|
|
2778
|
+
stringChar = null;
|
|
2779
|
+
}
|
|
2780
|
+
if (!inString) {
|
|
2781
|
+
if (char === "{") braceCount++;
|
|
2782
|
+
if (char === "}") braceCount--;
|
|
2783
|
+
}
|
|
2784
|
+
i++;
|
|
2785
|
+
}
|
|
2786
|
+
if (braceCount === 0) {
|
|
2787
|
+
const upMigrationContent = migrationContent.substring(braceStart, i - 1);
|
|
2788
|
+
return parseMigrationOperationsFromContent(upMigrationContent);
|
|
2789
|
+
}
|
|
2790
|
+
return parseMigrationOperationsFromContent(migrationContent);
|
|
2791
|
+
} catch (error) {
|
|
2792
|
+
console.warn(`Failed to parse migration operations: ${error}`);
|
|
2793
|
+
return { collectionsToCreate: [], collectionsToDelete: [] };
|
|
2794
|
+
}
|
|
2795
|
+
}
|
|
2796
|
+
({
|
|
2797
|
+
workspaceRoot: process.cwd()});
|
|
2798
|
+
function findLatestSnapshot(migrationsPath) {
|
|
2799
|
+
try {
|
|
2800
|
+
if (!fs5__namespace.existsSync(migrationsPath)) {
|
|
2801
|
+
return null;
|
|
2802
|
+
}
|
|
2803
|
+
const files = fs5__namespace.readdirSync(migrationsPath);
|
|
2804
|
+
const snapshotFiles = files.filter(
|
|
2805
|
+
(file) => file.endsWith("_collections_snapshot.js") || file.endsWith("_snapshot.js")
|
|
2806
|
+
);
|
|
2807
|
+
if (snapshotFiles.length === 0) {
|
|
2808
|
+
return null;
|
|
2809
|
+
}
|
|
2810
|
+
snapshotFiles.sort().reverse();
|
|
2811
|
+
const latestSnapshot = snapshotFiles[0];
|
|
2812
|
+
if (!latestSnapshot) {
|
|
2813
|
+
return null;
|
|
2814
|
+
}
|
|
2815
|
+
return path5__namespace.join(migrationsPath, latestSnapshot);
|
|
2816
|
+
} catch (error) {
|
|
2817
|
+
console.warn(`Error finding latest snapshot: ${error}`);
|
|
2818
|
+
return null;
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2821
|
+
function applyMigrationOperations(snapshot, operations) {
|
|
2822
|
+
const updatedCollections = new Map(snapshot.collections);
|
|
2823
|
+
for (const collectionName of operations.collectionsToDelete) {
|
|
2824
|
+
updatedCollections.delete(collectionName);
|
|
2825
|
+
}
|
|
2826
|
+
for (const collection of operations.collectionsToCreate) {
|
|
2827
|
+
updatedCollections.set(collection.name, collection);
|
|
2828
|
+
}
|
|
2829
|
+
return {
|
|
2830
|
+
...snapshot,
|
|
2831
|
+
collections: updatedCollections
|
|
2832
|
+
};
|
|
2833
|
+
}
|
|
2834
|
+
function loadSnapshotWithMigrations(config = {}) {
|
|
2835
|
+
const migrationsPath = config.migrationsPath;
|
|
2836
|
+
if (!migrationsPath) {
|
|
2837
|
+
return null;
|
|
2838
|
+
}
|
|
2839
|
+
if (fs5__namespace.existsSync(migrationsPath) && fs5__namespace.statSync(migrationsPath).isFile()) {
|
|
2840
|
+
try {
|
|
2841
|
+
const migrationContent = fs5__namespace.readFileSync(migrationsPath, "utf-8");
|
|
2842
|
+
return convertPocketBaseMigration(migrationContent);
|
|
2843
|
+
} catch (error) {
|
|
2844
|
+
console.warn(`Failed to load snapshot from ${migrationsPath}: ${error}`);
|
|
2845
|
+
return null;
|
|
2846
|
+
}
|
|
2847
|
+
}
|
|
2848
|
+
const latestSnapshotPath = findLatestSnapshot(migrationsPath);
|
|
2849
|
+
if (!latestSnapshotPath) {
|
|
2850
|
+
return null;
|
|
2851
|
+
}
|
|
2852
|
+
try {
|
|
2853
|
+
const migrationContent = fs5__namespace.readFileSync(latestSnapshotPath, "utf-8");
|
|
2854
|
+
let snapshot = convertPocketBaseMigration(migrationContent);
|
|
2855
|
+
const snapshotFilename = path5__namespace.basename(latestSnapshotPath);
|
|
2856
|
+
const snapshotTimestamp = extractTimestampFromFilename(snapshotFilename);
|
|
2857
|
+
if (snapshotTimestamp) {
|
|
2858
|
+
const migrationFiles = findMigrationsAfterSnapshot(migrationsPath, snapshotTimestamp);
|
|
2859
|
+
for (const migrationFile of migrationFiles) {
|
|
2860
|
+
try {
|
|
2861
|
+
const migrationContent2 = fs5__namespace.readFileSync(migrationFile, "utf-8");
|
|
2862
|
+
const operations = parseMigrationOperations(migrationContent2);
|
|
2863
|
+
snapshot = applyMigrationOperations(snapshot, operations);
|
|
2864
|
+
} catch (error) {
|
|
2865
|
+
console.warn(`Failed to apply migration ${migrationFile}: ${error}`);
|
|
2866
|
+
}
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2869
|
+
return snapshot;
|
|
2870
|
+
} catch (error) {
|
|
2871
|
+
console.warn(`Failed to load snapshot from ${latestSnapshotPath}: ${error}`);
|
|
2872
|
+
return null;
|
|
2873
|
+
}
|
|
2874
|
+
}
|
|
2875
|
+
|
|
2458
2876
|
// src/migration/validation.ts
|
|
2459
2877
|
function detectCollectionDeletions(diff) {
|
|
2460
2878
|
const changes = [];
|
|
@@ -2623,8 +3041,8 @@ var DEFAULT_CONFIG5 = {
|
|
|
2623
3041
|
};
|
|
2624
3042
|
function findConfigFile(directory) {
|
|
2625
3043
|
for (const fileName of CONFIG_FILE_NAMES) {
|
|
2626
|
-
const filePath =
|
|
2627
|
-
if (
|
|
3044
|
+
const filePath = path5__namespace.join(directory, fileName);
|
|
3045
|
+
if (fs5__namespace.existsSync(filePath)) {
|
|
2628
3046
|
return filePath;
|
|
2629
3047
|
}
|
|
2630
3048
|
}
|
|
@@ -2632,7 +3050,7 @@ function findConfigFile(directory) {
|
|
|
2632
3050
|
}
|
|
2633
3051
|
function loadJsonConfig(configPath) {
|
|
2634
3052
|
try {
|
|
2635
|
-
const content =
|
|
3053
|
+
const content = fs5__namespace.readFileSync(configPath, "utf-8");
|
|
2636
3054
|
return JSON.parse(content);
|
|
2637
3055
|
} catch (error) {
|
|
2638
3056
|
if (error instanceof SyntaxError) {
|
|
@@ -2661,10 +3079,10 @@ async function loadJsConfig(configPath) {
|
|
|
2661
3079
|
}
|
|
2662
3080
|
}
|
|
2663
3081
|
async function loadConfigFile(configPath) {
|
|
2664
|
-
if (!
|
|
3082
|
+
if (!fs5__namespace.existsSync(configPath)) {
|
|
2665
3083
|
return null;
|
|
2666
3084
|
}
|
|
2667
|
-
const ext =
|
|
3085
|
+
const ext = path5__namespace.extname(configPath).toLowerCase();
|
|
2668
3086
|
if (ext === ".json") {
|
|
2669
3087
|
return loadJsonConfig(configPath);
|
|
2670
3088
|
} else if (ext === ".js" || ext === ".mjs") {
|
|
@@ -2731,10 +3149,10 @@ function validateConfig(config, configPath) {
|
|
|
2731
3149
|
}
|
|
2732
3150
|
const cwd = process.cwd();
|
|
2733
3151
|
const possiblePaths = [
|
|
2734
|
-
|
|
2735
|
-
|
|
3152
|
+
path5__namespace.resolve(cwd, config.schema.directory),
|
|
3153
|
+
path5__namespace.resolve(cwd, "shared", config.schema.directory)
|
|
2736
3154
|
];
|
|
2737
|
-
const schemaDir = possiblePaths.find((p) =>
|
|
3155
|
+
const schemaDir = possiblePaths.find((p) => fs5__namespace.existsSync(p));
|
|
2738
3156
|
if (!schemaDir) {
|
|
2739
3157
|
throw new ConfigurationError(`Schema directory not found. Tried: ${possiblePaths.join(", ")}`, configPath, [
|
|
2740
3158
|
"schema.directory"
|
|
@@ -2746,15 +3164,15 @@ async function loadConfig(options = {}) {
|
|
|
2746
3164
|
let configFilePath;
|
|
2747
3165
|
const cwd = process.cwd();
|
|
2748
3166
|
if (options.config) {
|
|
2749
|
-
const explicitPath =
|
|
2750
|
-
if (!
|
|
3167
|
+
const explicitPath = path5__namespace.resolve(cwd, options.config);
|
|
3168
|
+
if (!fs5__namespace.existsSync(explicitPath)) {
|
|
2751
3169
|
throw new ConfigurationError(`Configuration file not found: ${explicitPath}`, explicitPath);
|
|
2752
3170
|
}
|
|
2753
3171
|
configFilePath = explicitPath;
|
|
2754
3172
|
} else {
|
|
2755
|
-
const searchDirs = [cwd,
|
|
3173
|
+
const searchDirs = [cwd, path5__namespace.join(cwd, "shared")];
|
|
2756
3174
|
for (const dir of searchDirs) {
|
|
2757
|
-
if (
|
|
3175
|
+
if (fs5__namespace.existsSync(dir)) {
|
|
2758
3176
|
const found = findConfigFile(dir);
|
|
2759
3177
|
if (found) {
|
|
2760
3178
|
configFilePath = found;
|
|
@@ -2783,18 +3201,18 @@ async function loadConfig(options = {}) {
|
|
|
2783
3201
|
function getSchemaDirectory(config) {
|
|
2784
3202
|
const cwd = process.cwd();
|
|
2785
3203
|
const possiblePaths = [
|
|
2786
|
-
|
|
2787
|
-
|
|
3204
|
+
path5__namespace.resolve(cwd, config.schema.directory),
|
|
3205
|
+
path5__namespace.resolve(cwd, "shared", config.schema.directory)
|
|
2788
3206
|
];
|
|
2789
|
-
return possiblePaths.find((p) =>
|
|
3207
|
+
return possiblePaths.find((p) => fs5__namespace.existsSync(p)) || possiblePaths[0];
|
|
2790
3208
|
}
|
|
2791
3209
|
function getMigrationsDirectory(config) {
|
|
2792
3210
|
const cwd = process.cwd();
|
|
2793
3211
|
const possiblePaths = [
|
|
2794
|
-
|
|
2795
|
-
|
|
3212
|
+
path5__namespace.resolve(cwd, config.migrations.directory),
|
|
3213
|
+
path5__namespace.resolve(cwd, "shared", config.migrations.directory)
|
|
2796
3214
|
];
|
|
2797
|
-
return possiblePaths.find((p) =>
|
|
3215
|
+
return possiblePaths.find((p) => fs5__namespace.existsSync(p)) || possiblePaths[0];
|
|
2798
3216
|
}
|
|
2799
3217
|
var currentVerbosity = "normal";
|
|
2800
3218
|
function setVerbosity(level) {
|
|
@@ -3002,10 +3420,16 @@ async function executeGenerate(options) {
|
|
|
3002
3420
|
const schemaDir = getSchemaDirectory(config);
|
|
3003
3421
|
const migrationsDir = getMigrationsDirectory(config);
|
|
3004
3422
|
logSection("\u{1F50D} Analyzing Schema");
|
|
3005
|
-
const
|
|
3423
|
+
const analyzerConfig = {
|
|
3424
|
+
schemaDir,
|
|
3425
|
+
excludePatterns: config.schema.exclude,
|
|
3426
|
+
useCompiledFiles: false
|
|
3427
|
+
// Use source files since we're in development/testing
|
|
3428
|
+
};
|
|
3429
|
+
const currentSchema = await withProgress("Parsing Zod schemas...", () => parseSchemaFiles(analyzerConfig));
|
|
3006
3430
|
logSuccess(`Found ${currentSchema.collections.size} collection(s)`);
|
|
3007
3431
|
logInfo("Loading previous snapshot...");
|
|
3008
|
-
const previousSnapshot =
|
|
3432
|
+
const previousSnapshot = loadSnapshotWithMigrations({
|
|
3009
3433
|
migrationsPath: migrationsDir,
|
|
3010
3434
|
workspaceRoot: process.cwd()
|
|
3011
3435
|
});
|
|
@@ -3032,7 +3456,7 @@ async function executeGenerate(options) {
|
|
|
3032
3456
|
"Creating migration file...",
|
|
3033
3457
|
() => Promise.resolve(generate(diff, migrationsDir))
|
|
3034
3458
|
);
|
|
3035
|
-
logSuccess(`Migration file created: ${
|
|
3459
|
+
logSuccess(`Migration file created: ${path5__namespace.basename(migrationPath)}`);
|
|
3036
3460
|
logSection("\u2705 Next Steps");
|
|
3037
3461
|
console.log();
|
|
3038
3462
|
console.log(" 1. Review the generated migration file:");
|
|
@@ -3201,10 +3625,16 @@ async function executeStatus(options) {
|
|
|
3201
3625
|
const schemaDir = getSchemaDirectory(config);
|
|
3202
3626
|
const migrationsDir = getMigrationsDirectory(config);
|
|
3203
3627
|
logSection("\u{1F50D} Checking Migration Status");
|
|
3204
|
-
const
|
|
3628
|
+
const analyzerConfig = {
|
|
3629
|
+
schemaDir,
|
|
3630
|
+
excludePatterns: config.schema.exclude,
|
|
3631
|
+
useCompiledFiles: false
|
|
3632
|
+
// Use source files since we're in development/testing
|
|
3633
|
+
};
|
|
3634
|
+
const currentSchema = await withProgress("Parsing Zod schemas...", () => parseSchemaFiles(analyzerConfig));
|
|
3205
3635
|
logSuccess(`Found ${currentSchema.collections.size} collection(s) in schema`);
|
|
3206
3636
|
logInfo("Loading previous snapshot...");
|
|
3207
|
-
const previousSnapshot =
|
|
3637
|
+
const previousSnapshot = loadSnapshotWithMigrations({
|
|
3208
3638
|
migrationsPath: migrationsDir,
|
|
3209
3639
|
workspaceRoot: process.cwd()
|
|
3210
3640
|
});
|
|
@@ -3317,7 +3747,19 @@ Examples:
|
|
|
3317
3747
|
}
|
|
3318
3748
|
|
|
3319
3749
|
// src/cli/migrate.ts
|
|
3320
|
-
|
|
3750
|
+
function getVersion() {
|
|
3751
|
+
try {
|
|
3752
|
+
const __filename2 = url.fileURLToPath(importMetaUrl);
|
|
3753
|
+
const __dirname = path5.dirname(__filename2);
|
|
3754
|
+
const packageJsonPath = path5.join(__dirname, "../../package.json");
|
|
3755
|
+
const packageJson = JSON.parse(fs5.readFileSync(packageJsonPath, "utf-8"));
|
|
3756
|
+
return packageJson.version || "0.0.0";
|
|
3757
|
+
} catch {
|
|
3758
|
+
console.warn("Warning: Could not read version from package.json");
|
|
3759
|
+
return "0.0.0";
|
|
3760
|
+
}
|
|
3761
|
+
}
|
|
3762
|
+
var VERSION = getVersion();
|
|
3321
3763
|
function displayBanner() {
|
|
3322
3764
|
console.log();
|
|
3323
3765
|
console.log(chalk__default.default.cyan.bold(" PocketBase Zod Migration Tool"));
|