pocketbase-zod-schema 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +329 -99
  3. package/dist/cli/index.cjs +577 -152
  4. package/dist/cli/index.cjs.map +1 -1
  5. package/dist/cli/index.js +575 -150
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/cli/migrate.cjs +595 -153
  8. package/dist/cli/migrate.cjs.map +1 -1
  9. package/dist/cli/migrate.js +592 -151
  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 +688 -231
  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 +685 -230
  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/diff.cjs +21 -3
  26. package/dist/migration/diff.cjs.map +1 -1
  27. package/dist/migration/diff.js +21 -3
  28. package/dist/migration/diff.js.map +1 -1
  29. package/dist/migration/generator.cjs +60 -25
  30. package/dist/migration/generator.cjs.map +1 -1
  31. package/dist/migration/generator.d.cts +9 -5
  32. package/dist/migration/generator.d.ts +9 -5
  33. package/dist/migration/generator.js +60 -25
  34. package/dist/migration/generator.js.map +1 -1
  35. package/dist/migration/index.cjs +614 -171
  36. package/dist/migration/index.cjs.map +1 -1
  37. package/dist/migration/index.d.cts +1 -1
  38. package/dist/migration/index.d.ts +1 -1
  39. package/dist/migration/index.js +613 -171
  40. package/dist/migration/index.js.map +1 -1
  41. package/dist/migration/snapshot.cjs +432 -117
  42. package/dist/migration/snapshot.cjs.map +1 -1
  43. package/dist/migration/snapshot.d.cts +34 -12
  44. package/dist/migration/snapshot.d.ts +34 -12
  45. package/dist/migration/snapshot.js +430 -116
  46. package/dist/migration/snapshot.js.map +1 -1
  47. package/dist/migration/utils/index.cjs +19 -17
  48. package/dist/migration/utils/index.cjs.map +1 -1
  49. package/dist/migration/utils/index.d.cts +3 -1
  50. package/dist/migration/utils/index.d.ts +3 -1
  51. package/dist/migration/utils/index.js +19 -17
  52. package/dist/migration/utils/index.js.map +1 -1
  53. package/dist/mutator.cjs +9 -11
  54. package/dist/mutator.cjs.map +1 -1
  55. package/dist/mutator.d.cts +5 -9
  56. package/dist/mutator.d.ts +5 -9
  57. package/dist/mutator.js +9 -11
  58. package/dist/mutator.js.map +1 -1
  59. package/dist/schema.cjs +54 -23
  60. package/dist/schema.cjs.map +1 -1
  61. package/dist/schema.d.cts +94 -12
  62. package/dist/schema.d.ts +94 -12
  63. package/dist/schema.js +54 -24
  64. package/dist/schema.js.map +1 -1
  65. package/dist/types.d.cts +1 -1
  66. package/dist/types.d.ts +1 -1
  67. package/dist/{user-jS1aYoeD.d.cts → user-_AM523hb.d.cts} +6 -6
  68. package/dist/{user-jS1aYoeD.d.ts → user-_AM523hb.d.ts} +6 -6
  69. package/package.json +2 -4
@@ -3,6 +3,35 @@ import * as path from 'path';
3
3
  import { z } from 'zod';
4
4
 
5
5
  // src/migration/analyzer.ts
6
+ ({
7
+ id: z.string().describe("unique id"),
8
+ collectionId: z.string().describe("collection id"),
9
+ collectionName: z.string().describe("collection name"),
10
+ expand: z.record(z.any()).describe("expandable fields")
11
+ });
12
+ ({
13
+ created: z.string().describe("creation timestamp"),
14
+ updated: z.string().describe("last update timestamp")
15
+ });
16
+ ({
17
+ thumbnailURL: z.string().optional(),
18
+ imageFiles: z.array(z.string())
19
+ });
20
+ ({
21
+ imageFiles: z.array(z.instanceof(File))
22
+ });
23
+ var RELATION_METADATA_KEY = "__pocketbase_relation__";
24
+ function extractRelationMetadata(description) {
25
+ if (!description) return null;
26
+ try {
27
+ const parsed = JSON.parse(description);
28
+ if (parsed[RELATION_METADATA_KEY]) {
29
+ return parsed[RELATION_METADATA_KEY];
30
+ }
31
+ } catch {
32
+ }
33
+ return null;
34
+ }
6
35
 
7
36
  // src/migration/errors.ts
8
37
  var MigrationError = class _MigrationError extends Error {
@@ -77,7 +106,7 @@ Cause: ${this.originalError.message}`);
77
106
  }
78
107
  };
79
108
 
80
- // src/schema/permission-templates.ts
109
+ // src/utils/permission-templates.ts
81
110
  var PermissionTemplates = {
82
111
  /**
83
112
  * Public access - anyone can perform all operations
@@ -736,26 +765,28 @@ function getMaxSelect(fieldName, zodType) {
736
765
  return 1;
737
766
  }
738
767
  function getMinSelect(fieldName, zodType) {
739
- if (!isMultipleRelationField(fieldName, zodType)) {
740
- return void 0;
741
- }
742
- let unwrappedType = zodType;
743
- if (zodType instanceof z.ZodOptional) {
744
- unwrappedType = zodType._def.innerType;
745
- }
746
- if (unwrappedType instanceof z.ZodNullable) {
747
- unwrappedType = unwrappedType._def.innerType;
748
- }
749
- if (unwrappedType instanceof z.ZodDefault) {
750
- unwrappedType = unwrappedType._def.innerType;
768
+ if (isSingleRelationField(fieldName, zodType)) {
769
+ return 0;
751
770
  }
752
- if (unwrappedType instanceof z.ZodArray) {
753
- const arrayDef = unwrappedType._def;
754
- if (arrayDef.minLength) {
755
- return arrayDef.minLength.value;
771
+ if (isMultipleRelationField(fieldName, zodType)) {
772
+ let unwrappedType = zodType;
773
+ if (zodType instanceof z.ZodOptional) {
774
+ unwrappedType = zodType._def.innerType;
775
+ }
776
+ if (unwrappedType instanceof z.ZodNullable) {
777
+ unwrappedType = unwrappedType._def.innerType;
778
+ }
779
+ if (unwrappedType instanceof z.ZodDefault) {
780
+ unwrappedType = unwrappedType._def.innerType;
781
+ }
782
+ if (unwrappedType instanceof z.ZodArray) {
783
+ const arrayDef = unwrappedType._def;
784
+ if (arrayDef.minLength) {
785
+ return arrayDef.minLength.value;
786
+ }
756
787
  }
757
788
  }
758
- return void 0;
789
+ return 0;
759
790
  }
760
791
  function mapZodStringType(zodType) {
761
792
  const checks = zodType._def.checks || [];
@@ -1013,13 +1044,32 @@ async function importSchemaModule(filePath, config) {
1013
1044
  if (config?.pathTransformer) {
1014
1045
  importPath = config.pathTransformer(filePath);
1015
1046
  }
1016
- if (!importPath.endsWith(".js")) {
1017
- importPath = `${importPath}.js`;
1047
+ let resolvedPath = null;
1048
+ const jsPath = `${importPath}.js`;
1049
+ const tsPath = `${importPath}.ts`;
1050
+ if (fs.existsSync(jsPath)) {
1051
+ resolvedPath = jsPath;
1052
+ } else if (fs.existsSync(tsPath)) {
1053
+ resolvedPath = tsPath;
1054
+ } else {
1055
+ resolvedPath = jsPath;
1018
1056
  }
1019
- const fileUrl = new URL(`file://${path.resolve(importPath)}`);
1057
+ const fileUrl = new URL(`file://${path.resolve(resolvedPath)}`);
1020
1058
  const module = await import(fileUrl.href);
1021
1059
  return module;
1022
1060
  } catch (error) {
1061
+ const tsPath = `${filePath}.ts`;
1062
+ const isTypeScriptFile = fs.existsSync(tsPath);
1063
+ if (isTypeScriptFile) {
1064
+ throw new SchemaParsingError(
1065
+ `Failed to import TypeScript schema file. Node.js cannot import TypeScript files directly.
1066
+ Please either:
1067
+ 1. Compile your schema files to JavaScript first, or
1068
+ 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")`,
1069
+ filePath,
1070
+ error
1071
+ );
1072
+ }
1023
1073
  throw new SchemaParsingError(
1024
1074
  `Failed to import schema module. Make sure the schema files are compiled to JavaScript.`,
1025
1075
  filePath,
@@ -1082,7 +1132,17 @@ function buildFieldDefinition(fieldName, zodType) {
1082
1132
  required,
1083
1133
  options
1084
1134
  };
1085
- if (isRelationField(fieldName, zodType)) {
1135
+ const relationMetadata = extractRelationMetadata(zodType.description);
1136
+ if (relationMetadata) {
1137
+ fieldDef.type = "relation";
1138
+ fieldDef.relation = {
1139
+ collection: relationMetadata.collection,
1140
+ maxSelect: relationMetadata.maxSelect,
1141
+ minSelect: relationMetadata.minSelect,
1142
+ cascadeDelete: relationMetadata.cascadeDelete
1143
+ };
1144
+ fieldDef.options = void 0;
1145
+ } else if (isRelationField(fieldName, zodType)) {
1086
1146
  fieldDef.type = "relation";
1087
1147
  const targetCollection = resolveTargetCollection(fieldName);
1088
1148
  const maxSelect = getMaxSelect(fieldName, zodType);
@@ -1094,6 +1154,13 @@ function buildFieldDefinition(fieldName, zodType) {
1094
1154
  cascadeDelete: false
1095
1155
  // Default to false, can be configured later
1096
1156
  };
1157
+ if (fieldDef.options) {
1158
+ const { min, max, pattern, ...relationSafeOptions } = fieldDef.options;
1159
+ console.log("min", min);
1160
+ console.log("max", max);
1161
+ console.log("pattern", pattern);
1162
+ fieldDef.options = Object.keys(relationSafeOptions).length > 0 ? relationSafeOptions : void 0;
1163
+ }
1097
1164
  }
1098
1165
  return fieldDef;
1099
1166
  }
@@ -1146,11 +1213,12 @@ function convertZodSchemaToCollectionSchema(collectionName, zodSchema) {
1146
1213
  fields,
1147
1214
  indexes,
1148
1215
  rules: {
1149
- listRule: null,
1150
- viewRule: null,
1151
- createRule: null,
1152
- updateRule: null,
1153
- deleteRule: null
1216
+ listRule: permissions?.listRule ?? null,
1217
+ viewRule: permissions?.viewRule ?? null,
1218
+ createRule: permissions?.createRule ?? null,
1219
+ updateRule: permissions?.updateRule ?? null,
1220
+ deleteRule: permissions?.deleteRule ?? null,
1221
+ manageRule: permissions?.manageRule ?? null
1154
1222
  },
1155
1223
  permissions
1156
1224
  };
@@ -1174,7 +1242,12 @@ async function buildSchemaDefinition(config) {
1174
1242
  if (normalizedConfig.pathTransformer) {
1175
1243
  importPath = normalizedConfig.pathTransformer(filePath);
1176
1244
  } else if (mergedConfig.useCompiledFiles) {
1177
- importPath = filePath.replace(/\/src\//, "/dist/");
1245
+ const distPath = filePath.replace(/\/src\//, "/dist/");
1246
+ if (fs.existsSync(`${distPath}.js`) || fs.existsSync(`${distPath}.mjs`)) {
1247
+ importPath = distPath;
1248
+ } else {
1249
+ importPath = filePath;
1250
+ }
1178
1251
  }
1179
1252
  const module = await importSchemaModule(importPath, normalizedConfig);
1180
1253
  const schemas = extractSchemaDefinitions(module, mergedConfig.schemaPatterns);