pocketbase-zod-schema 0.1.3 → 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.
Files changed (46) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/cli/index.cjs +406 -102
  3. package/dist/cli/index.cjs.map +1 -1
  4. package/dist/cli/index.js +404 -100
  5. package/dist/cli/index.js.map +1 -1
  6. package/dist/cli/migrate.cjs +409 -105
  7. package/dist/cli/migrate.cjs.map +1 -1
  8. package/dist/cli/migrate.js +404 -100
  9. package/dist/cli/migrate.js.map +1 -1
  10. package/dist/index.cjs +515 -159
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.d.cts +3 -3
  13. package/dist/index.d.ts +3 -3
  14. package/dist/index.js +511 -158
  15. package/dist/index.js.map +1 -1
  16. package/dist/migration/diff.cjs +21 -3
  17. package/dist/migration/diff.cjs.map +1 -1
  18. package/dist/migration/diff.js +21 -3
  19. package/dist/migration/diff.js.map +1 -1
  20. package/dist/migration/index.cjs +457 -123
  21. package/dist/migration/index.cjs.map +1 -1
  22. package/dist/migration/index.d.cts +1 -1
  23. package/dist/migration/index.d.ts +1 -1
  24. package/dist/migration/index.js +456 -123
  25. package/dist/migration/index.js.map +1 -1
  26. package/dist/migration/snapshot.cjs +432 -118
  27. package/dist/migration/snapshot.cjs.map +1 -1
  28. package/dist/migration/snapshot.d.cts +34 -12
  29. package/dist/migration/snapshot.d.ts +34 -12
  30. package/dist/migration/snapshot.js +430 -117
  31. package/dist/migration/snapshot.js.map +1 -1
  32. package/dist/mutator.d.cts +3 -3
  33. package/dist/mutator.d.ts +3 -3
  34. package/dist/schema.cjs +34 -0
  35. package/dist/schema.cjs.map +1 -1
  36. package/dist/schema.d.cts +1 -1
  37. package/dist/schema.d.ts +1 -1
  38. package/dist/schema.js +33 -1
  39. package/dist/schema.js.map +1 -1
  40. package/dist/types.d.cts +5 -2
  41. package/dist/types.d.ts +5 -2
  42. package/dist/user-_AM523hb.d.cts +123 -0
  43. package/dist/user-_AM523hb.d.ts +123 -0
  44. package/package.json +2 -3
  45. package/dist/user-C39DQ40N.d.cts +0 -53
  46. package/dist/user-C39DQ40N.d.ts +0 -53
@@ -3,8 +3,8 @@
3
3
 
4
4
  var chalk = require('chalk');
5
5
  var commander = require('commander');
6
- var fs4 = require('fs');
7
- var path4 = require('path');
6
+ var fs5 = require('fs');
7
+ var path5 = require('path');
8
8
  var url = require('url');
9
9
  var zod = require('zod');
10
10
  var ora = require('ora');
@@ -30,8 +30,8 @@ function _interopNamespace(e) {
30
30
  }
31
31
 
32
32
  var chalk__default = /*#__PURE__*/_interopDefault(chalk);
33
- var fs4__namespace = /*#__PURE__*/_interopNamespace(fs4);
34
- var path4__namespace = /*#__PURE__*/_interopNamespace(path4);
33
+ var fs5__namespace = /*#__PURE__*/_interopNamespace(fs5);
34
+ var path5__namespace = /*#__PURE__*/_interopNamespace(path5);
35
35
  var ora__default = /*#__PURE__*/_interopDefault(ora);
36
36
 
37
37
  // ../node_modules/tsup/assets/cjs_shims.js
@@ -164,10 +164,10 @@ var FileSystemError = class _FileSystemError extends MigrationError {
164
164
  operation;
165
165
  code;
166
166
  originalError;
167
- constructor(message, path6, operation, code, originalError) {
167
+ constructor(message, path7, operation, code, originalError) {
168
168
  super(message);
169
169
  this.name = "FileSystemError";
170
- this.path = path6;
170
+ this.path = path7;
171
171
  this.operation = operation;
172
172
  this.code = code;
173
173
  this.originalError = originalError;
@@ -1108,20 +1108,20 @@ function mergeConfig(config) {
1108
1108
  }
1109
1109
  function resolveSchemaDir(config) {
1110
1110
  const workspaceRoot = config.workspaceRoot || process.cwd();
1111
- if (path4__namespace.isAbsolute(config.schemaDir)) {
1111
+ if (path5__namespace.isAbsolute(config.schemaDir)) {
1112
1112
  return config.schemaDir;
1113
1113
  }
1114
- return path4__namespace.join(workspaceRoot, config.schemaDir);
1114
+ return path5__namespace.join(workspaceRoot, config.schemaDir);
1115
1115
  }
1116
1116
  function discoverSchemaFiles(config) {
1117
1117
  const normalizedConfig = typeof config === "string" ? { schemaDir: config } : config;
1118
1118
  const mergedConfig = mergeConfig(normalizedConfig);
1119
1119
  const schemaDir = resolveSchemaDir(normalizedConfig);
1120
1120
  try {
1121
- if (!fs4__namespace.existsSync(schemaDir)) {
1121
+ if (!fs5__namespace.existsSync(schemaDir)) {
1122
1122
  throw new FileSystemError(`Schema directory not found: ${schemaDir}`, schemaDir, "access", "ENOENT");
1123
1123
  }
1124
- const files = fs4__namespace.readdirSync(schemaDir);
1124
+ const files = fs5__namespace.readdirSync(schemaDir);
1125
1125
  const schemaFiles = files.filter((file) => {
1126
1126
  const hasValidExtension = mergedConfig.includeExtensions.some((ext) => file.endsWith(ext));
1127
1127
  if (!hasValidExtension) return false;
@@ -1137,7 +1137,7 @@ function discoverSchemaFiles(config) {
1137
1137
  });
1138
1138
  return schemaFiles.map((file) => {
1139
1139
  const ext = mergedConfig.includeExtensions.find((ext2) => file.endsWith(ext2)) || ".ts";
1140
- return path4__namespace.join(schemaDir, file.replace(new RegExp(`\\${ext}$`), ""));
1140
+ return path5__namespace.join(schemaDir, file.replace(new RegExp(`\\${ext}$`), ""));
1141
1141
  });
1142
1142
  } catch (error) {
1143
1143
  if (error instanceof FileSystemError) {
@@ -1171,19 +1171,19 @@ async function importSchemaModule(filePath, config) {
1171
1171
  let resolvedPath = null;
1172
1172
  const jsPath = `${importPath}.js`;
1173
1173
  const tsPath = `${importPath}.ts`;
1174
- if (fs4__namespace.existsSync(jsPath)) {
1174
+ if (fs5__namespace.existsSync(jsPath)) {
1175
1175
  resolvedPath = jsPath;
1176
- } else if (fs4__namespace.existsSync(tsPath)) {
1176
+ } else if (fs5__namespace.existsSync(tsPath)) {
1177
1177
  resolvedPath = tsPath;
1178
1178
  } else {
1179
1179
  resolvedPath = jsPath;
1180
1180
  }
1181
- const fileUrl = new URL(`file://${path4__namespace.resolve(resolvedPath)}`);
1181
+ const fileUrl = new URL(`file://${path5__namespace.resolve(resolvedPath)}`);
1182
1182
  const module = await import(fileUrl.href);
1183
1183
  return module;
1184
1184
  } catch (error) {
1185
1185
  const tsPath = `${filePath}.ts`;
1186
- const isTypeScriptFile = fs4__namespace.existsSync(tsPath);
1186
+ const isTypeScriptFile = fs5__namespace.existsSync(tsPath);
1187
1187
  if (isTypeScriptFile) {
1188
1188
  throw new SchemaParsingError(
1189
1189
  `Failed to import TypeScript schema file. Node.js cannot import TypeScript files directly.
@@ -1202,7 +1202,7 @@ Please either:
1202
1202
  }
1203
1203
  }
1204
1204
  function getCollectionNameFromFile(filePath) {
1205
- const filename = path4__namespace.basename(filePath).replace(/\.(ts|js)$/, "");
1205
+ const filename = path5__namespace.basename(filePath).replace(/\.(ts|js)$/, "");
1206
1206
  return toCollectionName(filename);
1207
1207
  }
1208
1208
  function extractSchemaDefinitions(module, patterns = ["Schema", "InputSchema"]) {
@@ -1367,7 +1367,7 @@ async function buildSchemaDefinition(config) {
1367
1367
  importPath = normalizedConfig.pathTransformer(filePath);
1368
1368
  } else if (mergedConfig.useCompiledFiles) {
1369
1369
  const distPath = filePath.replace(/\/src\//, "/dist/");
1370
- if (fs4__namespace.existsSync(`${distPath}.js`) || fs4__namespace.existsSync(`${distPath}.mjs`)) {
1370
+ if (fs5__namespace.existsSync(`${distPath}.js`) || fs5__namespace.existsSync(`${distPath}.mjs`)) {
1371
1371
  importPath = distPath;
1372
1372
  } else {
1373
1373
  importPath = filePath;
@@ -1544,6 +1544,9 @@ function compareFieldOptions(currentField, previousField) {
1544
1544
  for (const key of allKeys) {
1545
1545
  const currentValue = currentOptions[key];
1546
1546
  const previousValue = previousOptions[key];
1547
+ if (currentValue === void 0 && previousValue === void 0) {
1548
+ continue;
1549
+ }
1547
1550
  if (!areValuesEqual(currentValue, previousValue)) {
1548
1551
  changes.push({
1549
1552
  property: `options.${key}`,
@@ -1564,11 +1567,26 @@ function compareRelationConfigurations(currentField, previousField) {
1564
1567
  if (!currentRelation || !previousRelation) {
1565
1568
  return changes;
1566
1569
  }
1567
- if (currentRelation.collection !== previousRelation.collection) {
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) {
1568
1584
  changes.push({
1569
1585
  property: "relation.collection",
1570
- oldValue: previousRelation.collection,
1571
- newValue: currentRelation.collection
1586
+ oldValue: normalizedPrevious,
1587
+ // Use normalized value for clarity
1588
+ newValue: normalizedCurrent
1589
+ // Use normalized value for clarity
1572
1590
  });
1573
1591
  }
1574
1592
  if (currentRelation.cascadeDelete !== previousRelation.cascadeDelete) {
@@ -1788,10 +1806,10 @@ function mergeConfig3(config) {
1788
1806
  }
1789
1807
  function resolveMigrationDir(config) {
1790
1808
  const workspaceRoot = config.workspaceRoot || process.cwd();
1791
- if (path4__namespace.isAbsolute(config.migrationDir)) {
1809
+ if (path5__namespace.isAbsolute(config.migrationDir)) {
1792
1810
  return config.migrationDir;
1793
1811
  }
1794
- return path4__namespace.join(workspaceRoot, config.migrationDir);
1812
+ return path5__namespace.join(workspaceRoot, config.migrationDir);
1795
1813
  }
1796
1814
  function generateTimestamp(config) {
1797
1815
  if (config?.timestampGenerator) {
@@ -1849,9 +1867,9 @@ function createMigrationFileStructure(upCode, downCode, config) {
1849
1867
  }
1850
1868
  function writeMigrationFile(migrationDir, filename, content) {
1851
1869
  try {
1852
- if (!fs4__namespace.existsSync(migrationDir)) {
1870
+ if (!fs5__namespace.existsSync(migrationDir)) {
1853
1871
  try {
1854
- fs4__namespace.mkdirSync(migrationDir, { recursive: true });
1872
+ fs5__namespace.mkdirSync(migrationDir, { recursive: true });
1855
1873
  } catch (error) {
1856
1874
  const fsError = error;
1857
1875
  if (fsError.code === "EACCES" || fsError.code === "EPERM") {
@@ -1872,15 +1890,15 @@ function writeMigrationFile(migrationDir, filename, content) {
1872
1890
  );
1873
1891
  }
1874
1892
  }
1875
- const filePath = path4__namespace.join(migrationDir, filename);
1876
- fs4__namespace.writeFileSync(filePath, content, "utf-8");
1893
+ const filePath = path5__namespace.join(migrationDir, filename);
1894
+ fs5__namespace.writeFileSync(filePath, content, "utf-8");
1877
1895
  return filePath;
1878
1896
  } catch (error) {
1879
1897
  if (error instanceof FileSystemError) {
1880
1898
  throw error;
1881
1899
  }
1882
1900
  const fsError = error;
1883
- const filePath = path4__namespace.join(migrationDir, filename);
1901
+ const filePath = path5__namespace.join(migrationDir, filename);
1884
1902
  if (fsError.code === "EACCES" || fsError.code === "EPERM") {
1885
1903
  throw new FileSystemError(
1886
1904
  `Permission denied writing migration file. Check file and directory permissions.`,
@@ -2425,57 +2443,18 @@ function generate(diff, config) {
2425
2443
  );
2426
2444
  }
2427
2445
  }
2446
+
2447
+ // src/migration/pocketbase-converter.ts
2428
2448
  var SNAPSHOT_VERSION = "1.0.0";
2429
- ({
2430
- workspaceRoot: process.cwd()});
2431
- function findLatestSnapshot(migrationsPath) {
2432
- try {
2433
- if (!fs4__namespace.existsSync(migrationsPath)) {
2434
- return null;
2435
- }
2436
- const files = fs4__namespace.readdirSync(migrationsPath);
2437
- const snapshotFiles = files.filter(
2438
- (file) => file.endsWith("_collections_snapshot.js") || file.endsWith("_snapshot.js")
2439
- );
2440
- if (snapshotFiles.length === 0) {
2441
- return null;
2442
- }
2443
- snapshotFiles.sort().reverse();
2444
- const latestSnapshot = snapshotFiles[0];
2445
- if (!latestSnapshot) {
2446
- return null;
2447
- }
2448
- return path4__namespace.join(migrationsPath, latestSnapshot);
2449
- } catch (error) {
2450
- console.warn(`Error finding latest snapshot: ${error}`);
2451
- return null;
2449
+ function resolveCollectionIdToName(collectionId) {
2450
+ if (collectionId === "_pb_users_auth_") {
2451
+ return "Users";
2452
2452
  }
2453
- }
2454
- function loadSnapshotIfExists(config = {}) {
2455
- const migrationsPath = config.migrationsPath;
2456
- if (!migrationsPath) {
2457
- return null;
2453
+ const nameMatch = collectionId.match(/app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\)/);
2454
+ if (nameMatch) {
2455
+ return nameMatch[1];
2458
2456
  }
2459
- if (fs4__namespace.existsSync(migrationsPath) && fs4__namespace.statSync(migrationsPath).isFile()) {
2460
- try {
2461
- const migrationContent = fs4__namespace.readFileSync(migrationsPath, "utf-8");
2462
- return convertPocketBaseMigration(migrationContent);
2463
- } catch (error) {
2464
- console.warn(`Failed to load snapshot from ${migrationsPath}: ${error}`);
2465
- return null;
2466
- }
2467
- }
2468
- const latestSnapshotPath = findLatestSnapshot(migrationsPath);
2469
- if (latestSnapshotPath) {
2470
- try {
2471
- const migrationContent = fs4__namespace.readFileSync(latestSnapshotPath, "utf-8");
2472
- return convertPocketBaseMigration(migrationContent);
2473
- } catch (error) {
2474
- console.warn(`Failed to load snapshot from ${latestSnapshotPath}: ${error}`);
2475
- return null;
2476
- }
2477
- }
2478
- return null;
2457
+ return collectionId;
2479
2458
  }
2480
2459
  function convertPocketBaseCollection(pbCollection) {
2481
2460
  const fields = [];
@@ -2494,17 +2473,28 @@ function convertPocketBaseCollection(pbCollection) {
2494
2473
  type: pbField.type,
2495
2474
  required: pbField.required || false
2496
2475
  };
2497
- if (pbField.options) {
2498
- field.options = pbField.options;
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
+ }
2499
2483
  }
2500
2484
  if (pbField.type === "relation") {
2485
+ const collectionId = pbField.collectionId || pbField.options?.collectionId || "";
2486
+ const collectionName = resolveCollectionIdToName(collectionId);
2501
2487
  field.relation = {
2502
- collection: pbField.options?.collectionId || "",
2503
- cascadeDelete: pbField.options?.cascadeDelete || false,
2504
- maxSelect: pbField.options?.maxSelect,
2505
- 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
2506
2492
  };
2507
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) ;
2508
2498
  fields.push(field);
2509
2499
  }
2510
2500
  }
@@ -2569,6 +2559,320 @@ function convertPocketBaseMigration(migrationContent) {
2569
2559
  }
2570
2560
  }
2571
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
+
2572
2876
  // src/migration/validation.ts
2573
2877
  function detectCollectionDeletions(diff) {
2574
2878
  const changes = [];
@@ -2737,8 +3041,8 @@ var DEFAULT_CONFIG5 = {
2737
3041
  };
2738
3042
  function findConfigFile(directory) {
2739
3043
  for (const fileName of CONFIG_FILE_NAMES) {
2740
- const filePath = path4__namespace.join(directory, fileName);
2741
- if (fs4__namespace.existsSync(filePath)) {
3044
+ const filePath = path5__namespace.join(directory, fileName);
3045
+ if (fs5__namespace.existsSync(filePath)) {
2742
3046
  return filePath;
2743
3047
  }
2744
3048
  }
@@ -2746,7 +3050,7 @@ function findConfigFile(directory) {
2746
3050
  }
2747
3051
  function loadJsonConfig(configPath) {
2748
3052
  try {
2749
- const content = fs4__namespace.readFileSync(configPath, "utf-8");
3053
+ const content = fs5__namespace.readFileSync(configPath, "utf-8");
2750
3054
  return JSON.parse(content);
2751
3055
  } catch (error) {
2752
3056
  if (error instanceof SyntaxError) {
@@ -2775,10 +3079,10 @@ async function loadJsConfig(configPath) {
2775
3079
  }
2776
3080
  }
2777
3081
  async function loadConfigFile(configPath) {
2778
- if (!fs4__namespace.existsSync(configPath)) {
3082
+ if (!fs5__namespace.existsSync(configPath)) {
2779
3083
  return null;
2780
3084
  }
2781
- const ext = path4__namespace.extname(configPath).toLowerCase();
3085
+ const ext = path5__namespace.extname(configPath).toLowerCase();
2782
3086
  if (ext === ".json") {
2783
3087
  return loadJsonConfig(configPath);
2784
3088
  } else if (ext === ".js" || ext === ".mjs") {
@@ -2845,10 +3149,10 @@ function validateConfig(config, configPath) {
2845
3149
  }
2846
3150
  const cwd = process.cwd();
2847
3151
  const possiblePaths = [
2848
- path4__namespace.resolve(cwd, config.schema.directory),
2849
- path4__namespace.resolve(cwd, "shared", config.schema.directory)
3152
+ path5__namespace.resolve(cwd, config.schema.directory),
3153
+ path5__namespace.resolve(cwd, "shared", config.schema.directory)
2850
3154
  ];
2851
- const schemaDir = possiblePaths.find((p) => fs4__namespace.existsSync(p));
3155
+ const schemaDir = possiblePaths.find((p) => fs5__namespace.existsSync(p));
2852
3156
  if (!schemaDir) {
2853
3157
  throw new ConfigurationError(`Schema directory not found. Tried: ${possiblePaths.join(", ")}`, configPath, [
2854
3158
  "schema.directory"
@@ -2860,15 +3164,15 @@ async function loadConfig(options = {}) {
2860
3164
  let configFilePath;
2861
3165
  const cwd = process.cwd();
2862
3166
  if (options.config) {
2863
- const explicitPath = path4__namespace.resolve(cwd, options.config);
2864
- if (!fs4__namespace.existsSync(explicitPath)) {
3167
+ const explicitPath = path5__namespace.resolve(cwd, options.config);
3168
+ if (!fs5__namespace.existsSync(explicitPath)) {
2865
3169
  throw new ConfigurationError(`Configuration file not found: ${explicitPath}`, explicitPath);
2866
3170
  }
2867
3171
  configFilePath = explicitPath;
2868
3172
  } else {
2869
- const searchDirs = [cwd, path4__namespace.join(cwd, "shared")];
3173
+ const searchDirs = [cwd, path5__namespace.join(cwd, "shared")];
2870
3174
  for (const dir of searchDirs) {
2871
- if (fs4__namespace.existsSync(dir)) {
3175
+ if (fs5__namespace.existsSync(dir)) {
2872
3176
  const found = findConfigFile(dir);
2873
3177
  if (found) {
2874
3178
  configFilePath = found;
@@ -2897,18 +3201,18 @@ async function loadConfig(options = {}) {
2897
3201
  function getSchemaDirectory(config) {
2898
3202
  const cwd = process.cwd();
2899
3203
  const possiblePaths = [
2900
- path4__namespace.resolve(cwd, config.schema.directory),
2901
- path4__namespace.resolve(cwd, "shared", config.schema.directory)
3204
+ path5__namespace.resolve(cwd, config.schema.directory),
3205
+ path5__namespace.resolve(cwd, "shared", config.schema.directory)
2902
3206
  ];
2903
- return possiblePaths.find((p) => fs4__namespace.existsSync(p)) || possiblePaths[0];
3207
+ return possiblePaths.find((p) => fs5__namespace.existsSync(p)) || possiblePaths[0];
2904
3208
  }
2905
3209
  function getMigrationsDirectory(config) {
2906
3210
  const cwd = process.cwd();
2907
3211
  const possiblePaths = [
2908
- path4__namespace.resolve(cwd, config.migrations.directory),
2909
- path4__namespace.resolve(cwd, "shared", config.migrations.directory)
3212
+ path5__namespace.resolve(cwd, config.migrations.directory),
3213
+ path5__namespace.resolve(cwd, "shared", config.migrations.directory)
2910
3214
  ];
2911
- return possiblePaths.find((p) => fs4__namespace.existsSync(p)) || possiblePaths[0];
3215
+ return possiblePaths.find((p) => fs5__namespace.existsSync(p)) || possiblePaths[0];
2912
3216
  }
2913
3217
  var currentVerbosity = "normal";
2914
3218
  function setVerbosity(level) {
@@ -3125,7 +3429,7 @@ async function executeGenerate(options) {
3125
3429
  const currentSchema = await withProgress("Parsing Zod schemas...", () => parseSchemaFiles(analyzerConfig));
3126
3430
  logSuccess(`Found ${currentSchema.collections.size} collection(s)`);
3127
3431
  logInfo("Loading previous snapshot...");
3128
- const previousSnapshot = loadSnapshotIfExists({
3432
+ const previousSnapshot = loadSnapshotWithMigrations({
3129
3433
  migrationsPath: migrationsDir,
3130
3434
  workspaceRoot: process.cwd()
3131
3435
  });
@@ -3152,7 +3456,7 @@ async function executeGenerate(options) {
3152
3456
  "Creating migration file...",
3153
3457
  () => Promise.resolve(generate(diff, migrationsDir))
3154
3458
  );
3155
- logSuccess(`Migration file created: ${path4__namespace.basename(migrationPath)}`);
3459
+ logSuccess(`Migration file created: ${path5__namespace.basename(migrationPath)}`);
3156
3460
  logSection("\u2705 Next Steps");
3157
3461
  console.log();
3158
3462
  console.log(" 1. Review the generated migration file:");
@@ -3330,7 +3634,7 @@ async function executeStatus(options) {
3330
3634
  const currentSchema = await withProgress("Parsing Zod schemas...", () => parseSchemaFiles(analyzerConfig));
3331
3635
  logSuccess(`Found ${currentSchema.collections.size} collection(s) in schema`);
3332
3636
  logInfo("Loading previous snapshot...");
3333
- const previousSnapshot = loadSnapshotIfExists({
3637
+ const previousSnapshot = loadSnapshotWithMigrations({
3334
3638
  migrationsPath: migrationsDir,
3335
3639
  workspaceRoot: process.cwd()
3336
3640
  });
@@ -3446,9 +3750,9 @@ Examples:
3446
3750
  function getVersion() {
3447
3751
  try {
3448
3752
  const __filename2 = url.fileURLToPath(importMetaUrl);
3449
- const __dirname = path4.dirname(__filename2);
3450
- const packageJsonPath = path4.join(__dirname, "../../package.json");
3451
- const packageJson = JSON.parse(fs4.readFileSync(packageJsonPath, "utf-8"));
3753
+ const __dirname = path5.dirname(__filename2);
3754
+ const packageJsonPath = path5.join(__dirname, "../../package.json");
3755
+ const packageJson = JSON.parse(fs5.readFileSync(packageJsonPath, "utf-8"));
3452
3756
  return packageJson.version || "0.0.0";
3453
3757
  } catch {
3454
3758
  console.warn("Warning: Could not read version from package.json");