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,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var fs2 = require('fs');
3
+ var fs3 = require('fs');
4
4
  var path = require('path');
5
5
  var zod = require('zod');
6
6
 
@@ -22,7 +22,7 @@ function _interopNamespace(e) {
22
22
  return Object.freeze(n);
23
23
  }
24
24
 
25
- var fs2__namespace = /*#__PURE__*/_interopNamespace(fs2);
25
+ var fs3__namespace = /*#__PURE__*/_interopNamespace(fs3);
26
26
  var path__namespace = /*#__PURE__*/_interopNamespace(path);
27
27
 
28
28
  // src/migration/analyzer.ts
@@ -153,10 +153,10 @@ var FileSystemError = class _FileSystemError extends MigrationError {
153
153
  operation;
154
154
  code;
155
155
  originalError;
156
- constructor(message, path4, operation, code, originalError) {
156
+ constructor(message, path5, operation, code, originalError) {
157
157
  super(message);
158
158
  this.name = "FileSystemError";
159
- this.path = path4;
159
+ this.path = path5;
160
160
  this.operation = operation;
161
161
  this.code = code;
162
162
  this.originalError = originalError;
@@ -1379,10 +1379,10 @@ function discoverSchemaFiles(config) {
1379
1379
  const mergedConfig = mergeConfig(normalizedConfig);
1380
1380
  const schemaDir = resolveSchemaDir(normalizedConfig);
1381
1381
  try {
1382
- if (!fs2__namespace.existsSync(schemaDir)) {
1382
+ if (!fs3__namespace.existsSync(schemaDir)) {
1383
1383
  throw new FileSystemError(`Schema directory not found: ${schemaDir}`, schemaDir, "access", "ENOENT");
1384
1384
  }
1385
- const files = fs2__namespace.readdirSync(schemaDir);
1385
+ const files = fs3__namespace.readdirSync(schemaDir);
1386
1386
  const schemaFiles = files.filter((file) => {
1387
1387
  const hasValidExtension = mergedConfig.includeExtensions.some((ext) => file.endsWith(ext));
1388
1388
  if (!hasValidExtension) return false;
@@ -1432,9 +1432,9 @@ async function importSchemaModule(filePath, config) {
1432
1432
  let resolvedPath = null;
1433
1433
  const jsPath = `${importPath}.js`;
1434
1434
  const tsPath = `${importPath}.ts`;
1435
- if (fs2__namespace.existsSync(jsPath)) {
1435
+ if (fs3__namespace.existsSync(jsPath)) {
1436
1436
  resolvedPath = jsPath;
1437
- } else if (fs2__namespace.existsSync(tsPath)) {
1437
+ } else if (fs3__namespace.existsSync(tsPath)) {
1438
1438
  resolvedPath = tsPath;
1439
1439
  } else {
1440
1440
  resolvedPath = jsPath;
@@ -1444,7 +1444,7 @@ async function importSchemaModule(filePath, config) {
1444
1444
  return module;
1445
1445
  } catch (error) {
1446
1446
  const tsPath = `${filePath}.ts`;
1447
- const isTypeScriptFile = fs2__namespace.existsSync(tsPath);
1447
+ const isTypeScriptFile = fs3__namespace.existsSync(tsPath);
1448
1448
  if (isTypeScriptFile) {
1449
1449
  throw new SchemaParsingError(
1450
1450
  `Failed to import TypeScript schema file. Node.js cannot import TypeScript files directly.
@@ -1628,7 +1628,7 @@ async function buildSchemaDefinition(config) {
1628
1628
  importPath = normalizedConfig.pathTransformer(filePath);
1629
1629
  } else if (mergedConfig.useCompiledFiles) {
1630
1630
  const distPath = filePath.replace(/\/src\//, "/dist/");
1631
- if (fs2__namespace.existsSync(`${distPath}.js`) || fs2__namespace.existsSync(`${distPath}.mjs`)) {
1631
+ if (fs3__namespace.existsSync(`${distPath}.js`) || fs3__namespace.existsSync(`${distPath}.mjs`)) {
1632
1632
  importPath = distPath;
1633
1633
  } else {
1634
1634
  importPath = filePath;
@@ -1684,7 +1684,359 @@ var SchemaAnalyzer = class {
1684
1684
  return convertZodSchemaToCollectionSchema(name, schema);
1685
1685
  }
1686
1686
  };
1687
+
1688
+ // src/migration/pocketbase-converter.ts
1687
1689
  var SNAPSHOT_VERSION = "1.0.0";
1690
+ function resolveCollectionIdToName(collectionId) {
1691
+ if (collectionId === "_pb_users_auth_") {
1692
+ return "Users";
1693
+ }
1694
+ const nameMatch = collectionId.match(/app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\)/);
1695
+ if (nameMatch) {
1696
+ return nameMatch[1];
1697
+ }
1698
+ return collectionId;
1699
+ }
1700
+ function convertPocketBaseCollection(pbCollection) {
1701
+ const fields = [];
1702
+ const systemFieldNames = ["id", "created", "updated", "collectionId", "collectionName", "expand"];
1703
+ const authSystemFieldNames = ["email", "emailVisibility", "verified", "password", "tokenKey"];
1704
+ if (pbCollection.fields && Array.isArray(pbCollection.fields)) {
1705
+ for (const pbField of pbCollection.fields) {
1706
+ if (pbField.system || systemFieldNames.includes(pbField.name)) {
1707
+ continue;
1708
+ }
1709
+ if (pbCollection.type === "auth" && authSystemFieldNames.includes(pbField.name)) {
1710
+ continue;
1711
+ }
1712
+ const field = {
1713
+ name: pbField.name,
1714
+ type: pbField.type,
1715
+ required: pbField.required || false
1716
+ };
1717
+ field.options = pbField.options ? { ...pbField.options } : {};
1718
+ if (pbField.type === "select") {
1719
+ if (pbField.values && Array.isArray(pbField.values)) {
1720
+ field.options.values = pbField.values;
1721
+ } else if (pbField.options?.values && Array.isArray(pbField.options.values)) {
1722
+ field.options.values = pbField.options.values;
1723
+ }
1724
+ }
1725
+ if (pbField.type === "relation") {
1726
+ const collectionId = pbField.collectionId || pbField.options?.collectionId || "";
1727
+ const collectionName = resolveCollectionIdToName(collectionId);
1728
+ field.relation = {
1729
+ collection: collectionName,
1730
+ cascadeDelete: pbField.cascadeDelete ?? pbField.options?.cascadeDelete ?? false,
1731
+ maxSelect: pbField.maxSelect ?? pbField.options?.maxSelect,
1732
+ minSelect: pbField.minSelect ?? pbField.options?.minSelect
1733
+ };
1734
+ }
1735
+ const hasOnlyValues = Object.keys(field.options).length === 1 && field.options.values !== void 0;
1736
+ if (Object.keys(field.options).length === 0) {
1737
+ delete field.options;
1738
+ } else if (pbField.type === "select" && hasOnlyValues) ;
1739
+ fields.push(field);
1740
+ }
1741
+ }
1742
+ const schema = {
1743
+ name: pbCollection.name,
1744
+ type: pbCollection.type || "base",
1745
+ fields
1746
+ };
1747
+ if (pbCollection.indexes && Array.isArray(pbCollection.indexes)) {
1748
+ schema.indexes = pbCollection.indexes;
1749
+ }
1750
+ const rules = {};
1751
+ if (pbCollection.listRule !== void 0) rules.listRule = pbCollection.listRule;
1752
+ if (pbCollection.viewRule !== void 0) rules.viewRule = pbCollection.viewRule;
1753
+ if (pbCollection.createRule !== void 0) rules.createRule = pbCollection.createRule;
1754
+ if (pbCollection.updateRule !== void 0) rules.updateRule = pbCollection.updateRule;
1755
+ if (pbCollection.deleteRule !== void 0) rules.deleteRule = pbCollection.deleteRule;
1756
+ if (pbCollection.manageRule !== void 0) rules.manageRule = pbCollection.manageRule;
1757
+ if (Object.keys(rules).length > 0) {
1758
+ schema.rules = rules;
1759
+ schema.permissions = { ...rules };
1760
+ }
1761
+ return schema;
1762
+ }
1763
+ function convertPocketBaseMigration(migrationContent) {
1764
+ try {
1765
+ const snapshotMatch = migrationContent.match(/const\s+snapshot\s*=\s*(\[[\s\S]*?\]);/);
1766
+ if (!snapshotMatch) {
1767
+ throw new Error("Could not find snapshot array in migration file");
1768
+ }
1769
+ const snapshotArrayStr = snapshotMatch[1];
1770
+ let snapshotArray;
1771
+ try {
1772
+ snapshotArray = new Function(`return ${snapshotArrayStr}`)();
1773
+ } catch (parseError) {
1774
+ throw new Error(`Failed to parse snapshot array: ${parseError}`);
1775
+ }
1776
+ if (!Array.isArray(snapshotArray)) {
1777
+ throw new Error("Snapshot is not an array");
1778
+ }
1779
+ const collections = /* @__PURE__ */ new Map();
1780
+ for (const pbCollection of snapshotArray) {
1781
+ if (!pbCollection.name) {
1782
+ console.warn("Skipping collection without name");
1783
+ continue;
1784
+ }
1785
+ const schema = convertPocketBaseCollection(pbCollection);
1786
+ collections.set(pbCollection.name, schema);
1787
+ }
1788
+ return {
1789
+ version: SNAPSHOT_VERSION,
1790
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1791
+ collections
1792
+ };
1793
+ } catch (error) {
1794
+ throw new SnapshotError(
1795
+ `Failed to convert PocketBase migration: ${error instanceof Error ? error.message : String(error)}`,
1796
+ void 0,
1797
+ "parse",
1798
+ error instanceof Error ? error : void 0
1799
+ );
1800
+ }
1801
+ }
1802
+
1803
+ // src/migration/migration-parser.ts
1804
+ function extractTimestampFromFilename(filename) {
1805
+ const match = filename.match(/^(\d+)_/);
1806
+ if (match) {
1807
+ return parseInt(match[1], 10);
1808
+ }
1809
+ return null;
1810
+ }
1811
+ function findMigrationsAfterSnapshot(migrationsPath, snapshotTimestamp) {
1812
+ try {
1813
+ if (!fs3__namespace.existsSync(migrationsPath)) {
1814
+ return [];
1815
+ }
1816
+ const files = fs3__namespace.readdirSync(migrationsPath);
1817
+ const migrationFiles = [];
1818
+ for (const file of files) {
1819
+ if (file.endsWith("_collections_snapshot.js") || file.endsWith("_snapshot.js")) {
1820
+ continue;
1821
+ }
1822
+ if (!file.endsWith(".js")) {
1823
+ continue;
1824
+ }
1825
+ const timestamp = extractTimestampFromFilename(file);
1826
+ if (timestamp && timestamp > snapshotTimestamp) {
1827
+ migrationFiles.push({
1828
+ path: path__namespace.join(migrationsPath, file),
1829
+ timestamp
1830
+ });
1831
+ }
1832
+ }
1833
+ migrationFiles.sort((a, b) => a.timestamp - b.timestamp);
1834
+ return migrationFiles.map((f) => f.path);
1835
+ } catch (error) {
1836
+ console.warn(`Error finding migrations after snapshot: ${error}`);
1837
+ return [];
1838
+ }
1839
+ }
1840
+ function parseMigrationOperationsFromContent(content) {
1841
+ const collectionsToCreate = [];
1842
+ const collectionsToDelete = [];
1843
+ try {
1844
+ let searchIndex = 0;
1845
+ while (true) {
1846
+ const collectionStart = content.indexOf("new Collection(", searchIndex);
1847
+ if (collectionStart === -1) {
1848
+ break;
1849
+ }
1850
+ const openParen = collectionStart + "new Collection(".length;
1851
+ let braceCount = 0;
1852
+ let parenCount = 1;
1853
+ let inString = false;
1854
+ let stringChar = null;
1855
+ let i = openParen;
1856
+ while (i < content.length && /\s/.test(content[i])) {
1857
+ i++;
1858
+ }
1859
+ if (content[i] !== "{") {
1860
+ searchIndex = i + 1;
1861
+ continue;
1862
+ }
1863
+ const objectStart = i;
1864
+ braceCount = 1;
1865
+ i++;
1866
+ while (i < content.length && (braceCount > 0 || parenCount > 0)) {
1867
+ const char = content[i];
1868
+ const prevChar = i > 0 ? content[i - 1] : "";
1869
+ if (!inString && (char === '"' || char === "'")) {
1870
+ inString = true;
1871
+ stringChar = char;
1872
+ } else if (inString && char === stringChar && prevChar !== "\\") {
1873
+ inString = false;
1874
+ stringChar = null;
1875
+ }
1876
+ if (!inString) {
1877
+ if (char === "{") braceCount++;
1878
+ if (char === "}") braceCount--;
1879
+ if (char === "(") parenCount++;
1880
+ if (char === ")") parenCount--;
1881
+ }
1882
+ i++;
1883
+ }
1884
+ if (braceCount === 0 && parenCount === 0) {
1885
+ const objectContent = content.substring(objectStart, i - 1);
1886
+ try {
1887
+ const collectionObj = new Function(`return ${objectContent}`)();
1888
+ if (collectionObj && collectionObj.name) {
1889
+ const schema = convertPocketBaseCollection(collectionObj);
1890
+ collectionsToCreate.push(schema);
1891
+ }
1892
+ } catch (error) {
1893
+ console.warn(`Failed to parse collection definition: ${error}`);
1894
+ }
1895
+ }
1896
+ searchIndex = i;
1897
+ }
1898
+ const deleteMatches = content.matchAll(
1899
+ /app\.delete\s*\(\s*(?:collection_\w+|app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\))\s*\)/g
1900
+ );
1901
+ for (const match of deleteMatches) {
1902
+ if (match[1]) {
1903
+ collectionsToDelete.push(match[1]);
1904
+ } else {
1905
+ const varNameMatch = match[0].match(/collection_(\w+)/);
1906
+ if (varNameMatch) {
1907
+ const varName = `collection_${varNameMatch[1]}`;
1908
+ const deleteIndex = content.indexOf(match[0]);
1909
+ const beforeDelete = content.substring(0, deleteIndex);
1910
+ const varDefMatch = beforeDelete.match(
1911
+ new RegExp(`const\\s+${varName}\\s*=\\s*new\\s+Collection\\(\\s*(\\{[\\s\\S]*?\\})\\s*\\)`, "g")
1912
+ );
1913
+ if (varDefMatch && varDefMatch.length > 0) {
1914
+ const collectionDefMatch = beforeDelete.match(
1915
+ new RegExp(`const\\s+${varName}\\s*=\\s*new\\s+Collection\\(\\s*(\\{[\\s\\S]*?\\})\\s*\\)`)
1916
+ );
1917
+ if (collectionDefMatch) {
1918
+ try {
1919
+ const collectionDefStr = collectionDefMatch[1];
1920
+ const collectionObj = new Function(`return ${collectionDefStr}`)();
1921
+ if (collectionObj && collectionObj.name) {
1922
+ collectionsToDelete.push(collectionObj.name);
1923
+ }
1924
+ } catch {
1925
+ }
1926
+ }
1927
+ }
1928
+ }
1929
+ }
1930
+ }
1931
+ const findAndDeleteMatches = content.matchAll(
1932
+ /app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\)[\s\S]*?app\.delete/g
1933
+ );
1934
+ for (const match of findAndDeleteMatches) {
1935
+ collectionsToDelete.push(match[1]);
1936
+ }
1937
+ } catch (error) {
1938
+ console.warn(`Failed to parse migration operations from content: ${error}`);
1939
+ }
1940
+ return { collectionsToCreate, collectionsToDelete };
1941
+ }
1942
+ function parseMigrationOperations(migrationContent) {
1943
+ try {
1944
+ const migrateMatch = migrationContent.match(/migrate\s*\(\s*/);
1945
+ if (!migrateMatch) {
1946
+ return parseMigrationOperationsFromContent(migrationContent);
1947
+ }
1948
+ const startIndex = migrateMatch.index + migrateMatch[0].length;
1949
+ let i = startIndex;
1950
+ let parenCount = 0;
1951
+ let foundFirstParen = false;
1952
+ while (i < migrationContent.length) {
1953
+ const char = migrationContent[i];
1954
+ if (char === "(") {
1955
+ parenCount++;
1956
+ foundFirstParen = true;
1957
+ i++;
1958
+ break;
1959
+ }
1960
+ i++;
1961
+ }
1962
+ if (!foundFirstParen) {
1963
+ return parseMigrationOperationsFromContent(migrationContent);
1964
+ }
1965
+ let inString = false;
1966
+ let stringChar = null;
1967
+ let foundBrace = false;
1968
+ let braceStart = -1;
1969
+ while (i < migrationContent.length && !foundBrace) {
1970
+ const char = migrationContent[i];
1971
+ const prevChar = i > 0 ? migrationContent[i - 1] : "";
1972
+ if (!inString && (char === '"' || char === "'")) {
1973
+ inString = true;
1974
+ stringChar = char;
1975
+ } else if (inString && char === stringChar && prevChar !== "\\") {
1976
+ inString = false;
1977
+ stringChar = null;
1978
+ }
1979
+ if (!inString) {
1980
+ if (char === "(") parenCount++;
1981
+ if (char === ")") {
1982
+ parenCount--;
1983
+ if (parenCount === 0) {
1984
+ i++;
1985
+ while (i < migrationContent.length && /\s/.test(migrationContent[i])) {
1986
+ i++;
1987
+ }
1988
+ if (i < migrationContent.length - 1 && migrationContent[i] === "=" && migrationContent[i + 1] === ">") {
1989
+ i += 2;
1990
+ while (i < migrationContent.length && /\s/.test(migrationContent[i])) {
1991
+ i++;
1992
+ }
1993
+ if (i < migrationContent.length && migrationContent[i] === "{") {
1994
+ foundBrace = true;
1995
+ braceStart = i + 1;
1996
+ break;
1997
+ }
1998
+ }
1999
+ }
2000
+ }
2001
+ }
2002
+ i++;
2003
+ }
2004
+ if (!foundBrace || braceStart === -1) {
2005
+ return parseMigrationOperationsFromContent(migrationContent);
2006
+ }
2007
+ let braceCount = 1;
2008
+ i = braceStart;
2009
+ inString = false;
2010
+ stringChar = null;
2011
+ while (i < migrationContent.length && braceCount > 0) {
2012
+ const char = migrationContent[i];
2013
+ const prevChar = i > 0 ? migrationContent[i - 1] : "";
2014
+ if (!inString && (char === '"' || char === "'")) {
2015
+ inString = true;
2016
+ stringChar = char;
2017
+ } else if (inString && char === stringChar && prevChar !== "\\") {
2018
+ inString = false;
2019
+ stringChar = null;
2020
+ }
2021
+ if (!inString) {
2022
+ if (char === "{") braceCount++;
2023
+ if (char === "}") braceCount--;
2024
+ }
2025
+ i++;
2026
+ }
2027
+ if (braceCount === 0) {
2028
+ const upMigrationContent = migrationContent.substring(braceStart, i - 1);
2029
+ return parseMigrationOperationsFromContent(upMigrationContent);
2030
+ }
2031
+ return parseMigrationOperationsFromContent(migrationContent);
2032
+ } catch (error) {
2033
+ console.warn(`Failed to parse migration operations: ${error}`);
2034
+ return { collectionsToCreate: [], collectionsToDelete: [] };
2035
+ }
2036
+ }
2037
+
2038
+ // src/migration/snapshot.ts
2039
+ var SNAPSHOT_VERSION2 = "1.0.0";
1688
2040
  var DEFAULT_SNAPSHOT_FILENAME = ".migration-snapshot.json";
1689
2041
  var SNAPSHOT_MIGRATIONS = [
1690
2042
  // Add migrations here as the format evolves
@@ -1699,7 +2051,7 @@ var DEFAULT_CONFIG2 = {
1699
2051
  snapshotPath: DEFAULT_SNAPSHOT_FILENAME,
1700
2052
  workspaceRoot: process.cwd(),
1701
2053
  autoMigrate: true,
1702
- version: SNAPSHOT_VERSION
2054
+ version: SNAPSHOT_VERSION2
1703
2055
  };
1704
2056
  function mergeConfig2(config = {}) {
1705
2057
  return {
@@ -1719,7 +2071,7 @@ function getSnapshotPath(config = {}) {
1719
2071
  function snapshotExists(config = {}) {
1720
2072
  try {
1721
2073
  const snapshotPath = getSnapshotPath(config);
1722
- return fs2__namespace.existsSync(snapshotPath);
2074
+ return fs3__namespace.existsSync(snapshotPath);
1723
2075
  } catch {
1724
2076
  return false;
1725
2077
  }
@@ -1779,12 +2131,12 @@ function saveSnapshot(schema, config = {}) {
1779
2131
  const snapshotPath = getSnapshotPath(config);
1780
2132
  try {
1781
2133
  const snapshotDir = path__namespace.dirname(snapshotPath);
1782
- if (!fs2__namespace.existsSync(snapshotDir)) {
1783
- fs2__namespace.mkdirSync(snapshotDir, { recursive: true });
2134
+ if (!fs3__namespace.existsSync(snapshotDir)) {
2135
+ fs3__namespace.mkdirSync(snapshotDir, { recursive: true });
1784
2136
  }
1785
2137
  const snapshotData = addSnapshotMetadata(schema, config);
1786
2138
  const jsonContent = JSON.stringify(snapshotData, null, 2);
1787
- fs2__namespace.writeFileSync(snapshotPath, jsonContent, "utf-8");
2139
+ fs3__namespace.writeFileSync(snapshotPath, jsonContent, "utf-8");
1788
2140
  } catch (error) {
1789
2141
  handleFileSystemError(error, "write", snapshotPath);
1790
2142
  }
@@ -1879,7 +2231,7 @@ function deserializeSnapshot(data) {
1879
2231
  function loadSnapshot(config = {}) {
1880
2232
  const snapshotPath = getSnapshotPath(config);
1881
2233
  try {
1882
- const jsonContent = fs2__namespace.readFileSync(snapshotPath, "utf-8");
2234
+ const jsonContent = fs3__namespace.readFileSync(snapshotPath, "utf-8");
1883
2235
  const data = parseAndValidateSnapshot(jsonContent, snapshotPath);
1884
2236
  const migratedData = migrateSnapshotFormat(data, config);
1885
2237
  return deserializeSnapshot(migratedData);
@@ -1914,10 +2266,10 @@ function mergeSnapshots(baseSnapshot, customSnapshot) {
1914
2266
  }
1915
2267
  function findLatestSnapshot(migrationsPath) {
1916
2268
  try {
1917
- if (!fs2__namespace.existsSync(migrationsPath)) {
2269
+ if (!fs3__namespace.existsSync(migrationsPath)) {
1918
2270
  return null;
1919
2271
  }
1920
- const files = fs2__namespace.readdirSync(migrationsPath);
2272
+ const files = fs3__namespace.readdirSync(migrationsPath);
1921
2273
  const snapshotFiles = files.filter(
1922
2274
  (file) => file.endsWith("_collections_snapshot.js") || file.endsWith("_snapshot.js")
1923
2275
  );
@@ -1935,14 +2287,68 @@ function findLatestSnapshot(migrationsPath) {
1935
2287
  return null;
1936
2288
  }
1937
2289
  }
2290
+ function applyMigrationOperations(snapshot, operations) {
2291
+ const updatedCollections = new Map(snapshot.collections);
2292
+ for (const collectionName of operations.collectionsToDelete) {
2293
+ updatedCollections.delete(collectionName);
2294
+ }
2295
+ for (const collection of operations.collectionsToCreate) {
2296
+ updatedCollections.set(collection.name, collection);
2297
+ }
2298
+ return {
2299
+ ...snapshot,
2300
+ collections: updatedCollections
2301
+ };
2302
+ }
2303
+ function loadSnapshotWithMigrations(config = {}) {
2304
+ const migrationsPath = config.migrationsPath;
2305
+ if (!migrationsPath) {
2306
+ return null;
2307
+ }
2308
+ if (fs3__namespace.existsSync(migrationsPath) && fs3__namespace.statSync(migrationsPath).isFile()) {
2309
+ try {
2310
+ const migrationContent = fs3__namespace.readFileSync(migrationsPath, "utf-8");
2311
+ return convertPocketBaseMigration(migrationContent);
2312
+ } catch (error) {
2313
+ console.warn(`Failed to load snapshot from ${migrationsPath}: ${error}`);
2314
+ return null;
2315
+ }
2316
+ }
2317
+ const latestSnapshotPath = findLatestSnapshot(migrationsPath);
2318
+ if (!latestSnapshotPath) {
2319
+ return null;
2320
+ }
2321
+ try {
2322
+ const migrationContent = fs3__namespace.readFileSync(latestSnapshotPath, "utf-8");
2323
+ let snapshot = convertPocketBaseMigration(migrationContent);
2324
+ const snapshotFilename = path__namespace.basename(latestSnapshotPath);
2325
+ const snapshotTimestamp = extractTimestampFromFilename(snapshotFilename);
2326
+ if (snapshotTimestamp) {
2327
+ const migrationFiles = findMigrationsAfterSnapshot(migrationsPath, snapshotTimestamp);
2328
+ for (const migrationFile of migrationFiles) {
2329
+ try {
2330
+ const migrationContent2 = fs3__namespace.readFileSync(migrationFile, "utf-8");
2331
+ const operations = parseMigrationOperations(migrationContent2);
2332
+ snapshot = applyMigrationOperations(snapshot, operations);
2333
+ } catch (error) {
2334
+ console.warn(`Failed to apply migration ${migrationFile}: ${error}`);
2335
+ }
2336
+ }
2337
+ }
2338
+ return snapshot;
2339
+ } catch (error) {
2340
+ console.warn(`Failed to load snapshot from ${latestSnapshotPath}: ${error}`);
2341
+ return null;
2342
+ }
2343
+ }
1938
2344
  function loadSnapshotIfExists(config = {}) {
1939
2345
  const migrationsPath = config.migrationsPath;
1940
2346
  if (!migrationsPath) {
1941
2347
  return null;
1942
2348
  }
1943
- if (fs2__namespace.existsSync(migrationsPath) && fs2__namespace.statSync(migrationsPath).isFile()) {
2349
+ if (fs3__namespace.existsSync(migrationsPath) && fs3__namespace.statSync(migrationsPath).isFile()) {
1944
2350
  try {
1945
- const migrationContent = fs2__namespace.readFileSync(migrationsPath, "utf-8");
2351
+ const migrationContent = fs3__namespace.readFileSync(migrationsPath, "utf-8");
1946
2352
  return convertPocketBaseMigration(migrationContent);
1947
2353
  } catch (error) {
1948
2354
  console.warn(`Failed to load snapshot from ${migrationsPath}: ${error}`);
@@ -1952,7 +2358,7 @@ function loadSnapshotIfExists(config = {}) {
1952
2358
  const latestSnapshotPath = findLatestSnapshot(migrationsPath);
1953
2359
  if (latestSnapshotPath) {
1954
2360
  try {
1955
- const migrationContent = fs2__namespace.readFileSync(latestSnapshotPath, "utf-8");
2361
+ const migrationContent = fs3__namespace.readFileSync(latestSnapshotPath, "utf-8");
1956
2362
  return convertPocketBaseMigration(migrationContent);
1957
2363
  } catch (error) {
1958
2364
  console.warn(`Failed to load snapshot from ${latestSnapshotPath}: ${error}`);
@@ -1961,100 +2367,9 @@ function loadSnapshotIfExists(config = {}) {
1961
2367
  }
1962
2368
  return null;
1963
2369
  }
1964
- function convertPocketBaseCollection(pbCollection) {
1965
- const fields = [];
1966
- const systemFieldNames = ["id", "created", "updated", "collectionId", "collectionName", "expand"];
1967
- const authSystemFieldNames = ["email", "emailVisibility", "verified", "password", "tokenKey"];
1968
- if (pbCollection.fields && Array.isArray(pbCollection.fields)) {
1969
- for (const pbField of pbCollection.fields) {
1970
- if (pbField.system || systemFieldNames.includes(pbField.name)) {
1971
- continue;
1972
- }
1973
- if (pbCollection.type === "auth" && authSystemFieldNames.includes(pbField.name)) {
1974
- continue;
1975
- }
1976
- const field = {
1977
- name: pbField.name,
1978
- type: pbField.type,
1979
- required: pbField.required || false
1980
- };
1981
- if (pbField.options) {
1982
- field.options = pbField.options;
1983
- }
1984
- if (pbField.type === "relation") {
1985
- field.relation = {
1986
- collection: pbField.options?.collectionId || "",
1987
- cascadeDelete: pbField.options?.cascadeDelete || false,
1988
- maxSelect: pbField.options?.maxSelect,
1989
- minSelect: pbField.options?.minSelect
1990
- };
1991
- }
1992
- fields.push(field);
1993
- }
1994
- }
1995
- const schema = {
1996
- name: pbCollection.name,
1997
- type: pbCollection.type || "base",
1998
- fields
1999
- };
2000
- if (pbCollection.indexes && Array.isArray(pbCollection.indexes)) {
2001
- schema.indexes = pbCollection.indexes;
2002
- }
2003
- const rules = {};
2004
- if (pbCollection.listRule !== void 0) rules.listRule = pbCollection.listRule;
2005
- if (pbCollection.viewRule !== void 0) rules.viewRule = pbCollection.viewRule;
2006
- if (pbCollection.createRule !== void 0) rules.createRule = pbCollection.createRule;
2007
- if (pbCollection.updateRule !== void 0) rules.updateRule = pbCollection.updateRule;
2008
- if (pbCollection.deleteRule !== void 0) rules.deleteRule = pbCollection.deleteRule;
2009
- if (pbCollection.manageRule !== void 0) rules.manageRule = pbCollection.manageRule;
2010
- if (Object.keys(rules).length > 0) {
2011
- schema.rules = rules;
2012
- schema.permissions = { ...rules };
2013
- }
2014
- return schema;
2015
- }
2016
- function convertPocketBaseMigration(migrationContent) {
2017
- try {
2018
- const snapshotMatch = migrationContent.match(/const\s+snapshot\s*=\s*(\[[\s\S]*?\]);/);
2019
- if (!snapshotMatch) {
2020
- throw new Error("Could not find snapshot array in migration file");
2021
- }
2022
- const snapshotArrayStr = snapshotMatch[1];
2023
- let snapshotArray;
2024
- try {
2025
- snapshotArray = new Function(`return ${snapshotArrayStr}`)();
2026
- } catch (parseError) {
2027
- throw new Error(`Failed to parse snapshot array: ${parseError}`);
2028
- }
2029
- if (!Array.isArray(snapshotArray)) {
2030
- throw new Error("Snapshot is not an array");
2031
- }
2032
- const collections = /* @__PURE__ */ new Map();
2033
- for (const pbCollection of snapshotArray) {
2034
- if (!pbCollection.name) {
2035
- console.warn("Skipping collection without name");
2036
- continue;
2037
- }
2038
- const schema = convertPocketBaseCollection(pbCollection);
2039
- collections.set(pbCollection.name, schema);
2040
- }
2041
- return {
2042
- version: SNAPSHOT_VERSION,
2043
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2044
- collections
2045
- };
2046
- } catch (error) {
2047
- throw new SnapshotError(
2048
- `Failed to convert PocketBase migration: ${error instanceof Error ? error.message : String(error)}`,
2049
- void 0,
2050
- "parse",
2051
- error instanceof Error ? error : void 0
2052
- );
2053
- }
2054
- }
2055
2370
  function loadBaseMigration(migrationPath) {
2056
2371
  try {
2057
- if (!fs2__namespace.existsSync(migrationPath)) {
2372
+ if (!fs3__namespace.existsSync(migrationPath)) {
2058
2373
  throw new SnapshotError(
2059
2374
  `Base migration file not found: ${migrationPath}
2060
2375
 
@@ -2065,7 +2380,7 @@ If the file exists in a different location, update the configuration.`,
2065
2380
  "read"
2066
2381
  );
2067
2382
  }
2068
- const migrationContent = fs2__namespace.readFileSync(migrationPath, "utf-8");
2383
+ const migrationContent = fs3__namespace.readFileSync(migrationPath, "utf-8");
2069
2384
  const snapshot = convertPocketBaseMigration(migrationContent);
2070
2385
  return snapshot;
2071
2386
  } catch (error) {
@@ -2101,14 +2416,14 @@ Please ensure PocketBase is properly set up by running 'yarn setup'.`,
2101
2416
  }
2102
2417
  }
2103
2418
  function getSnapshotVersion() {
2104
- return SNAPSHOT_VERSION;
2419
+ return SNAPSHOT_VERSION2;
2105
2420
  }
2106
2421
  function validateSnapshot(snapshot) {
2107
2422
  const issues = [];
2108
2423
  if (!snapshot.version) {
2109
2424
  issues.push("Missing version field");
2110
- } else if (compareVersions(snapshot.version, SNAPSHOT_VERSION) > 0) {
2111
- issues.push(`Snapshot version ${snapshot.version} is newer than supported version ${SNAPSHOT_VERSION}`);
2425
+ } else if (compareVersions(snapshot.version, SNAPSHOT_VERSION2) > 0) {
2426
+ issues.push(`Snapshot version ${snapshot.version} is newer than supported version ${SNAPSHOT_VERSION2}`);
2112
2427
  }
2113
2428
  if (!snapshot.timestamp) {
2114
2429
  issues.push("Missing timestamp field");
@@ -2327,6 +2642,9 @@ function compareFieldOptions(currentField, previousField) {
2327
2642
  for (const key of allKeys) {
2328
2643
  const currentValue = currentOptions[key];
2329
2644
  const previousValue = previousOptions[key];
2645
+ if (currentValue === void 0 && previousValue === void 0) {
2646
+ continue;
2647
+ }
2330
2648
  if (!areValuesEqual(currentValue, previousValue)) {
2331
2649
  changes.push({
2332
2650
  property: `options.${key}`,
@@ -2347,11 +2665,26 @@ function compareRelationConfigurations(currentField, previousField) {
2347
2665
  if (!currentRelation || !previousRelation) {
2348
2666
  return changes;
2349
2667
  }
2350
- if (currentRelation.collection !== previousRelation.collection) {
2668
+ const normalizeCollection = (collection) => {
2669
+ if (!collection) return collection;
2670
+ if (collection === "_pb_users_auth_") {
2671
+ return "Users";
2672
+ }
2673
+ const nameMatch = collection.match(/app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\)/);
2674
+ if (nameMatch) {
2675
+ return nameMatch[1];
2676
+ }
2677
+ return collection;
2678
+ };
2679
+ const normalizedCurrent = normalizeCollection(currentRelation.collection);
2680
+ const normalizedPrevious = normalizeCollection(previousRelation.collection);
2681
+ if (normalizedCurrent !== normalizedPrevious) {
2351
2682
  changes.push({
2352
2683
  property: "relation.collection",
2353
- oldValue: previousRelation.collection,
2354
- newValue: currentRelation.collection
2684
+ oldValue: normalizedPrevious,
2685
+ // Use normalized value for clarity
2686
+ newValue: normalizedCurrent
2687
+ // Use normalized value for clarity
2355
2688
  });
2356
2689
  }
2357
2690
  if (currentRelation.cascadeDelete !== previousRelation.cascadeDelete) {
@@ -2785,9 +3118,9 @@ function createMigrationFileStructure(upCode, downCode, config) {
2785
3118
  }
2786
3119
  function writeMigrationFile(migrationDir, filename, content) {
2787
3120
  try {
2788
- if (!fs2__namespace.existsSync(migrationDir)) {
3121
+ if (!fs3__namespace.existsSync(migrationDir)) {
2789
3122
  try {
2790
- fs2__namespace.mkdirSync(migrationDir, { recursive: true });
3123
+ fs3__namespace.mkdirSync(migrationDir, { recursive: true });
2791
3124
  } catch (error) {
2792
3125
  const fsError = error;
2793
3126
  if (fsError.code === "EACCES" || fsError.code === "EPERM") {
@@ -2809,7 +3142,7 @@ function writeMigrationFile(migrationDir, filename, content) {
2809
3142
  }
2810
3143
  }
2811
3144
  const filePath = path__namespace.join(migrationDir, filename);
2812
- fs2__namespace.writeFileSync(filePath, content, "utf-8");
3145
+ fs3__namespace.writeFileSync(filePath, content, "utf-8");
2813
3146
  return filePath;
2814
3147
  } catch (error) {
2815
3148
  if (error instanceof FileSystemError) {
@@ -3472,6 +3805,7 @@ exports.isSystemCollection = isSystemCollection;
3472
3805
  exports.loadBaseMigration = loadBaseMigration;
3473
3806
  exports.loadSnapshot = loadSnapshot;
3474
3807
  exports.loadSnapshotIfExists = loadSnapshotIfExists;
3808
+ exports.loadSnapshotWithMigrations = loadSnapshotWithMigrations;
3475
3809
  exports.mapZodArrayType = mapZodArrayType;
3476
3810
  exports.mapZodBooleanType = mapZodBooleanType;
3477
3811
  exports.mapZodDateType = mapZodDateType;