pocketbase-zod-schema 0.1.4 → 0.2.1

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 (45) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +233 -98
  3. package/dist/cli/index.cjs +45 -11
  4. package/dist/cli/index.cjs.map +1 -1
  5. package/dist/cli/index.js +45 -11
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/cli/migrate.cjs +45 -11
  8. package/dist/cli/migrate.cjs.map +1 -1
  9. package/dist/cli/migrate.js +45 -11
  10. package/dist/cli/migrate.js.map +1 -1
  11. package/dist/index.cjs +86 -27
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.cts +2 -2
  14. package/dist/index.d.ts +2 -2
  15. package/dist/index.js +81 -26
  16. package/dist/index.js.map +1 -1
  17. package/dist/migration/analyzer.cjs +46 -11
  18. package/dist/migration/analyzer.cjs.map +1 -1
  19. package/dist/migration/analyzer.d.cts +11 -1
  20. package/dist/migration/analyzer.d.ts +11 -1
  21. package/dist/migration/analyzer.js +46 -12
  22. package/dist/migration/analyzer.js.map +1 -1
  23. package/dist/migration/index.cjs +45 -11
  24. package/dist/migration/index.cjs.map +1 -1
  25. package/dist/migration/index.js +45 -11
  26. package/dist/migration/index.js.map +1 -1
  27. package/dist/migration/snapshot.cjs.map +1 -1
  28. package/dist/migration/snapshot.js.map +1 -1
  29. package/dist/mutator.cjs +20 -21
  30. package/dist/mutator.cjs.map +1 -1
  31. package/dist/mutator.d.cts +2 -2
  32. package/dist/mutator.d.ts +2 -2
  33. package/dist/mutator.js +20 -21
  34. package/dist/mutator.js.map +1 -1
  35. package/dist/schema.cjs +41 -16
  36. package/dist/schema.cjs.map +1 -1
  37. package/dist/schema.d.cts +98 -8
  38. package/dist/schema.d.ts +98 -8
  39. package/dist/schema.js +36 -15
  40. package/dist/schema.js.map +1 -1
  41. package/dist/types.d.cts +1 -1
  42. package/dist/types.d.ts +1 -1
  43. package/dist/{user-_AM523hb.d.cts → user-DTJQIj4K.d.cts} +31 -5
  44. package/dist/{user-_AM523hb.d.ts → user-DTJQIj4K.d.ts} +31 -5
  45. package/package.json +2 -1
package/dist/index.cjs CHANGED
@@ -105,7 +105,7 @@ function filesField(options) {
105
105
  return schema;
106
106
  }
107
107
  var RELATION_METADATA_KEY = "__pocketbase_relation__";
108
- function relationField(config) {
108
+ function RelationField(config) {
109
109
  const metadata = {
110
110
  [RELATION_METADATA_KEY]: {
111
111
  type: "single",
@@ -117,7 +117,7 @@ function relationField(config) {
117
117
  };
118
118
  return zod.z.string().describe(JSON.stringify(metadata));
119
119
  }
120
- function relationsField(config) {
120
+ function RelationsField(config) {
121
121
  const metadata = {
122
122
  [RELATION_METADATA_KEY]: {
123
123
  type: "multiple",
@@ -176,6 +176,22 @@ function withIndexes(schema, indexes) {
176
176
  };
177
177
  return schema.describe(JSON.stringify(metadata));
178
178
  }
179
+ function defineCollection(config) {
180
+ const { collectionName, schema, permissions, indexes, ...futureOptions } = config;
181
+ const metadata = {
182
+ collectionName
183
+ };
184
+ if (permissions) {
185
+ metadata.permissions = permissions;
186
+ }
187
+ if (indexes) {
188
+ metadata.indexes = indexes;
189
+ }
190
+ if (Object.keys(futureOptions).length > 0) {
191
+ Object.assign(metadata, futureOptions);
192
+ }
193
+ return schema.describe(JSON.stringify(metadata));
194
+ }
179
195
 
180
196
  // src/utils/permission-templates.ts
181
197
  var PermissionTemplates = {
@@ -402,12 +418,14 @@ var ProjectInputSchema = zod.z.object({
402
418
  content: zod.z.string(),
403
419
  status: StatusEnum,
404
420
  summary: zod.z.string().optional(),
405
- OwnerUser: relationField({ collection: "Users" }),
406
- SubscriberUsers: relationsField({ collection: "Users" })
421
+ OwnerUser: RelationField({ collection: "Users" }),
422
+ SubscriberUsers: RelationsField({ collection: "Users" })
407
423
  }).extend(inputImageFileSchema);
408
- var ProjectSchema = withPermissions(
409
- ProjectInputSchema.omit(omitImageFilesSchema).extend(baseImageFileSchema),
410
- {
424
+ var ProjectSchema = ProjectInputSchema.omit(omitImageFilesSchema).extend(baseImageFileSchema);
425
+ var ProjectCollection = defineCollection({
426
+ collectionName: "Projects",
427
+ schema: ProjectSchema,
428
+ permissions: {
411
429
  template: "owner-only",
412
430
  ownerField: "OwnerUser",
413
431
  customRules: {
@@ -415,7 +433,7 @@ var ProjectSchema = withPermissions(
415
433
  viewRule: '@request.auth.id != "" && (OwnerUser = @request.auth.id || SubscriberUsers ?= @request.auth.id)'
416
434
  }
417
435
  }
418
- );
436
+ });
419
437
  var UserInputSchema = zod.z.object({
420
438
  name: zod.z.string().optional(),
421
439
  email: zod.z.string().email(),
@@ -423,14 +441,17 @@ var UserInputSchema = zod.z.object({
423
441
  passwordConfirm: zod.z.string(),
424
442
  avatar: zod.z.instanceof(File).optional()
425
443
  });
426
- var UserDatabaseSchema = zod.z.object({
444
+ var UserCollectionSchema = zod.z.object({
427
445
  name: zod.z.string().optional(),
428
446
  email: zod.z.string().email(),
429
447
  password: zod.z.string().min(8, "Password must be at least 8 characters"),
430
448
  avatar: zod.z.instanceof(File).optional()
431
449
  });
432
- var UserSchema = withIndexes(
433
- withPermissions(UserDatabaseSchema.extend(baseSchema), {
450
+ var UserSchema = UserCollectionSchema.extend(baseSchema);
451
+ var UserCollection = defineCollection({
452
+ collectionName: "Users",
453
+ schema: UserSchema,
454
+ permissions: {
434
455
  // Users can list their own profile
435
456
  listRule: "id = @request.auth.id",
436
457
  // Users can view their own profile
@@ -442,13 +463,13 @@ var UserSchema = withIndexes(
442
463
  // Users can only delete their own account
443
464
  deleteRule: "id = @request.auth.id"
444
465
  // manageRule is null in PocketBase default (not set)
445
- }),
446
- [
466
+ },
467
+ indexes: [
447
468
  // PocketBase's default indexes for auth collections
448
469
  "CREATE UNIQUE INDEX `idx_tokenKey__pb_users_auth_` ON `users` (`tokenKey`)",
449
470
  "CREATE UNIQUE INDEX `idx_email__pb_users_auth_` ON `users` (`email`) WHERE `email` != ''"
450
471
  ]
451
- );
472
+ });
452
473
  var BaseMutator = class {
453
474
  pb;
454
475
  // Define a default property that subclasses will override
@@ -1970,6 +1991,16 @@ function getFieldTypeInfo(zodType, fieldName) {
1970
1991
  }
1971
1992
 
1972
1993
  // src/migration/analyzer.ts
1994
+ var tsxLoaderRegistered = false;
1995
+ async function ensureTsxLoader() {
1996
+ if (tsxLoaderRegistered) return;
1997
+ try {
1998
+ await import('tsx/esm');
1999
+ tsxLoaderRegistered = true;
2000
+ } catch {
2001
+ tsxLoaderRegistered = false;
2002
+ }
2003
+ }
1973
2004
  var DEFAULT_CONFIG = {
1974
2005
  workspaceRoot: process.cwd(),
1975
2006
  excludePatterns: [
@@ -2067,24 +2098,37 @@ async function importSchemaModule(filePath, config) {
2067
2098
  } else {
2068
2099
  resolvedPath = jsPath;
2069
2100
  }
2101
+ if (resolvedPath.endsWith(".ts")) {
2102
+ await ensureTsxLoader();
2103
+ if (!tsxLoaderRegistered) {
2104
+ throw new SchemaParsingError(
2105
+ `Failed to import TypeScript schema file. The 'tsx' package is required to load TypeScript files.
2106
+ Please install tsx: npm install tsx (or yarn add tsx, or pnpm add tsx)
2107
+ Alternatively, compile your schema files to JavaScript first.`,
2108
+ filePath
2109
+ );
2110
+ }
2111
+ }
2070
2112
  const fileUrl = new URL(`file://${path5__namespace.resolve(resolvedPath)}`);
2071
2113
  const module = await import(fileUrl.href);
2072
2114
  return module;
2073
2115
  } catch (error) {
2074
2116
  const tsPath = `${filePath}.ts`;
2075
2117
  const isTypeScriptFile = fs3__namespace.existsSync(tsPath);
2118
+ if (isTypeScriptFile && error instanceof SchemaParsingError) {
2119
+ throw error;
2120
+ }
2076
2121
  if (isTypeScriptFile) {
2077
2122
  throw new SchemaParsingError(
2078
- `Failed to import TypeScript schema file. Node.js cannot import TypeScript files directly.
2079
- Please either:
2080
- 1. Compile your schema files to JavaScript first, or
2081
- 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")`,
2123
+ `Failed to import TypeScript schema file. The 'tsx' package is required to load TypeScript files.
2124
+ Please install tsx: npm install tsx (or yarn add tsx, or pnpm add tsx)
2125
+ Alternatively, compile your schema files to JavaScript first.`,
2082
2126
  filePath,
2083
2127
  error
2084
2128
  );
2085
2129
  }
2086
2130
  throw new SchemaParsingError(
2087
- `Failed to import schema module. Make sure the schema files are compiled to JavaScript.`,
2131
+ `Failed to import schema module. Make sure the schema files exist and are valid.`,
2088
2132
  filePath,
2089
2133
  error
2090
2134
  );
@@ -2094,6 +2138,19 @@ function getCollectionNameFromFile(filePath) {
2094
2138
  const filename = path5__namespace.basename(filePath).replace(/\.(ts|js)$/, "");
2095
2139
  return toCollectionName(filename);
2096
2140
  }
2141
+ function extractCollectionNameFromSchema(zodSchema) {
2142
+ if (!zodSchema.description) {
2143
+ return null;
2144
+ }
2145
+ try {
2146
+ const metadata = JSON.parse(zodSchema.description);
2147
+ if (metadata.collectionName && typeof metadata.collectionName === "string") {
2148
+ return metadata.collectionName;
2149
+ }
2150
+ } catch {
2151
+ }
2152
+ return null;
2153
+ }
2097
2154
  function extractSchemaDefinitions(module, patterns = ["Schema", "InputSchema"]) {
2098
2155
  const result = {};
2099
2156
  for (const [key, value] of Object.entries(module)) {
@@ -2168,11 +2225,8 @@ function buildFieldDefinition(fieldName, zodType) {
2168
2225
  // Default to false, can be configured later
2169
2226
  };
2170
2227
  if (fieldDef.options) {
2171
- const { min, max, pattern, ...relationSafeOptions } = fieldDef.options;
2172
- console.log("min", min);
2173
- console.log("max", max);
2174
- console.log("pattern", pattern);
2175
- fieldDef.options = Object.keys(relationSafeOptions).length > 0 ? relationSafeOptions : void 0;
2228
+ const { min: _min, max: _max, pattern: _pattern, ...relationSafeOptions } = fieldDef.options;
2229
+ fieldDef.options = Object.keys(relationSafeOptions).length ? relationSafeOptions : void 0;
2176
2230
  }
2177
2231
  }
2178
2232
  return fieldDef;
@@ -2269,7 +2323,8 @@ async function buildSchemaDefinition(config) {
2269
2323
  console.warn(`No valid schema found in ${filePath}, skipping...`);
2270
2324
  continue;
2271
2325
  }
2272
- const collectionName = getCollectionNameFromFile(filePath);
2326
+ const collectionNameFromSchema = extractCollectionNameFromSchema(zodSchema);
2327
+ const collectionName = collectionNameFromSchema ?? getCollectionNameFromFile(filePath);
2273
2328
  const collectionSchema = convertZodSchemaToCollectionSchema(collectionName, zodSchema);
2274
2329
  collections.set(collectionName, collectionSchema);
2275
2330
  } catch (error) {
@@ -5213,13 +5268,18 @@ exports.MigrationGenerationError = MigrationGenerationError;
5213
5268
  exports.MigrationGenerator = MigrationGenerator;
5214
5269
  exports.POCKETBASE_FIELD_TYPES = POCKETBASE_FIELD_TYPES;
5215
5270
  exports.PermissionTemplates = PermissionTemplates;
5271
+ exports.ProjectCollection = ProjectCollection;
5216
5272
  exports.ProjectInputSchema = ProjectInputSchema;
5217
5273
  exports.ProjectSchema = ProjectSchema;
5274
+ exports.RelationField = RelationField;
5275
+ exports.RelationsField = RelationsField;
5218
5276
  exports.SchemaAnalyzer = SchemaAnalyzer;
5219
5277
  exports.SchemaParsingError = SchemaParsingError;
5220
5278
  exports.SnapshotError = SnapshotError;
5221
5279
  exports.SnapshotManager = SnapshotManager;
5222
5280
  exports.StatusEnum = StatusEnum;
5281
+ exports.UserCollection = UserCollection;
5282
+ exports.UserCollectionSchema = UserCollectionSchema;
5223
5283
  exports.UserInputSchema = UserInputSchema;
5224
5284
  exports.UserMutator = UserMutator;
5225
5285
  exports.UserSchema = UserSchema;
@@ -5242,6 +5302,7 @@ exports.convertZodSchemaToCollectionSchema = convertZodSchemaToCollectionSchema;
5242
5302
  exports.createMigrationFileStructure = createMigrationFileStructure;
5243
5303
  exports.createPermissions = createPermissions;
5244
5304
  exports.dateField = dateField;
5305
+ exports.defineCollection = defineCollection;
5245
5306
  exports.detectDestructiveChanges = detectDestructiveChanges;
5246
5307
  exports.detectFieldChanges = detectFieldChanges;
5247
5308
  exports.discoverSchemaFiles = discoverSchemaFiles;
@@ -5332,8 +5393,6 @@ exports.numberField = numberField;
5332
5393
  exports.omitImageFilesSchema = omitImageFilesSchema;
5333
5394
  exports.parseSchemaFiles = parseSchemaFiles;
5334
5395
  exports.pluralize = pluralize;
5335
- exports.relationField = relationField;
5336
- exports.relationsField = relationsField;
5337
5396
  exports.requiresForceFlag = requiresForceFlag;
5338
5397
  exports.resolveTargetCollection = resolveTargetCollection;
5339
5398
  exports.resolveTemplate = resolveTemplate;