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
@@ -1,4 +1,4 @@
1
- import * as fs2 from 'fs';
1
+ import * as fs3 from 'fs';
2
2
  import * as path from 'path';
3
3
  import { z } from 'zod';
4
4
 
@@ -130,10 +130,10 @@ var FileSystemError = class _FileSystemError extends MigrationError {
130
130
  operation;
131
131
  code;
132
132
  originalError;
133
- constructor(message, path4, operation, code, originalError) {
133
+ constructor(message, path5, operation, code, originalError) {
134
134
  super(message);
135
135
  this.name = "FileSystemError";
136
- this.path = path4;
136
+ this.path = path5;
137
137
  this.operation = operation;
138
138
  this.code = code;
139
139
  this.originalError = originalError;
@@ -1356,10 +1356,10 @@ function discoverSchemaFiles(config) {
1356
1356
  const mergedConfig = mergeConfig(normalizedConfig);
1357
1357
  const schemaDir = resolveSchemaDir(normalizedConfig);
1358
1358
  try {
1359
- if (!fs2.existsSync(schemaDir)) {
1359
+ if (!fs3.existsSync(schemaDir)) {
1360
1360
  throw new FileSystemError(`Schema directory not found: ${schemaDir}`, schemaDir, "access", "ENOENT");
1361
1361
  }
1362
- const files = fs2.readdirSync(schemaDir);
1362
+ const files = fs3.readdirSync(schemaDir);
1363
1363
  const schemaFiles = files.filter((file) => {
1364
1364
  const hasValidExtension = mergedConfig.includeExtensions.some((ext) => file.endsWith(ext));
1365
1365
  if (!hasValidExtension) return false;
@@ -1409,9 +1409,9 @@ async function importSchemaModule(filePath, config) {
1409
1409
  let resolvedPath = null;
1410
1410
  const jsPath = `${importPath}.js`;
1411
1411
  const tsPath = `${importPath}.ts`;
1412
- if (fs2.existsSync(jsPath)) {
1412
+ if (fs3.existsSync(jsPath)) {
1413
1413
  resolvedPath = jsPath;
1414
- } else if (fs2.existsSync(tsPath)) {
1414
+ } else if (fs3.existsSync(tsPath)) {
1415
1415
  resolvedPath = tsPath;
1416
1416
  } else {
1417
1417
  resolvedPath = jsPath;
@@ -1421,7 +1421,7 @@ async function importSchemaModule(filePath, config) {
1421
1421
  return module;
1422
1422
  } catch (error) {
1423
1423
  const tsPath = `${filePath}.ts`;
1424
- const isTypeScriptFile = fs2.existsSync(tsPath);
1424
+ const isTypeScriptFile = fs3.existsSync(tsPath);
1425
1425
  if (isTypeScriptFile) {
1426
1426
  throw new SchemaParsingError(
1427
1427
  `Failed to import TypeScript schema file. Node.js cannot import TypeScript files directly.
@@ -1605,7 +1605,7 @@ async function buildSchemaDefinition(config) {
1605
1605
  importPath = normalizedConfig.pathTransformer(filePath);
1606
1606
  } else if (mergedConfig.useCompiledFiles) {
1607
1607
  const distPath = filePath.replace(/\/src\//, "/dist/");
1608
- if (fs2.existsSync(`${distPath}.js`) || fs2.existsSync(`${distPath}.mjs`)) {
1608
+ if (fs3.existsSync(`${distPath}.js`) || fs3.existsSync(`${distPath}.mjs`)) {
1609
1609
  importPath = distPath;
1610
1610
  } else {
1611
1611
  importPath = filePath;
@@ -1661,7 +1661,359 @@ var SchemaAnalyzer = class {
1661
1661
  return convertZodSchemaToCollectionSchema(name, schema);
1662
1662
  }
1663
1663
  };
1664
+
1665
+ // src/migration/pocketbase-converter.ts
1664
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";
1665
2017
  var DEFAULT_SNAPSHOT_FILENAME = ".migration-snapshot.json";
1666
2018
  var SNAPSHOT_MIGRATIONS = [
1667
2019
  // Add migrations here as the format evolves
@@ -1676,7 +2028,7 @@ var DEFAULT_CONFIG2 = {
1676
2028
  snapshotPath: DEFAULT_SNAPSHOT_FILENAME,
1677
2029
  workspaceRoot: process.cwd(),
1678
2030
  autoMigrate: true,
1679
- version: SNAPSHOT_VERSION
2031
+ version: SNAPSHOT_VERSION2
1680
2032
  };
1681
2033
  function mergeConfig2(config = {}) {
1682
2034
  return {
@@ -1696,7 +2048,7 @@ function getSnapshotPath(config = {}) {
1696
2048
  function snapshotExists(config = {}) {
1697
2049
  try {
1698
2050
  const snapshotPath = getSnapshotPath(config);
1699
- return fs2.existsSync(snapshotPath);
2051
+ return fs3.existsSync(snapshotPath);
1700
2052
  } catch {
1701
2053
  return false;
1702
2054
  }
@@ -1756,12 +2108,12 @@ function saveSnapshot(schema, config = {}) {
1756
2108
  const snapshotPath = getSnapshotPath(config);
1757
2109
  try {
1758
2110
  const snapshotDir = path.dirname(snapshotPath);
1759
- if (!fs2.existsSync(snapshotDir)) {
1760
- fs2.mkdirSync(snapshotDir, { recursive: true });
2111
+ if (!fs3.existsSync(snapshotDir)) {
2112
+ fs3.mkdirSync(snapshotDir, { recursive: true });
1761
2113
  }
1762
2114
  const snapshotData = addSnapshotMetadata(schema, config);
1763
2115
  const jsonContent = JSON.stringify(snapshotData, null, 2);
1764
- fs2.writeFileSync(snapshotPath, jsonContent, "utf-8");
2116
+ fs3.writeFileSync(snapshotPath, jsonContent, "utf-8");
1765
2117
  } catch (error) {
1766
2118
  handleFileSystemError(error, "write", snapshotPath);
1767
2119
  }
@@ -1856,7 +2208,7 @@ function deserializeSnapshot(data) {
1856
2208
  function loadSnapshot(config = {}) {
1857
2209
  const snapshotPath = getSnapshotPath(config);
1858
2210
  try {
1859
- const jsonContent = fs2.readFileSync(snapshotPath, "utf-8");
2211
+ const jsonContent = fs3.readFileSync(snapshotPath, "utf-8");
1860
2212
  const data = parseAndValidateSnapshot(jsonContent, snapshotPath);
1861
2213
  const migratedData = migrateSnapshotFormat(data, config);
1862
2214
  return deserializeSnapshot(migratedData);
@@ -1891,10 +2243,10 @@ function mergeSnapshots(baseSnapshot, customSnapshot) {
1891
2243
  }
1892
2244
  function findLatestSnapshot(migrationsPath) {
1893
2245
  try {
1894
- if (!fs2.existsSync(migrationsPath)) {
2246
+ if (!fs3.existsSync(migrationsPath)) {
1895
2247
  return null;
1896
2248
  }
1897
- const files = fs2.readdirSync(migrationsPath);
2249
+ const files = fs3.readdirSync(migrationsPath);
1898
2250
  const snapshotFiles = files.filter(
1899
2251
  (file) => file.endsWith("_collections_snapshot.js") || file.endsWith("_snapshot.js")
1900
2252
  );
@@ -1912,14 +2264,68 @@ function findLatestSnapshot(migrationsPath) {
1912
2264
  return null;
1913
2265
  }
1914
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
+ }
1915
2321
  function loadSnapshotIfExists(config = {}) {
1916
2322
  const migrationsPath = config.migrationsPath;
1917
2323
  if (!migrationsPath) {
1918
2324
  return null;
1919
2325
  }
1920
- if (fs2.existsSync(migrationsPath) && fs2.statSync(migrationsPath).isFile()) {
2326
+ if (fs3.existsSync(migrationsPath) && fs3.statSync(migrationsPath).isFile()) {
1921
2327
  try {
1922
- const migrationContent = fs2.readFileSync(migrationsPath, "utf-8");
2328
+ const migrationContent = fs3.readFileSync(migrationsPath, "utf-8");
1923
2329
  return convertPocketBaseMigration(migrationContent);
1924
2330
  } catch (error) {
1925
2331
  console.warn(`Failed to load snapshot from ${migrationsPath}: ${error}`);
@@ -1929,7 +2335,7 @@ function loadSnapshotIfExists(config = {}) {
1929
2335
  const latestSnapshotPath = findLatestSnapshot(migrationsPath);
1930
2336
  if (latestSnapshotPath) {
1931
2337
  try {
1932
- const migrationContent = fs2.readFileSync(latestSnapshotPath, "utf-8");
2338
+ const migrationContent = fs3.readFileSync(latestSnapshotPath, "utf-8");
1933
2339
  return convertPocketBaseMigration(migrationContent);
1934
2340
  } catch (error) {
1935
2341
  console.warn(`Failed to load snapshot from ${latestSnapshotPath}: ${error}`);
@@ -1938,100 +2344,9 @@ function loadSnapshotIfExists(config = {}) {
1938
2344
  }
1939
2345
  return null;
1940
2346
  }
1941
- function convertPocketBaseCollection(pbCollection) {
1942
- const fields = [];
1943
- const systemFieldNames = ["id", "created", "updated", "collectionId", "collectionName", "expand"];
1944
- const authSystemFieldNames = ["email", "emailVisibility", "verified", "password", "tokenKey"];
1945
- if (pbCollection.fields && Array.isArray(pbCollection.fields)) {
1946
- for (const pbField of pbCollection.fields) {
1947
- if (pbField.system || systemFieldNames.includes(pbField.name)) {
1948
- continue;
1949
- }
1950
- if (pbCollection.type === "auth" && authSystemFieldNames.includes(pbField.name)) {
1951
- continue;
1952
- }
1953
- const field = {
1954
- name: pbField.name,
1955
- type: pbField.type,
1956
- required: pbField.required || false
1957
- };
1958
- if (pbField.options) {
1959
- field.options = pbField.options;
1960
- }
1961
- if (pbField.type === "relation") {
1962
- field.relation = {
1963
- collection: pbField.options?.collectionId || "",
1964
- cascadeDelete: pbField.options?.cascadeDelete || false,
1965
- maxSelect: pbField.options?.maxSelect,
1966
- minSelect: pbField.options?.minSelect
1967
- };
1968
- }
1969
- fields.push(field);
1970
- }
1971
- }
1972
- const schema = {
1973
- name: pbCollection.name,
1974
- type: pbCollection.type || "base",
1975
- fields
1976
- };
1977
- if (pbCollection.indexes && Array.isArray(pbCollection.indexes)) {
1978
- schema.indexes = pbCollection.indexes;
1979
- }
1980
- const rules = {};
1981
- if (pbCollection.listRule !== void 0) rules.listRule = pbCollection.listRule;
1982
- if (pbCollection.viewRule !== void 0) rules.viewRule = pbCollection.viewRule;
1983
- if (pbCollection.createRule !== void 0) rules.createRule = pbCollection.createRule;
1984
- if (pbCollection.updateRule !== void 0) rules.updateRule = pbCollection.updateRule;
1985
- if (pbCollection.deleteRule !== void 0) rules.deleteRule = pbCollection.deleteRule;
1986
- if (pbCollection.manageRule !== void 0) rules.manageRule = pbCollection.manageRule;
1987
- if (Object.keys(rules).length > 0) {
1988
- schema.rules = rules;
1989
- schema.permissions = { ...rules };
1990
- }
1991
- return schema;
1992
- }
1993
- function convertPocketBaseMigration(migrationContent) {
1994
- try {
1995
- const snapshotMatch = migrationContent.match(/const\s+snapshot\s*=\s*(\[[\s\S]*?\]);/);
1996
- if (!snapshotMatch) {
1997
- throw new Error("Could not find snapshot array in migration file");
1998
- }
1999
- const snapshotArrayStr = snapshotMatch[1];
2000
- let snapshotArray;
2001
- try {
2002
- snapshotArray = new Function(`return ${snapshotArrayStr}`)();
2003
- } catch (parseError) {
2004
- throw new Error(`Failed to parse snapshot array: ${parseError}`);
2005
- }
2006
- if (!Array.isArray(snapshotArray)) {
2007
- throw new Error("Snapshot is not an array");
2008
- }
2009
- const collections = /* @__PURE__ */ new Map();
2010
- for (const pbCollection of snapshotArray) {
2011
- if (!pbCollection.name) {
2012
- console.warn("Skipping collection without name");
2013
- continue;
2014
- }
2015
- const schema = convertPocketBaseCollection(pbCollection);
2016
- collections.set(pbCollection.name, schema);
2017
- }
2018
- return {
2019
- version: SNAPSHOT_VERSION,
2020
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2021
- collections
2022
- };
2023
- } catch (error) {
2024
- throw new SnapshotError(
2025
- `Failed to convert PocketBase migration: ${error instanceof Error ? error.message : String(error)}`,
2026
- void 0,
2027
- "parse",
2028
- error instanceof Error ? error : void 0
2029
- );
2030
- }
2031
- }
2032
2347
  function loadBaseMigration(migrationPath) {
2033
2348
  try {
2034
- if (!fs2.existsSync(migrationPath)) {
2349
+ if (!fs3.existsSync(migrationPath)) {
2035
2350
  throw new SnapshotError(
2036
2351
  `Base migration file not found: ${migrationPath}
2037
2352
 
@@ -2042,7 +2357,7 @@ If the file exists in a different location, update the configuration.`,
2042
2357
  "read"
2043
2358
  );
2044
2359
  }
2045
- const migrationContent = fs2.readFileSync(migrationPath, "utf-8");
2360
+ const migrationContent = fs3.readFileSync(migrationPath, "utf-8");
2046
2361
  const snapshot = convertPocketBaseMigration(migrationContent);
2047
2362
  return snapshot;
2048
2363
  } catch (error) {
@@ -2078,14 +2393,14 @@ Please ensure PocketBase is properly set up by running 'yarn setup'.`,
2078
2393
  }
2079
2394
  }
2080
2395
  function getSnapshotVersion() {
2081
- return SNAPSHOT_VERSION;
2396
+ return SNAPSHOT_VERSION2;
2082
2397
  }
2083
2398
  function validateSnapshot(snapshot) {
2084
2399
  const issues = [];
2085
2400
  if (!snapshot.version) {
2086
2401
  issues.push("Missing version field");
2087
- } else if (compareVersions(snapshot.version, SNAPSHOT_VERSION) > 0) {
2088
- issues.push(`Snapshot version ${snapshot.version} is newer than supported version ${SNAPSHOT_VERSION}`);
2402
+ } else if (compareVersions(snapshot.version, SNAPSHOT_VERSION2) > 0) {
2403
+ issues.push(`Snapshot version ${snapshot.version} is newer than supported version ${SNAPSHOT_VERSION2}`);
2089
2404
  }
2090
2405
  if (!snapshot.timestamp) {
2091
2406
  issues.push("Missing timestamp field");
@@ -2304,6 +2619,9 @@ function compareFieldOptions(currentField, previousField) {
2304
2619
  for (const key of allKeys) {
2305
2620
  const currentValue = currentOptions[key];
2306
2621
  const previousValue = previousOptions[key];
2622
+ if (currentValue === void 0 && previousValue === void 0) {
2623
+ continue;
2624
+ }
2307
2625
  if (!areValuesEqual(currentValue, previousValue)) {
2308
2626
  changes.push({
2309
2627
  property: `options.${key}`,
@@ -2324,11 +2642,26 @@ function compareRelationConfigurations(currentField, previousField) {
2324
2642
  if (!currentRelation || !previousRelation) {
2325
2643
  return changes;
2326
2644
  }
2327
- if (currentRelation.collection !== previousRelation.collection) {
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) {
2328
2659
  changes.push({
2329
2660
  property: "relation.collection",
2330
- oldValue: previousRelation.collection,
2331
- newValue: currentRelation.collection
2661
+ oldValue: normalizedPrevious,
2662
+ // Use normalized value for clarity
2663
+ newValue: normalizedCurrent
2664
+ // Use normalized value for clarity
2332
2665
  });
2333
2666
  }
2334
2667
  if (currentRelation.cascadeDelete !== previousRelation.cascadeDelete) {
@@ -2762,9 +3095,9 @@ function createMigrationFileStructure(upCode, downCode, config) {
2762
3095
  }
2763
3096
  function writeMigrationFile(migrationDir, filename, content) {
2764
3097
  try {
2765
- if (!fs2.existsSync(migrationDir)) {
3098
+ if (!fs3.existsSync(migrationDir)) {
2766
3099
  try {
2767
- fs2.mkdirSync(migrationDir, { recursive: true });
3100
+ fs3.mkdirSync(migrationDir, { recursive: true });
2768
3101
  } catch (error) {
2769
3102
  const fsError = error;
2770
3103
  if (fsError.code === "EACCES" || fsError.code === "EPERM") {
@@ -2786,7 +3119,7 @@ function writeMigrationFile(migrationDir, filename, content) {
2786
3119
  }
2787
3120
  }
2788
3121
  const filePath = path.join(migrationDir, filename);
2789
- fs2.writeFileSync(filePath, content, "utf-8");
3122
+ fs3.writeFileSync(filePath, content, "utf-8");
2790
3123
  return filePath;
2791
3124
  } catch (error) {
2792
3125
  if (error instanceof FileSystemError) {
@@ -3369,6 +3702,6 @@ var MigrationGenerator = class {
3369
3702
  }
3370
3703
  };
3371
3704
 
3372
- 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 };
3373
3706
  //# sourceMappingURL=index.js.map
3374
3707
  //# sourceMappingURL=index.js.map