pocketbase-zod-schema 0.1.2 → 0.1.3

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 (63) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +329 -99
  3. package/dist/cli/index.cjs +176 -55
  4. package/dist/cli/index.cjs.map +1 -1
  5. package/dist/cli/index.js +176 -55
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/cli/migrate.cjs +196 -58
  8. package/dist/cli/migrate.cjs.map +1 -1
  9. package/dist/cli/migrate.js +194 -57
  10. package/dist/cli/migrate.js.map +1 -1
  11. package/dist/cli/utils/index.cjs +1 -1
  12. package/dist/cli/utils/index.cjs.map +1 -1
  13. package/dist/cli/utils/index.js +1 -1
  14. package/dist/cli/utils/index.js.map +1 -1
  15. package/dist/index.cjs +197 -96
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.cts +3 -3
  18. package/dist/index.d.ts +3 -3
  19. package/dist/index.js +197 -95
  20. package/dist/index.js.map +1 -1
  21. package/dist/migration/analyzer.cjs +101 -28
  22. package/dist/migration/analyzer.cjs.map +1 -1
  23. package/dist/migration/analyzer.js +101 -28
  24. package/dist/migration/analyzer.js.map +1 -1
  25. package/dist/migration/generator.cjs +60 -25
  26. package/dist/migration/generator.cjs.map +1 -1
  27. package/dist/migration/generator.d.cts +9 -5
  28. package/dist/migration/generator.d.ts +9 -5
  29. package/dist/migration/generator.js +60 -25
  30. package/dist/migration/generator.js.map +1 -1
  31. package/dist/migration/index.cjs +162 -53
  32. package/dist/migration/index.cjs.map +1 -1
  33. package/dist/migration/index.js +162 -53
  34. package/dist/migration/index.js.map +1 -1
  35. package/dist/migration/snapshot.cjs +1 -0
  36. package/dist/migration/snapshot.cjs.map +1 -1
  37. package/dist/migration/snapshot.js +1 -0
  38. package/dist/migration/snapshot.js.map +1 -1
  39. package/dist/migration/utils/index.cjs +19 -17
  40. package/dist/migration/utils/index.cjs.map +1 -1
  41. package/dist/migration/utils/index.d.cts +3 -1
  42. package/dist/migration/utils/index.d.ts +3 -1
  43. package/dist/migration/utils/index.js +19 -17
  44. package/dist/migration/utils/index.js.map +1 -1
  45. package/dist/mutator.cjs +9 -11
  46. package/dist/mutator.cjs.map +1 -1
  47. package/dist/mutator.d.cts +5 -9
  48. package/dist/mutator.d.ts +5 -9
  49. package/dist/mutator.js +9 -11
  50. package/dist/mutator.js.map +1 -1
  51. package/dist/schema.cjs +50 -53
  52. package/dist/schema.cjs.map +1 -1
  53. package/dist/schema.d.cts +94 -12
  54. package/dist/schema.d.ts +94 -12
  55. package/dist/schema.js +50 -52
  56. package/dist/schema.js.map +1 -1
  57. package/dist/types.d.cts +2 -5
  58. package/dist/types.d.ts +2 -5
  59. package/dist/user-C39DQ40N.d.cts +53 -0
  60. package/dist/user-C39DQ40N.d.ts +53 -0
  61. package/package.json +2 -3
  62. package/dist/user-jS1aYoeD.d.cts +0 -123
  63. package/dist/user-jS1aYoeD.d.ts +0 -123
@@ -3,8 +3,9 @@
3
3
 
4
4
  var chalk = require('chalk');
5
5
  var commander = require('commander');
6
- var path4 = require('path');
7
6
  var fs4 = require('fs');
7
+ var path4 = require('path');
8
+ var url = require('url');
8
9
  var zod = require('zod');
9
10
  var ora = require('ora');
10
11
 
@@ -29,10 +30,43 @@ function _interopNamespace(e) {
29
30
  }
30
31
 
31
32
  var chalk__default = /*#__PURE__*/_interopDefault(chalk);
32
- var path4__namespace = /*#__PURE__*/_interopNamespace(path4);
33
33
  var fs4__namespace = /*#__PURE__*/_interopNamespace(fs4);
34
+ var path4__namespace = /*#__PURE__*/_interopNamespace(path4);
34
35
  var ora__default = /*#__PURE__*/_interopDefault(ora);
35
36
 
37
+ // ../node_modules/tsup/assets/cjs_shims.js
38
+ var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
39
+ var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
40
+ ({
41
+ id: zod.z.string().describe("unique id"),
42
+ collectionId: zod.z.string().describe("collection id"),
43
+ collectionName: zod.z.string().describe("collection name"),
44
+ expand: zod.z.record(zod.z.any()).describe("expandable fields")
45
+ });
46
+ ({
47
+ created: zod.z.string().describe("creation timestamp"),
48
+ updated: zod.z.string().describe("last update timestamp")
49
+ });
50
+ ({
51
+ thumbnailURL: zod.z.string().optional(),
52
+ imageFiles: zod.z.array(zod.z.string())
53
+ });
54
+ ({
55
+ imageFiles: zod.z.array(zod.z.instanceof(File))
56
+ });
57
+ var RELATION_METADATA_KEY = "__pocketbase_relation__";
58
+ function extractRelationMetadata(description) {
59
+ if (!description) return null;
60
+ try {
61
+ const parsed = JSON.parse(description);
62
+ if (parsed[RELATION_METADATA_KEY]) {
63
+ return parsed[RELATION_METADATA_KEY];
64
+ }
65
+ } catch {
66
+ }
67
+ return null;
68
+ }
69
+
36
70
  // src/migration/errors.ts
37
71
  var MigrationError = class _MigrationError extends Error {
38
72
  constructor(message) {
@@ -196,7 +230,7 @@ Cause: ${this.originalError.message}`);
196
230
  }
197
231
  };
198
232
 
199
- // src/schema/permission-templates.ts
233
+ // src/utils/permission-templates.ts
200
234
  var PermissionTemplates = {
201
235
  /**
202
236
  * Public access - anyone can perform all operations
@@ -855,26 +889,28 @@ function getMaxSelect(fieldName, zodType) {
855
889
  return 1;
856
890
  }
857
891
  function getMinSelect(fieldName, zodType) {
858
- if (!isMultipleRelationField(fieldName, zodType)) {
859
- return void 0;
860
- }
861
- let unwrappedType = zodType;
862
- if (zodType instanceof zod.z.ZodOptional) {
863
- unwrappedType = zodType._def.innerType;
864
- }
865
- if (unwrappedType instanceof zod.z.ZodNullable) {
866
- unwrappedType = unwrappedType._def.innerType;
867
- }
868
- if (unwrappedType instanceof zod.z.ZodDefault) {
869
- unwrappedType = unwrappedType._def.innerType;
892
+ if (isSingleRelationField(fieldName, zodType)) {
893
+ return 0;
870
894
  }
871
- if (unwrappedType instanceof zod.z.ZodArray) {
872
- const arrayDef = unwrappedType._def;
873
- if (arrayDef.minLength) {
874
- return arrayDef.minLength.value;
895
+ if (isMultipleRelationField(fieldName, zodType)) {
896
+ let unwrappedType = zodType;
897
+ if (zodType instanceof zod.z.ZodOptional) {
898
+ unwrappedType = zodType._def.innerType;
899
+ }
900
+ if (unwrappedType instanceof zod.z.ZodNullable) {
901
+ unwrappedType = unwrappedType._def.innerType;
902
+ }
903
+ if (unwrappedType instanceof zod.z.ZodDefault) {
904
+ unwrappedType = unwrappedType._def.innerType;
905
+ }
906
+ if (unwrappedType instanceof zod.z.ZodArray) {
907
+ const arrayDef = unwrappedType._def;
908
+ if (arrayDef.minLength) {
909
+ return arrayDef.minLength.value;
910
+ }
875
911
  }
876
912
  }
877
- return void 0;
913
+ return 0;
878
914
  }
879
915
  function mapZodStringType(zodType) {
880
916
  const checks = zodType._def.checks || [];
@@ -1132,13 +1168,32 @@ async function importSchemaModule(filePath, config) {
1132
1168
  if (config?.pathTransformer) {
1133
1169
  importPath = config.pathTransformer(filePath);
1134
1170
  }
1135
- if (!importPath.endsWith(".js")) {
1136
- importPath = `${importPath}.js`;
1171
+ let resolvedPath = null;
1172
+ const jsPath = `${importPath}.js`;
1173
+ const tsPath = `${importPath}.ts`;
1174
+ if (fs4__namespace.existsSync(jsPath)) {
1175
+ resolvedPath = jsPath;
1176
+ } else if (fs4__namespace.existsSync(tsPath)) {
1177
+ resolvedPath = tsPath;
1178
+ } else {
1179
+ resolvedPath = jsPath;
1137
1180
  }
1138
- const fileUrl = new URL(`file://${path4__namespace.resolve(importPath)}`);
1181
+ const fileUrl = new URL(`file://${path4__namespace.resolve(resolvedPath)}`);
1139
1182
  const module = await import(fileUrl.href);
1140
1183
  return module;
1141
1184
  } catch (error) {
1185
+ const tsPath = `${filePath}.ts`;
1186
+ const isTypeScriptFile = fs4__namespace.existsSync(tsPath);
1187
+ if (isTypeScriptFile) {
1188
+ throw new SchemaParsingError(
1189
+ `Failed to import TypeScript schema file. Node.js cannot import TypeScript files directly.
1190
+ Please either:
1191
+ 1. Compile your schema files to JavaScript first, or
1192
+ 2. Use tsx to run the migration tool (e.g., "npx tsx package/dist/cli/migrate.js status" or "tsx package/dist/cli/migrate.js status")`,
1193
+ filePath,
1194
+ error
1195
+ );
1196
+ }
1142
1197
  throw new SchemaParsingError(
1143
1198
  `Failed to import schema module. Make sure the schema files are compiled to JavaScript.`,
1144
1199
  filePath,
@@ -1201,7 +1256,17 @@ function buildFieldDefinition(fieldName, zodType) {
1201
1256
  required,
1202
1257
  options
1203
1258
  };
1204
- if (isRelationField(fieldName, zodType)) {
1259
+ const relationMetadata = extractRelationMetadata(zodType.description);
1260
+ if (relationMetadata) {
1261
+ fieldDef.type = "relation";
1262
+ fieldDef.relation = {
1263
+ collection: relationMetadata.collection,
1264
+ maxSelect: relationMetadata.maxSelect,
1265
+ minSelect: relationMetadata.minSelect,
1266
+ cascadeDelete: relationMetadata.cascadeDelete
1267
+ };
1268
+ fieldDef.options = void 0;
1269
+ } else if (isRelationField(fieldName, zodType)) {
1205
1270
  fieldDef.type = "relation";
1206
1271
  const targetCollection = resolveTargetCollection(fieldName);
1207
1272
  const maxSelect = getMaxSelect(fieldName, zodType);
@@ -1213,6 +1278,13 @@ function buildFieldDefinition(fieldName, zodType) {
1213
1278
  cascadeDelete: false
1214
1279
  // Default to false, can be configured later
1215
1280
  };
1281
+ if (fieldDef.options) {
1282
+ const { min, max, pattern, ...relationSafeOptions } = fieldDef.options;
1283
+ console.log("min", min);
1284
+ console.log("max", max);
1285
+ console.log("pattern", pattern);
1286
+ fieldDef.options = Object.keys(relationSafeOptions).length > 0 ? relationSafeOptions : void 0;
1287
+ }
1216
1288
  }
1217
1289
  return fieldDef;
1218
1290
  }
@@ -1265,11 +1337,12 @@ function convertZodSchemaToCollectionSchema(collectionName, zodSchema) {
1265
1337
  fields,
1266
1338
  indexes,
1267
1339
  rules: {
1268
- listRule: null,
1269
- viewRule: null,
1270
- createRule: null,
1271
- updateRule: null,
1272
- deleteRule: null
1340
+ listRule: permissions?.listRule ?? null,
1341
+ viewRule: permissions?.viewRule ?? null,
1342
+ createRule: permissions?.createRule ?? null,
1343
+ updateRule: permissions?.updateRule ?? null,
1344
+ deleteRule: permissions?.deleteRule ?? null,
1345
+ manageRule: permissions?.manageRule ?? null
1273
1346
  },
1274
1347
  permissions
1275
1348
  };
@@ -1293,7 +1366,12 @@ async function buildSchemaDefinition(config) {
1293
1366
  if (normalizedConfig.pathTransformer) {
1294
1367
  importPath = normalizedConfig.pathTransformer(filePath);
1295
1368
  } else if (mergedConfig.useCompiledFiles) {
1296
- importPath = filePath.replace(/\/src\//, "/dist/");
1369
+ const distPath = filePath.replace(/\/src\//, "/dist/");
1370
+ if (fs4__namespace.existsSync(`${distPath}.js`) || fs4__namespace.existsSync(`${distPath}.mjs`)) {
1371
+ importPath = distPath;
1372
+ } else {
1373
+ importPath = filePath;
1374
+ }
1297
1375
  }
1298
1376
  const module = await importSchemaModule(importPath, normalizedConfig);
1299
1377
  const schemas = extractSchemaDefinitions(module, mergedConfig.schemaPatterns);
@@ -1691,10 +1769,8 @@ function compare(currentSchema, previousSnapshot, config) {
1691
1769
  var DEFAULT_TEMPLATE = `/// <reference path="{{TYPES_PATH}}" />
1692
1770
  migrate((app) => {
1693
1771
  {{UP_CODE}}
1694
- return true;
1695
1772
  }, (app) => {
1696
1773
  {{DOWN_CODE}}
1697
- return true;
1698
1774
  });
1699
1775
  `;
1700
1776
  var DEFAULT_CONFIG3 = {
@@ -1859,7 +1935,8 @@ function generateFieldDefinitionObject(field) {
1859
1935
  }
1860
1936
  }
1861
1937
  if (field.relation) {
1862
- const collectionIdPlaceholder = field.relation.collection === "Users" ? '"_pb_users_auth_"' : `app.findCollectionByNameOrId("${field.relation.collection}").id`;
1938
+ const isUsersCollection = field.relation.collection.toLowerCase() === "users";
1939
+ const collectionIdPlaceholder = isUsersCollection ? '"_pb_users_auth_"' : `app.findCollectionByNameOrId("${field.relation.collection}").id`;
1863
1940
  parts.push(` collectionId: ${collectionIdPlaceholder}`);
1864
1941
  if (field.relation.maxSelect !== void 0) {
1865
1942
  parts.push(` maxSelect: ${field.relation.maxSelect}`);
@@ -1943,7 +2020,7 @@ function generateIndexesArray(indexes) {
1943
2020
  ${indexStrings.join(",\n ")},
1944
2021
  ]`;
1945
2022
  }
1946
- function generateCollectionCreation(collection, varName = "collection") {
2023
+ function generateCollectionCreation(collection, varName = "collection", isLast = false) {
1947
2024
  const lines = [];
1948
2025
  lines.push(` const ${varName} = new Collection({`);
1949
2026
  lines.push(` name: "${collection.name}",`);
@@ -1959,7 +2036,7 @@ function generateCollectionCreation(collection, varName = "collection") {
1959
2036
  lines.push(` indexes: ${generateIndexesArray(collection.indexes)},`);
1960
2037
  lines.push(` });`);
1961
2038
  lines.push(``);
1962
- lines.push(` app.save(${varName});`);
2039
+ lines.push(isLast ? ` return app.save(${varName});` : ` app.save(${varName});`);
1963
2040
  return lines.join("\n");
1964
2041
  }
1965
2042
  function getFieldConstructorName(fieldType) {
@@ -1990,7 +2067,8 @@ function generateFieldConstructorOptions(field) {
1990
2067
  }
1991
2068
  }
1992
2069
  if (field.relation && field.type === "relation") {
1993
- const collectionIdPlaceholder = field.relation.collection === "Users" ? '"_pb_users_auth_"' : `app.findCollectionByNameOrId("${field.relation.collection}").id`;
2070
+ const isUsersCollection = field.relation.collection.toLowerCase() === "users";
2071
+ const collectionIdPlaceholder = isUsersCollection ? '"_pb_users_auth_"' : `app.findCollectionByNameOrId("${field.relation.collection}").id`;
1994
2072
  parts.push(` collectionId: ${collectionIdPlaceholder}`);
1995
2073
  if (field.relation.maxSelect !== void 0) {
1996
2074
  parts.push(` maxSelect: ${field.relation.maxSelect}`);
@@ -2004,7 +2082,7 @@ function generateFieldConstructorOptions(field) {
2004
2082
  }
2005
2083
  return parts.join(",\n");
2006
2084
  }
2007
- function generateFieldAddition(collectionName, field, varName) {
2085
+ function generateFieldAddition(collectionName, field, varName, isLast = false) {
2008
2086
  const lines = [];
2009
2087
  const constructorName = getFieldConstructorName(field.type);
2010
2088
  const collectionVar = varName || `collection_${collectionName}_${field.name}`;
@@ -2014,10 +2092,10 @@ function generateFieldAddition(collectionName, field, varName) {
2014
2092
  lines.push(generateFieldConstructorOptions(field));
2015
2093
  lines.push(` }));`);
2016
2094
  lines.push(``);
2017
- lines.push(` app.save(${collectionVar});`);
2095
+ lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
2018
2096
  return lines.join("\n");
2019
2097
  }
2020
- function generateFieldModification(collectionName, modification, varName) {
2098
+ function generateFieldModification(collectionName, modification, varName, isLast = false) {
2021
2099
  const lines = [];
2022
2100
  const collectionVar = varName || `collection_${collectionName}_${modification.fieldName}`;
2023
2101
  const fieldVar = `${collectionVar}_field`;
@@ -2031,7 +2109,8 @@ function generateFieldModification(collectionName, modification, varName) {
2031
2109
  } else if (change.property.startsWith("relation.")) {
2032
2110
  const relationKey = change.property.replace("relation.", "");
2033
2111
  if (relationKey === "collection") {
2034
- const collectionIdValue = change.newValue === "Users" ? '"_pb_users_auth_"' : `app.findCollectionByNameOrId("${change.newValue}").id`;
2112
+ const isUsersCollection = String(change.newValue).toLowerCase() === "users";
2113
+ const collectionIdValue = isUsersCollection ? '"_pb_users_auth_"' : `app.findCollectionByNameOrId("${change.newValue}").id`;
2035
2114
  lines.push(` ${fieldVar}.collectionId = ${collectionIdValue};`);
2036
2115
  } else {
2037
2116
  lines.push(` ${fieldVar}.${relationKey} = ${formatValue(change.newValue)};`);
@@ -2041,10 +2120,10 @@ function generateFieldModification(collectionName, modification, varName) {
2041
2120
  }
2042
2121
  }
2043
2122
  lines.push(``);
2044
- lines.push(` app.save(${collectionVar});`);
2123
+ lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
2045
2124
  return lines.join("\n");
2046
2125
  }
2047
- function generateFieldDeletion(collectionName, fieldName, varName) {
2126
+ function generateFieldDeletion(collectionName, fieldName, varName, isLast = false) {
2048
2127
  const lines = [];
2049
2128
  const collectionVar = varName || `collection_${collectionName}_${fieldName}`;
2050
2129
  const fieldVar = `${collectionVar}_field`;
@@ -2053,18 +2132,18 @@ function generateFieldDeletion(collectionName, fieldName, varName) {
2053
2132
  lines.push(``);
2054
2133
  lines.push(` ${collectionVar}.fields.remove(${fieldVar}.id);`);
2055
2134
  lines.push(``);
2056
- lines.push(` app.save(${collectionVar});`);
2135
+ lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
2057
2136
  return lines.join("\n");
2058
2137
  }
2059
- function generateIndexAddition(collectionName, index, varName) {
2138
+ function generateIndexAddition(collectionName, index, varName, isLast = false) {
2060
2139
  const lines = [];
2061
2140
  const collectionVar = varName || `collection_${collectionName}_idx`;
2062
2141
  lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
2063
2142
  lines.push(` ${collectionVar}.indexes.push("${index}");`);
2064
- lines.push(` app.save(${collectionVar});`);
2143
+ lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
2065
2144
  return lines.join("\n");
2066
2145
  }
2067
- function generateIndexRemoval(collectionName, index, varName) {
2146
+ function generateIndexRemoval(collectionName, index, varName, isLast = false) {
2068
2147
  const lines = [];
2069
2148
  const collectionVar = varName || `collection_${collectionName}_idx`;
2070
2149
  const indexVar = `${collectionVar}_indexToRemove`;
@@ -2073,29 +2152,29 @@ function generateIndexRemoval(collectionName, index, varName) {
2073
2152
  lines.push(` if (${indexVar} !== -1) {`);
2074
2153
  lines.push(` ${collectionVar}.indexes.splice(${indexVar}, 1);`);
2075
2154
  lines.push(` }`);
2076
- lines.push(` app.save(${collectionVar});`);
2155
+ lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
2077
2156
  return lines.join("\n");
2078
2157
  }
2079
- function generateRuleUpdate(collectionName, ruleType, newValue, varName) {
2158
+ function generateRuleUpdate(collectionName, ruleType, newValue, varName, isLast = false) {
2080
2159
  const lines = [];
2081
2160
  const collectionVar = varName || `collection_${collectionName}_${ruleType}`;
2082
2161
  lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
2083
2162
  lines.push(` ${collectionVar}.${ruleType} = ${formatValue(newValue)};`);
2084
- lines.push(` app.save(${collectionVar});`);
2163
+ lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
2085
2164
  return lines.join("\n");
2086
2165
  }
2087
- function generatePermissionUpdate(collectionName, ruleType, newValue, varName) {
2166
+ function generatePermissionUpdate(collectionName, ruleType, newValue, varName, isLast = false) {
2088
2167
  const lines = [];
2089
2168
  const collectionVar = varName || `collection_${collectionName}_${ruleType}`;
2090
2169
  lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
2091
2170
  lines.push(` ${collectionVar}.${ruleType} = ${formatValue(newValue)};`);
2092
- lines.push(` app.save(${collectionVar});`);
2171
+ lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
2093
2172
  return lines.join("\n");
2094
2173
  }
2095
- function generateCollectionDeletion(collectionName, varName = "collection") {
2174
+ function generateCollectionDeletion(collectionName, varName = "collection", isLast = false) {
2096
2175
  const lines = [];
2097
2176
  lines.push(` const ${varName} = app.findCollectionByNameOrId("${collectionName}");`);
2098
- lines.push(` app.delete(${varName});`);
2177
+ lines.push(isLast ? ` return app.delete(${varName});` : ` app.delete(${varName});`);
2099
2178
  return lines.join("\n");
2100
2179
  }
2101
2180
  function generateUpMigration(diff) {
@@ -2187,7 +2266,24 @@ function generateUpMigration(diff) {
2187
2266
  lines.push(` // No changes detected`);
2188
2267
  lines.push(``);
2189
2268
  }
2190
- return lines.join("\n");
2269
+ let code = lines.join("\n");
2270
+ const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
2271
+ const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
2272
+ const saveMatches = [...code.matchAll(savePattern)];
2273
+ const deleteMatches = [...code.matchAll(deletePattern)];
2274
+ const allMatches = [
2275
+ ...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
2276
+ ...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
2277
+ ].sort((a, b) => b.index - a.index);
2278
+ if (allMatches.length > 0) {
2279
+ const lastMatch = allMatches[0];
2280
+ if (lastMatch.type === "save") {
2281
+ code = code.substring(0, lastMatch.match.index) + lastMatch.match[1] + "return app.save(" + lastMatch.match[2] + ");" + code.substring(lastMatch.match.index + lastMatch.match[0].length);
2282
+ } else {
2283
+ code = code.substring(0, lastMatch.match.index) + lastMatch.match[1] + "return app.delete(" + lastMatch.match[2] + ");" + code.substring(lastMatch.match.index + lastMatch.match[0].length);
2284
+ }
2285
+ }
2286
+ return code;
2191
2287
  }
2192
2288
  function generateDownMigration(diff) {
2193
2289
  const lines = [];
@@ -2289,7 +2385,24 @@ function generateDownMigration(diff) {
2289
2385
  lines.push(` // No changes to revert`);
2290
2386
  lines.push(``);
2291
2387
  }
2292
- return lines.join("\n");
2388
+ let code = lines.join("\n");
2389
+ const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
2390
+ const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
2391
+ const saveMatches = [...code.matchAll(savePattern)];
2392
+ const deleteMatches = [...code.matchAll(deletePattern)];
2393
+ const allMatches = [
2394
+ ...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
2395
+ ...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
2396
+ ].sort((a, b) => b.index - a.index);
2397
+ if (allMatches.length > 0) {
2398
+ const lastMatch = allMatches[0];
2399
+ if (lastMatch.type === "save") {
2400
+ code = code.substring(0, lastMatch.match.index) + lastMatch.match[1] + "return app.save(" + lastMatch.match[2] + ");" + code.substring(lastMatch.match.index + lastMatch.match[0].length);
2401
+ } else {
2402
+ code = code.substring(0, lastMatch.match.index) + lastMatch.match[1] + "return app.delete(" + lastMatch.match[2] + ");" + code.substring(lastMatch.match.index + lastMatch.match[0].length);
2403
+ }
2404
+ }
2405
+ return code;
2293
2406
  }
2294
2407
  function generate(diff, config) {
2295
2408
  const normalizedConfig = typeof config === "string" ? { migrationDir: config } : config;
@@ -2412,6 +2525,7 @@ function convertPocketBaseCollection(pbCollection) {
2412
2525
  if (pbCollection.manageRule !== void 0) rules.manageRule = pbCollection.manageRule;
2413
2526
  if (Object.keys(rules).length > 0) {
2414
2527
  schema.rules = rules;
2528
+ schema.permissions = { ...rules };
2415
2529
  }
2416
2530
  return schema;
2417
2531
  }
@@ -3002,7 +3116,13 @@ async function executeGenerate(options) {
3002
3116
  const schemaDir = getSchemaDirectory(config);
3003
3117
  const migrationsDir = getMigrationsDirectory(config);
3004
3118
  logSection("\u{1F50D} Analyzing Schema");
3005
- const currentSchema = await withProgress("Parsing Zod schemas...", () => parseSchemaFiles(schemaDir));
3119
+ const analyzerConfig = {
3120
+ schemaDir,
3121
+ excludePatterns: config.schema.exclude,
3122
+ useCompiledFiles: false
3123
+ // Use source files since we're in development/testing
3124
+ };
3125
+ const currentSchema = await withProgress("Parsing Zod schemas...", () => parseSchemaFiles(analyzerConfig));
3006
3126
  logSuccess(`Found ${currentSchema.collections.size} collection(s)`);
3007
3127
  logInfo("Loading previous snapshot...");
3008
3128
  const previousSnapshot = loadSnapshotIfExists({
@@ -3201,7 +3321,13 @@ async function executeStatus(options) {
3201
3321
  const schemaDir = getSchemaDirectory(config);
3202
3322
  const migrationsDir = getMigrationsDirectory(config);
3203
3323
  logSection("\u{1F50D} Checking Migration Status");
3204
- const currentSchema = await withProgress("Parsing Zod schemas...", () => parseSchemaFiles(schemaDir));
3324
+ const analyzerConfig = {
3325
+ schemaDir,
3326
+ excludePatterns: config.schema.exclude,
3327
+ useCompiledFiles: false
3328
+ // Use source files since we're in development/testing
3329
+ };
3330
+ const currentSchema = await withProgress("Parsing Zod schemas...", () => parseSchemaFiles(analyzerConfig));
3205
3331
  logSuccess(`Found ${currentSchema.collections.size} collection(s) in schema`);
3206
3332
  logInfo("Loading previous snapshot...");
3207
3333
  const previousSnapshot = loadSnapshotIfExists({
@@ -3317,7 +3443,19 @@ Examples:
3317
3443
  }
3318
3444
 
3319
3445
  // src/cli/migrate.ts
3320
- var VERSION = "0.1.0";
3446
+ function getVersion() {
3447
+ try {
3448
+ 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"));
3452
+ return packageJson.version || "0.0.0";
3453
+ } catch {
3454
+ console.warn("Warning: Could not read version from package.json");
3455
+ return "0.0.0";
3456
+ }
3457
+ }
3458
+ var VERSION = getVersion();
3321
3459
  function displayBanner() {
3322
3460
  console.log();
3323
3461
  console.log(chalk__default.default.cyan.bold(" PocketBase Zod Migration Tool"));