pocketbase-zod-schema 0.3.0 → 0.3.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 (64) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/cli/index.cjs +167 -46
  3. package/dist/cli/index.cjs.map +1 -1
  4. package/dist/cli/index.d.cts +2 -2
  5. package/dist/cli/index.d.ts +2 -2
  6. package/dist/cli/index.js +167 -46
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/cli/migrate.cjs +167 -46
  9. package/dist/cli/migrate.cjs.map +1 -1
  10. package/dist/cli/migrate.js +167 -46
  11. package/dist/cli/migrate.js.map +1 -1
  12. package/dist/cli/utils/index.d.cts +2 -2
  13. package/dist/cli/utils/index.d.ts +2 -2
  14. package/dist/{fields-UcOPu1OQ.d.cts → fields-RVj26U-O.d.cts} +1 -0
  15. package/dist/{fields-UcOPu1OQ.d.ts → fields-RVj26U-O.d.ts} +1 -0
  16. package/dist/index.cjs +167 -46
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +3 -3
  19. package/dist/index.d.ts +3 -3
  20. package/dist/index.js +167 -46
  21. package/dist/index.js.map +1 -1
  22. package/dist/migration/analyzer.cjs.map +1 -1
  23. package/dist/migration/analyzer.d.cts +2 -2
  24. package/dist/migration/analyzer.d.ts +2 -2
  25. package/dist/migration/analyzer.js.map +1 -1
  26. package/dist/migration/diff.cjs +77 -26
  27. package/dist/migration/diff.cjs.map +1 -1
  28. package/dist/migration/diff.d.cts +4 -4
  29. package/dist/migration/diff.d.ts +4 -4
  30. package/dist/migration/diff.js +77 -26
  31. package/dist/migration/diff.js.map +1 -1
  32. package/dist/migration/generator.cjs +39 -2
  33. package/dist/migration/generator.cjs.map +1 -1
  34. package/dist/migration/generator.d.cts +2 -2
  35. package/dist/migration/generator.d.ts +2 -2
  36. package/dist/migration/generator.js +39 -2
  37. package/dist/migration/generator.js.map +1 -1
  38. package/dist/migration/index.cjs +167 -46
  39. package/dist/migration/index.cjs.map +1 -1
  40. package/dist/migration/index.d.cts +3 -3
  41. package/dist/migration/index.d.ts +3 -3
  42. package/dist/migration/index.js +167 -46
  43. package/dist/migration/index.js.map +1 -1
  44. package/dist/migration/snapshot.cjs +51 -18
  45. package/dist/migration/snapshot.cjs.map +1 -1
  46. package/dist/migration/snapshot.d.cts +2 -2
  47. package/dist/migration/snapshot.d.ts +2 -2
  48. package/dist/migration/snapshot.js +51 -18
  49. package/dist/migration/snapshot.js.map +1 -1
  50. package/dist/migration/utils/index.cjs +5 -3
  51. package/dist/migration/utils/index.cjs.map +1 -1
  52. package/dist/migration/utils/index.d.cts +4 -4
  53. package/dist/migration/utils/index.d.ts +4 -4
  54. package/dist/migration/utils/index.js +5 -3
  55. package/dist/migration/utils/index.js.map +1 -1
  56. package/dist/schema.cjs.map +1 -1
  57. package/dist/schema.d.cts +1 -1
  58. package/dist/schema.d.ts +1 -1
  59. package/dist/schema.js.map +1 -1
  60. package/dist/{type-mapper-n231Fspm.d.ts → type-mapper-CZzVeDj7.d.ts} +1 -1
  61. package/dist/{type-mapper-DrQmtznD.d.cts → type-mapper-DaBe-1ph.d.cts} +1 -1
  62. package/dist/{types-Ds3NQvny.d.ts → types-CUVzgZ9k.d.ts} +1 -1
  63. package/dist/{types-YoBjsa-A.d.cts → types-D-Fsdn_O.d.cts} +1 -1
  64. package/package.json +1 -1
package/dist/index.d.cts CHANGED
@@ -1,15 +1,15 @@
1
1
  export { StatusEnum, StatusEnumType } from './enums.cjs';
2
2
  export { BaseMutator, MutatorOptions } from './mutator.cjs';
3
3
  export { CollectionConfig, PermissionTemplates, PermissionValidationResult, RelationConfig, RelationField, RelationsConfig, RelationsField, baseImageFileSchema, baseSchema, baseSchemaWithTimestamps, createPermissions, defineCollection, extractRelationMetadata, inputImageFileSchema, isPermissionSchema, isTemplateConfig, mergePermissions, omitImageFilesSchema, resolveTemplate, validatePermissionConfig, validateRuleExpression, withIndexes, withPermissions } from './schema.cjs';
4
- export { i as AutodateField, A as AutodateFieldOptions, B as BoolField, h as DateField, D as DateFieldOptions, g as EditorField, E as EmailField, F as FIELD_METADATA_KEY, a as FieldMetadata, k as FileField, b as FileFieldOptions, l as FilesField, c as FilesFieldOptions, G as GeoPointField, J as JSONField, d as NumberField, N as NumberFieldOptions, P as PocketBaseFieldType, j as SelectField, S as SelectFieldOptions, f as TextField, T as TextFieldOptions, U as URLField, e as extractFieldMetadata } from './fields-UcOPu1OQ.cjs';
4
+ export { i as AutodateField, A as AutodateFieldOptions, B as BoolField, h as DateField, D as DateFieldOptions, g as EditorField, E as EmailField, F as FIELD_METADATA_KEY, a as FieldMetadata, k as FileField, b as FileFieldOptions, l as FilesField, c as FilesFieldOptions, G as GeoPointField, J as JSONField, d as NumberField, N as NumberFieldOptions, P as PocketBaseFieldType, j as SelectField, S as SelectFieldOptions, f as TextField, T as TextFieldOptions, U as URLField, e as extractFieldMetadata } from './fields-RVj26U-O.cjs';
5
5
  export { A as APIRuleType, P as PermissionSchema, a as PermissionTemplate, b as PermissionTemplateConfig, R as RuleExpression } from './permissions-ZHafVSIx.cjs';
6
6
  export { SchemaAnalyzer, SchemaAnalyzerConfig, buildFieldDefinition, buildSchemaDefinition, convertZodSchemaToCollectionSchema, discoverSchemaFiles, extractFieldDefinitions, extractIndexes, extractSchemaDefinitions, getCollectionNameFromFile, importSchemaModule, isAuthCollection, parseSchemaFiles, selectSchemaForCollection } from './migration/analyzer.cjs';
7
7
  export { SnapshotConfig, SnapshotManager, convertPocketBaseMigration, findLatestSnapshot, getSnapshotPath, getSnapshotVersion, loadBaseMigration, loadSnapshot, loadSnapshotIfExists, loadSnapshotWithMigrations, mergeSnapshots, saveSnapshot, snapshotExists, validateSnapshot } from './migration/snapshot.cjs';
8
8
  export { ChangeSummary, DestructiveChange, DiffEngine, DiffEngineConfig, aggregateChanges, categorizeChangesBySeverity, compare, compareFieldConstraints, compareFieldOptions, compareFieldTypes, comparePermissions, compareRelationConfigurations, detectDestructiveChanges, detectFieldChanges, filterSystemCollections, findNewCollections, findNewFields, findRemovedCollections, findRemovedFields, generateChangeSummary, getUsersSystemFields, isSystemCollection, matchCollectionsByName, matchFieldsByName, requiresForceFlag } from './migration/diff.cjs';
9
9
  export { MigrationGenerator, MigrationGeneratorConfig, createMigrationFileStructure, generate, generateCollectionCreation, generateCollectionPermissions, generateCollectionRules, generateDownMigration, generateFieldAddition, generateFieldDefinitionObject, generateFieldDeletion, generateFieldModification, generateFieldsArray, generateIndexesArray, generateMigrationDescription, generateMigrationFilename, generatePermissionUpdate, generateTimestamp, generateUpMigration, writeMigrationFile } from './migration/generator.cjs';
10
- export { d as CollectionModification, f as CollectionOperation, C as CollectionSchema, b as FieldChange, F as FieldDefinition, c as FieldModification, P as PermissionChange, R as RuleUpdate, S as SchemaDefinition, e as SchemaDiff, a as SchemaSnapshot } from './types-YoBjsa-A.cjs';
10
+ export { d as CollectionModification, f as CollectionOperation, C as CollectionSchema, b as FieldChange, F as FieldDefinition, c as FieldModification, P as PermissionChange, R as RuleUpdate, S as SchemaDefinition, e as SchemaDiff, a as SchemaSnapshot } from './types-D-Fsdn_O.cjs';
11
11
  export { CLIUsageError, ConfigurationError, FileSystemError, MigrationError, MigrationGenerationError, SchemaParsingError, SnapshotError } from './migration/index.cjs';
12
- export { E as ExtractedFieldOptions, d as FIELD_TYPE_INFO, F as FieldTypeInfo, C as FieldTypeResult, P as POCKETBASE_FIELD_TYPES, z as extractComprehensiveFieldOptions, o as extractFieldOptions, x as getArrayElementType, v as getDefaultValue, D as getFieldTypeInfo, g as getMaxSelect, c as getMinSelect, w as isArrayType, A as isEditorField, q as isFieldRequired, B as isFileFieldByName, y as isGeoPointType, a as isMultipleRelationField, b as isRelationField, i as isSingleRelationField, j as mapZodArrayType, f as mapZodBooleanType, k as mapZodDateType, h as mapZodEnumType, e as mapZodNumberType, l as mapZodRecordType, m as mapZodStringType, n as mapZodTypeToPocketBase, p as pluralize, r as resolveTargetCollection, s as singularize, t as toCollectionName, u as unwrapZodType } from './type-mapper-DrQmtznD.cjs';
12
+ export { E as ExtractedFieldOptions, d as FIELD_TYPE_INFO, F as FieldTypeInfo, C as FieldTypeResult, P as POCKETBASE_FIELD_TYPES, z as extractComprehensiveFieldOptions, o as extractFieldOptions, x as getArrayElementType, v as getDefaultValue, D as getFieldTypeInfo, g as getMaxSelect, c as getMinSelect, w as isArrayType, A as isEditorField, q as isFieldRequired, B as isFileFieldByName, y as isGeoPointType, a as isMultipleRelationField, b as isRelationField, i as isSingleRelationField, j as mapZodArrayType, f as mapZodBooleanType, k as mapZodDateType, h as mapZodEnumType, e as mapZodNumberType, l as mapZodRecordType, m as mapZodStringType, n as mapZodTypeToPocketBase, p as pluralize, r as resolveTargetCollection, s as singularize, t as toCollectionName, u as unwrapZodType } from './type-mapper-DaBe-1ph.cjs';
13
13
  export { generateMigration, getMigrationStatus } from './cli/index.cjs';
14
14
  export { formatChangeSummary, loadConfig, logError, logInfo, logSection, logSuccess, logWarning, withProgress } from './cli/utils/index.cjs';
15
15
  import 'zod';
package/dist/index.d.ts CHANGED
@@ -1,15 +1,15 @@
1
1
  export { StatusEnum, StatusEnumType } from './enums.js';
2
2
  export { BaseMutator, MutatorOptions } from './mutator.js';
3
3
  export { CollectionConfig, PermissionTemplates, PermissionValidationResult, RelationConfig, RelationField, RelationsConfig, RelationsField, baseImageFileSchema, baseSchema, baseSchemaWithTimestamps, createPermissions, defineCollection, extractRelationMetadata, inputImageFileSchema, isPermissionSchema, isTemplateConfig, mergePermissions, omitImageFilesSchema, resolveTemplate, validatePermissionConfig, validateRuleExpression, withIndexes, withPermissions } from './schema.js';
4
- export { i as AutodateField, A as AutodateFieldOptions, B as BoolField, h as DateField, D as DateFieldOptions, g as EditorField, E as EmailField, F as FIELD_METADATA_KEY, a as FieldMetadata, k as FileField, b as FileFieldOptions, l as FilesField, c as FilesFieldOptions, G as GeoPointField, J as JSONField, d as NumberField, N as NumberFieldOptions, P as PocketBaseFieldType, j as SelectField, S as SelectFieldOptions, f as TextField, T as TextFieldOptions, U as URLField, e as extractFieldMetadata } from './fields-UcOPu1OQ.js';
4
+ export { i as AutodateField, A as AutodateFieldOptions, B as BoolField, h as DateField, D as DateFieldOptions, g as EditorField, E as EmailField, F as FIELD_METADATA_KEY, a as FieldMetadata, k as FileField, b as FileFieldOptions, l as FilesField, c as FilesFieldOptions, G as GeoPointField, J as JSONField, d as NumberField, N as NumberFieldOptions, P as PocketBaseFieldType, j as SelectField, S as SelectFieldOptions, f as TextField, T as TextFieldOptions, U as URLField, e as extractFieldMetadata } from './fields-RVj26U-O.js';
5
5
  export { A as APIRuleType, P as PermissionSchema, a as PermissionTemplate, b as PermissionTemplateConfig, R as RuleExpression } from './permissions-ZHafVSIx.js';
6
6
  export { SchemaAnalyzer, SchemaAnalyzerConfig, buildFieldDefinition, buildSchemaDefinition, convertZodSchemaToCollectionSchema, discoverSchemaFiles, extractFieldDefinitions, extractIndexes, extractSchemaDefinitions, getCollectionNameFromFile, importSchemaModule, isAuthCollection, parseSchemaFiles, selectSchemaForCollection } from './migration/analyzer.js';
7
7
  export { SnapshotConfig, SnapshotManager, convertPocketBaseMigration, findLatestSnapshot, getSnapshotPath, getSnapshotVersion, loadBaseMigration, loadSnapshot, loadSnapshotIfExists, loadSnapshotWithMigrations, mergeSnapshots, saveSnapshot, snapshotExists, validateSnapshot } from './migration/snapshot.js';
8
8
  export { ChangeSummary, DestructiveChange, DiffEngine, DiffEngineConfig, aggregateChanges, categorizeChangesBySeverity, compare, compareFieldConstraints, compareFieldOptions, compareFieldTypes, comparePermissions, compareRelationConfigurations, detectDestructiveChanges, detectFieldChanges, filterSystemCollections, findNewCollections, findNewFields, findRemovedCollections, findRemovedFields, generateChangeSummary, getUsersSystemFields, isSystemCollection, matchCollectionsByName, matchFieldsByName, requiresForceFlag } from './migration/diff.js';
9
9
  export { MigrationGenerator, MigrationGeneratorConfig, createMigrationFileStructure, generate, generateCollectionCreation, generateCollectionPermissions, generateCollectionRules, generateDownMigration, generateFieldAddition, generateFieldDefinitionObject, generateFieldDeletion, generateFieldModification, generateFieldsArray, generateIndexesArray, generateMigrationDescription, generateMigrationFilename, generatePermissionUpdate, generateTimestamp, generateUpMigration, writeMigrationFile } from './migration/generator.js';
10
- export { d as CollectionModification, f as CollectionOperation, C as CollectionSchema, b as FieldChange, F as FieldDefinition, c as FieldModification, P as PermissionChange, R as RuleUpdate, S as SchemaDefinition, e as SchemaDiff, a as SchemaSnapshot } from './types-Ds3NQvny.js';
10
+ export { d as CollectionModification, f as CollectionOperation, C as CollectionSchema, b as FieldChange, F as FieldDefinition, c as FieldModification, P as PermissionChange, R as RuleUpdate, S as SchemaDefinition, e as SchemaDiff, a as SchemaSnapshot } from './types-CUVzgZ9k.js';
11
11
  export { CLIUsageError, ConfigurationError, FileSystemError, MigrationError, MigrationGenerationError, SchemaParsingError, SnapshotError } from './migration/index.js';
12
- export { E as ExtractedFieldOptions, d as FIELD_TYPE_INFO, F as FieldTypeInfo, C as FieldTypeResult, P as POCKETBASE_FIELD_TYPES, z as extractComprehensiveFieldOptions, o as extractFieldOptions, x as getArrayElementType, v as getDefaultValue, D as getFieldTypeInfo, g as getMaxSelect, c as getMinSelect, w as isArrayType, A as isEditorField, q as isFieldRequired, B as isFileFieldByName, y as isGeoPointType, a as isMultipleRelationField, b as isRelationField, i as isSingleRelationField, j as mapZodArrayType, f as mapZodBooleanType, k as mapZodDateType, h as mapZodEnumType, e as mapZodNumberType, l as mapZodRecordType, m as mapZodStringType, n as mapZodTypeToPocketBase, p as pluralize, r as resolveTargetCollection, s as singularize, t as toCollectionName, u as unwrapZodType } from './type-mapper-n231Fspm.js';
12
+ export { E as ExtractedFieldOptions, d as FIELD_TYPE_INFO, F as FieldTypeInfo, C as FieldTypeResult, P as POCKETBASE_FIELD_TYPES, z as extractComprehensiveFieldOptions, o as extractFieldOptions, x as getArrayElementType, v as getDefaultValue, D as getFieldTypeInfo, g as getMaxSelect, c as getMinSelect, w as isArrayType, A as isEditorField, q as isFieldRequired, B as isFileFieldByName, y as isGeoPointType, a as isMultipleRelationField, b as isRelationField, i as isSingleRelationField, j as mapZodArrayType, f as mapZodBooleanType, k as mapZodDateType, h as mapZodEnumType, e as mapZodNumberType, l as mapZodRecordType, m as mapZodStringType, n as mapZodTypeToPocketBase, p as pluralize, r as resolveTargetCollection, s as singularize, t as toCollectionName, u as unwrapZodType } from './type-mapper-CZzVeDj7.js';
13
13
  export { generateMigration, getMigrationStatus } from './cli/index.js';
14
14
  export { formatChangeSummary, loadConfig, logError, logInfo, logSection, logSuccess, logWarning, withProgress } from './cli/utils/index.js';
15
15
  import 'zod';
package/dist/index.js CHANGED
@@ -2470,7 +2470,7 @@ var SchemaAnalyzer = class {
2470
2470
  var SNAPSHOT_VERSION = "1.0.0";
2471
2471
  function resolveCollectionIdToName(collectionId) {
2472
2472
  if (collectionId === "_pb_users_auth_") {
2473
- return "Users";
2473
+ return "users";
2474
2474
  }
2475
2475
  const nameMatch = collectionId.match(/app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\)/);
2476
2476
  if (nameMatch) {
@@ -2478,6 +2478,39 @@ function resolveCollectionIdToName(collectionId) {
2478
2478
  }
2479
2479
  return collectionId;
2480
2480
  }
2481
+ function extractFieldOptions2(pbField) {
2482
+ const options = {};
2483
+ if (pbField.options && typeof pbField.options === "object") {
2484
+ Object.assign(options, pbField.options);
2485
+ }
2486
+ const directOptionKeys = [
2487
+ "min",
2488
+ "max",
2489
+ "pattern",
2490
+ "noDecimal",
2491
+ // text/number fields
2492
+ "values",
2493
+ "maxSelect",
2494
+ // select fields
2495
+ "mimeTypes",
2496
+ "maxSize",
2497
+ "thumbs",
2498
+ "protected",
2499
+ // file fields
2500
+ "onCreate",
2501
+ "onUpdate",
2502
+ // autodate fields
2503
+ "exceptDomains",
2504
+ "onlyDomains"
2505
+ // email/url fields
2506
+ ];
2507
+ for (const key of directOptionKeys) {
2508
+ if (pbField[key] !== void 0) {
2509
+ options[key] = pbField[key];
2510
+ }
2511
+ }
2512
+ return options;
2513
+ }
2481
2514
  function convertPocketBaseCollection(pbCollection) {
2482
2515
  const fields = [];
2483
2516
  const systemFieldNames = ["id", "created", "updated", "collectionId", "collectionName", "expand"];
@@ -2495,23 +2528,19 @@ function convertPocketBaseCollection(pbCollection) {
2495
2528
  type: pbField.type,
2496
2529
  required: pbField.required || false
2497
2530
  };
2498
- field.options = pbField.options ? { ...pbField.options } : {};
2499
- if (pbField.type === "select") {
2500
- if (pbField.values && Array.isArray(pbField.values)) {
2501
- field.options.values = pbField.values;
2502
- } else if (pbField.options?.values && Array.isArray(pbField.options.values)) {
2503
- field.options.values = pbField.options.values;
2504
- }
2505
- }
2531
+ field.options = extractFieldOptions2(pbField);
2506
2532
  if (pbField.type === "relation") {
2507
2533
  const collectionId = pbField.collectionId || pbField.options?.collectionId || "";
2508
- const collectionName = resolveCollectionIdToName(collectionId);
2534
+ const collectionName = resolveCollectionIdToName(collectionId || "");
2509
2535
  field.relation = {
2510
2536
  collection: collectionName,
2511
2537
  cascadeDelete: pbField.cascadeDelete ?? pbField.options?.cascadeDelete ?? false,
2512
2538
  maxSelect: pbField.maxSelect ?? pbField.options?.maxSelect,
2513
2539
  minSelect: pbField.minSelect ?? pbField.options?.minSelect
2514
2540
  };
2541
+ delete field.options.maxSelect;
2542
+ delete field.options.minSelect;
2543
+ delete field.options.cascadeDelete;
2515
2544
  }
2516
2545
  const hasOnlyValues = Object.keys(field.options).length === 1 && field.options.values !== void 0;
2517
2546
  if (Object.keys(field.options).length === 0) {
@@ -2525,17 +2554,21 @@ function convertPocketBaseCollection(pbCollection) {
2525
2554
  type: pbCollection.type || "base",
2526
2555
  fields
2527
2556
  };
2557
+ if (pbCollection.id) {
2558
+ schema.id = pbCollection.id;
2559
+ }
2528
2560
  if (pbCollection.indexes && Array.isArray(pbCollection.indexes)) {
2529
2561
  schema.indexes = pbCollection.indexes;
2530
2562
  }
2531
- const rules = {};
2532
- if (pbCollection.listRule !== void 0) rules.listRule = pbCollection.listRule;
2533
- if (pbCollection.viewRule !== void 0) rules.viewRule = pbCollection.viewRule;
2534
- if (pbCollection.createRule !== void 0) rules.createRule = pbCollection.createRule;
2535
- if (pbCollection.updateRule !== void 0) rules.updateRule = pbCollection.updateRule;
2536
- if (pbCollection.deleteRule !== void 0) rules.deleteRule = pbCollection.deleteRule;
2537
- if (pbCollection.manageRule !== void 0) rules.manageRule = pbCollection.manageRule;
2538
- if (Object.keys(rules).length > 0) {
2563
+ const hasAnyRule = pbCollection.listRule !== void 0 || pbCollection.viewRule !== void 0 || pbCollection.createRule !== void 0 || pbCollection.updateRule !== void 0 || pbCollection.deleteRule !== void 0 || pbCollection.manageRule !== void 0;
2564
+ if (hasAnyRule) {
2565
+ const rules = {};
2566
+ if (pbCollection.listRule !== void 0) rules.listRule = pbCollection.listRule;
2567
+ if (pbCollection.viewRule !== void 0) rules.viewRule = pbCollection.viewRule;
2568
+ if (pbCollection.createRule !== void 0) rules.createRule = pbCollection.createRule;
2569
+ if (pbCollection.updateRule !== void 0) rules.updateRule = pbCollection.updateRule;
2570
+ if (pbCollection.deleteRule !== void 0) rules.deleteRule = pbCollection.deleteRule;
2571
+ if (pbCollection.manageRule !== void 0) rules.manageRule = pbCollection.manageRule;
2539
2572
  schema.rules = rules;
2540
2573
  schema.permissions = { ...rules };
2541
2574
  }
@@ -3285,17 +3318,19 @@ var CollectionIdRegistry = class {
3285
3318
  }
3286
3319
  /**
3287
3320
  * Generates a unique collection ID for a given collection name
3288
- * Special case: Returns constant "_pb_users_auth_" for users collection
3289
3321
  * Retries up to 10 times if collision occurs (extremely rare)
3322
+ * Special case: returns "_pb_users_auth_" for users collection
3290
3323
  *
3291
- * @param collectionName - The name of the collection
3324
+ * @param collectionName - The name of the collection (optional)
3292
3325
  * @returns A unique collection ID
3293
3326
  * @throws Error if unable to generate unique ID after max attempts
3294
3327
  */
3295
3328
  generate(collectionName) {
3296
3329
  if (collectionName && collectionName.toLowerCase() === "users") {
3297
3330
  const usersId = "_pb_users_auth_";
3298
- this.register(usersId);
3331
+ if (!this.has(usersId)) {
3332
+ this.register(usersId);
3333
+ }
3299
3334
  return usersId;
3300
3335
  }
3301
3336
  const maxAttempts = 10;
@@ -3479,18 +3514,49 @@ function compareFieldConstraints(currentField, previousField) {
3479
3514
  }
3480
3515
  return changes;
3481
3516
  }
3517
+ function normalizeOptionValue(key, value, fieldType) {
3518
+ if (key === "maxSelect" && value === 1 && (fieldType === "select" || fieldType === "file")) {
3519
+ return void 0;
3520
+ }
3521
+ if (key === "maxSize" && value === 0 && fieldType === "file") {
3522
+ return void 0;
3523
+ }
3524
+ if (fieldType === "file") {
3525
+ if (key === "mimeTypes" && Array.isArray(value) && value.length === 0) {
3526
+ return void 0;
3527
+ }
3528
+ if (key === "thumbs" && Array.isArray(value) && value.length === 0) {
3529
+ return void 0;
3530
+ }
3531
+ if (key === "protected" && value === false) {
3532
+ return void 0;
3533
+ }
3534
+ }
3535
+ if (fieldType === "autodate") {
3536
+ if (key === "onCreate" && value === true) {
3537
+ return void 0;
3538
+ }
3539
+ if (key === "onUpdate" && value === false) {
3540
+ return void 0;
3541
+ }
3542
+ }
3543
+ return value;
3544
+ }
3482
3545
  function compareFieldOptions(currentField, previousField) {
3483
3546
  const changes = [];
3484
3547
  const currentOptions = currentField.options || {};
3485
3548
  const previousOptions = previousField.options || {};
3486
3549
  const allKeys = /* @__PURE__ */ new Set([...Object.keys(currentOptions), ...Object.keys(previousOptions)]);
3550
+ const fieldType = currentField.type;
3487
3551
  for (const key of allKeys) {
3488
3552
  const currentValue = currentOptions[key];
3489
3553
  const previousValue = previousOptions[key];
3490
- if (currentValue === void 0 && previousValue === void 0) {
3554
+ const normalizedCurrent = normalizeOptionValue(key, currentValue, fieldType);
3555
+ const normalizedPrevious = normalizeOptionValue(key, previousValue, fieldType);
3556
+ if (normalizedCurrent === void 0 && normalizedPrevious === void 0) {
3491
3557
  continue;
3492
3558
  }
3493
- if (!areValuesEqual(currentValue, previousValue)) {
3559
+ if (!areValuesEqual(normalizedCurrent, normalizedPrevious)) {
3494
3560
  changes.push({
3495
3561
  property: `options.${key}`,
3496
3562
  oldValue: previousValue,
@@ -3500,7 +3566,7 @@ function compareFieldOptions(currentField, previousField) {
3500
3566
  }
3501
3567
  return changes;
3502
3568
  }
3503
- function compareRelationConfigurations(currentField, previousField) {
3569
+ function compareRelationConfigurations(currentField, previousField, collectionIdToName) {
3504
3570
  const changes = [];
3505
3571
  const currentRelation = currentField.relation;
3506
3572
  const previousRelation = previousField.relation;
@@ -3512,8 +3578,8 @@ function compareRelationConfigurations(currentField, previousField) {
3512
3578
  }
3513
3579
  const normalizeCollection = (collection) => {
3514
3580
  if (!collection) return collection;
3515
- if (collection === "_pb_users_auth_") {
3516
- return "Users";
3581
+ if (collectionIdToName && collectionIdToName.has(collection)) {
3582
+ return collectionIdToName.get(collection);
3517
3583
  }
3518
3584
  const nameMatch = collection.match(/app\.findCollectionByNameOrId\s*\(\s*["']([^"']+)["']\s*\)/);
3519
3585
  if (nameMatch) {
@@ -3523,13 +3589,11 @@ function compareRelationConfigurations(currentField, previousField) {
3523
3589
  };
3524
3590
  const normalizedCurrent = normalizeCollection(currentRelation.collection);
3525
3591
  const normalizedPrevious = normalizeCollection(previousRelation.collection);
3526
- if (normalizedCurrent !== normalizedPrevious) {
3592
+ if (normalizedCurrent.toLowerCase() !== normalizedPrevious.toLowerCase()) {
3527
3593
  changes.push({
3528
3594
  property: "relation.collection",
3529
- oldValue: normalizedPrevious,
3530
- // Use normalized value for clarity
3531
- newValue: normalizedCurrent
3532
- // Use normalized value for clarity
3595
+ oldValue: previousRelation.collection,
3596
+ newValue: currentRelation.collection
3533
3597
  });
3534
3598
  }
3535
3599
  if (currentRelation.cascadeDelete !== previousRelation.cascadeDelete) {
@@ -3539,14 +3603,20 @@ function compareRelationConfigurations(currentField, previousField) {
3539
3603
  newValue: currentRelation.cascadeDelete
3540
3604
  });
3541
3605
  }
3542
- if (currentRelation.maxSelect !== previousRelation.maxSelect) {
3606
+ const normalizeMax = (val) => val === 1 ? null : val;
3607
+ const currentMax = normalizeMax(currentRelation.maxSelect);
3608
+ const previousMax = normalizeMax(previousRelation.maxSelect);
3609
+ if (currentMax != previousMax) {
3543
3610
  changes.push({
3544
3611
  property: "relation.maxSelect",
3545
3612
  oldValue: previousRelation.maxSelect,
3546
3613
  newValue: currentRelation.maxSelect
3547
3614
  });
3548
3615
  }
3549
- if (currentRelation.minSelect !== previousRelation.minSelect) {
3616
+ const normalizeMin = (val) => val === 0 ? null : val;
3617
+ const currentMin = normalizeMin(currentRelation.minSelect);
3618
+ const previousMin = normalizeMin(previousRelation.minSelect);
3619
+ if (currentMin != previousMin) {
3550
3620
  changes.push({
3551
3621
  property: "relation.minSelect",
3552
3622
  oldValue: previousRelation.minSelect,
@@ -3555,7 +3625,7 @@ function compareRelationConfigurations(currentField, previousField) {
3555
3625
  }
3556
3626
  return changes;
3557
3627
  }
3558
- function detectFieldChanges(currentField, previousField) {
3628
+ function detectFieldChanges(currentField, previousField, collectionIdToName) {
3559
3629
  const changes = [];
3560
3630
  const typeChange = compareFieldTypes(currentField, previousField);
3561
3631
  if (typeChange) {
@@ -3564,7 +3634,7 @@ function detectFieldChanges(currentField, previousField) {
3564
3634
  changes.push(...compareFieldConstraints(currentField, previousField));
3565
3635
  changes.push(...compareFieldOptions(currentField, previousField));
3566
3636
  if (currentField.type === "relation" && previousField.type === "relation") {
3567
- changes.push(...compareRelationConfigurations(currentField, previousField));
3637
+ changes.push(...compareRelationConfigurations(currentField, previousField, collectionIdToName));
3568
3638
  }
3569
3639
  return changes;
3570
3640
  }
@@ -3575,7 +3645,7 @@ function compareIndexes(currentIndexes = [], previousIndexes = []) {
3575
3645
  const indexesToRemove = previousIndexes.filter((idx) => !currentSet.has(idx));
3576
3646
  return { indexesToAdd, indexesToRemove };
3577
3647
  }
3578
- function compareRules(currentRules, previousRules) {
3648
+ function compareRules(currentRules, previousRules, currentPermissions, previousPermissions) {
3579
3649
  const updates = [];
3580
3650
  const ruleTypes = [
3581
3651
  "listRule",
@@ -3586,8 +3656,8 @@ function compareRules(currentRules, previousRules) {
3586
3656
  "manageRule"
3587
3657
  ];
3588
3658
  for (const ruleType of ruleTypes) {
3589
- const currentValue = currentRules?.[ruleType] ?? null;
3590
- const previousValue = previousRules?.[ruleType] ?? null;
3659
+ const currentValue = currentRules?.[ruleType] ?? currentPermissions?.[ruleType] ?? null;
3660
+ const previousValue = previousRules?.[ruleType] ?? previousPermissions?.[ruleType] ?? null;
3591
3661
  if (currentValue !== previousValue) {
3592
3662
  updates.push({
3593
3663
  ruleType,
@@ -3614,7 +3684,7 @@ function comparePermissions(currentPermissions, previousPermissions) {
3614
3684
  }
3615
3685
  return changes;
3616
3686
  }
3617
- function compareCollectionFields(currentCollection, previousCollection, config) {
3687
+ function compareCollectionFields(currentCollection, previousCollection, config, collectionIdToName) {
3618
3688
  let fieldsToAdd = findNewFields(currentCollection.fields, previousCollection.fields);
3619
3689
  const fieldsToRemove = findRemovedFields(currentCollection.fields, previousCollection.fields);
3620
3690
  const fieldsToModify = [];
@@ -3624,7 +3694,7 @@ function compareCollectionFields(currentCollection, previousCollection, config)
3624
3694
  }
3625
3695
  const matchedFields = matchFieldsByName(currentCollection.fields, previousCollection.fields);
3626
3696
  for (const [currentField, previousField] of matchedFields) {
3627
- const changes = detectFieldChanges(currentField, previousField);
3697
+ const changes = detectFieldChanges(currentField, previousField, collectionIdToName);
3628
3698
  if (changes.length > 0) {
3629
3699
  fieldsToModify.push({
3630
3700
  fieldName: currentField.name,
@@ -3636,14 +3706,20 @@ function compareCollectionFields(currentCollection, previousCollection, config)
3636
3706
  }
3637
3707
  return { fieldsToAdd, fieldsToRemove, fieldsToModify };
3638
3708
  }
3639
- function buildCollectionModification(currentCollection, previousCollection, config) {
3709
+ function buildCollectionModification(currentCollection, previousCollection, config, collectionIdToName) {
3640
3710
  const { fieldsToAdd, fieldsToRemove, fieldsToModify } = compareCollectionFields(
3641
3711
  currentCollection,
3642
3712
  previousCollection,
3643
- config
3713
+ config,
3714
+ collectionIdToName
3644
3715
  );
3645
3716
  const { indexesToAdd, indexesToRemove } = compareIndexes(currentCollection.indexes, previousCollection.indexes);
3646
- const rulesToUpdate = compareRules(currentCollection.rules, previousCollection.rules);
3717
+ const rulesToUpdate = compareRules(
3718
+ currentCollection.rules,
3719
+ previousCollection.rules,
3720
+ currentCollection.permissions,
3721
+ previousCollection.permissions
3722
+ );
3647
3723
  const permissionsToUpdate = comparePermissions(currentCollection.permissions, previousCollection.permissions);
3648
3724
  return {
3649
3725
  collection: currentCollection.name,
@@ -3660,6 +3736,14 @@ function hasChanges(modification) {
3660
3736
  return modification.fieldsToAdd.length > 0 || modification.fieldsToRemove.length > 0 || modification.fieldsToModify.length > 0 || modification.indexesToAdd.length > 0 || modification.indexesToRemove.length > 0 || modification.rulesToUpdate.length > 0 || modification.permissionsToUpdate.length > 0;
3661
3737
  }
3662
3738
  function aggregateChanges(currentSchema, previousSnapshot, config) {
3739
+ const collectionIdToName = /* @__PURE__ */ new Map();
3740
+ if (previousSnapshot) {
3741
+ for (const [name, collection] of previousSnapshot.collections) {
3742
+ if (collection.id) {
3743
+ collectionIdToName.set(collection.id, name);
3744
+ }
3745
+ }
3746
+ }
3663
3747
  const collectionsToCreate = findNewCollections(currentSchema, previousSnapshot);
3664
3748
  const collectionsToDelete = findRemovedCollections(currentSchema, previousSnapshot);
3665
3749
  const filteredCollectionsToCreate = collectionsToCreate.filter(
@@ -3683,7 +3767,7 @@ function aggregateChanges(currentSchema, previousSnapshot, config) {
3683
3767
  const collectionsToModify = [];
3684
3768
  const matchedCollections = matchCollectionsByName(currentSchema, previousSnapshot);
3685
3769
  for (const [currentCollection, previousCollection] of matchedCollections) {
3686
- const modification = buildCollectionModification(currentCollection, previousCollection, config);
3770
+ const modification = buildCollectionModification(currentCollection, previousCollection, config, collectionIdToName);
3687
3771
  if (hasChanges(modification)) {
3688
3772
  collectionsToModify.push(modification);
3689
3773
  }
@@ -4253,6 +4337,9 @@ function getSystemFields() {
4253
4337
  function generateCollectionCreation(collection, varName = "collection", isLast = false, collectionIdMap) {
4254
4338
  const lines = [];
4255
4339
  lines.push(` const ${varName} = new Collection({`);
4340
+ if (collection.id) {
4341
+ lines.push(` id: ${formatValue(collection.id)},`);
4342
+ }
4256
4343
  lines.push(` name: "${collection.name}",`);
4257
4344
  lines.push(` type: "${collection.type}",`);
4258
4345
  const permissionsCode = generateCollectionPermissions(collection.permissions);
@@ -4496,7 +4583,24 @@ function generateOperationUpMigration(operation, collectionIdMap) {
4496
4583
  const varName = `collection_${collectionName}`;
4497
4584
  lines.push(generateCollectionDeletion(collectionName, varName, true));
4498
4585
  }
4499
- return lines.join("\n");
4586
+ let code = lines.join("\n");
4587
+ const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
4588
+ const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
4589
+ const saveMatches = [...code.matchAll(savePattern)];
4590
+ const deleteMatches = [...code.matchAll(deletePattern)];
4591
+ const allMatches = [
4592
+ ...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
4593
+ ...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
4594
+ ].sort((a, b) => b.index - a.index);
4595
+ if (allMatches.length > 0) {
4596
+ const lastMatch = allMatches[0];
4597
+ if (lastMatch.type === "save") {
4598
+ 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);
4599
+ } else {
4600
+ 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);
4601
+ }
4602
+ }
4603
+ return code;
4500
4604
  }
4501
4605
  function generateOperationDownMigration(operation, collectionIdMap) {
4502
4606
  const lines = [];
@@ -4581,7 +4685,24 @@ function generateOperationDownMigration(operation, collectionIdMap) {
4581
4685
  lines.push(generateCollectionCreation(collection, varName, true, collectionIdMap));
4582
4686
  }
4583
4687
  }
4584
- return lines.join("\n");
4688
+ let code = lines.join("\n");
4689
+ const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
4690
+ const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
4691
+ const saveMatches = [...code.matchAll(savePattern)];
4692
+ const deleteMatches = [...code.matchAll(deletePattern)];
4693
+ const allMatches = [
4694
+ ...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
4695
+ ...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
4696
+ ].sort((a, b) => b.index - a.index);
4697
+ if (allMatches.length > 0) {
4698
+ const lastMatch = allMatches[0];
4699
+ if (lastMatch.type === "save") {
4700
+ 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);
4701
+ } else {
4702
+ 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);
4703
+ }
4704
+ }
4705
+ return code;
4585
4706
  }
4586
4707
  function generateUpMigration(diff) {
4587
4708
  const lines = [];