pocketbase-zod-schema 0.3.1 → 0.3.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 (60) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cli/index.cjs +64 -38
  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 +64 -38
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/cli/migrate.cjs +64 -38
  9. package/dist/cli/migrate.cjs.map +1 -1
  10. package/dist/cli/migrate.js +64 -38
  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-RVj26U-O.d.cts → fields-DBBm06VU.d.cts} +34 -7
  15. package/dist/{fields-RVj26U-O.d.ts → fields-DBBm06VU.d.ts} +34 -7
  16. package/dist/index.cjs +167 -75
  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 -75
  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 +10 -1
  27. package/dist/migration/diff.cjs.map +1 -1
  28. package/dist/migration/diff.d.cts +2 -2
  29. package/dist/migration/diff.d.ts +2 -2
  30. package/dist/migration/diff.js +10 -1
  31. package/dist/migration/diff.js.map +1 -1
  32. package/dist/migration/generator.cjs +102 -68
  33. package/dist/migration/generator.cjs.map +1 -1
  34. package/dist/migration/generator.d.cts +3 -3
  35. package/dist/migration/generator.d.ts +3 -3
  36. package/dist/migration/generator.js +102 -68
  37. package/dist/migration/generator.js.map +1 -1
  38. package/dist/migration/index.cjs +112 -69
  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 +112 -69
  43. package/dist/migration/index.js.map +1 -1
  44. package/dist/migration/snapshot.d.cts +2 -2
  45. package/dist/migration/snapshot.d.ts +2 -2
  46. package/dist/migration/utils/index.cjs.map +1 -1
  47. package/dist/migration/utils/index.d.cts +2 -2
  48. package/dist/migration/utils/index.d.ts +2 -2
  49. package/dist/migration/utils/index.js.map +1 -1
  50. package/dist/schema.cjs +55 -6
  51. package/dist/schema.cjs.map +1 -1
  52. package/dist/schema.d.cts +1 -1
  53. package/dist/schema.d.ts +1 -1
  54. package/dist/schema.js +55 -6
  55. package/dist/schema.js.map +1 -1
  56. package/dist/{type-mapper-DaBe-1ph.d.cts → type-mapper-DsGgZwUo.d.cts} +1 -1
  57. package/dist/{type-mapper-CZzVeDj7.d.ts → type-mapper-Dvh4QTM-.d.ts} +1 -1
  58. package/dist/{types-CUVzgZ9k.d.ts → types-BWhwQxG-.d.ts} +6 -1
  59. package/dist/{types-D-Fsdn_O.d.cts → types-d0yBwHoN.d.cts} +6 -1
  60. package/package.json +1 -1
@@ -2,9 +2,9 @@ export { SchemaAnalyzer, SchemaAnalyzerConfig, buildFieldDefinition, buildSchema
2
2
  export { SnapshotConfig, SnapshotManager, convertPocketBaseMigration, findLatestSnapshot, getSnapshotPath, getSnapshotVersion, loadBaseMigration, loadSnapshot, loadSnapshotIfExists, loadSnapshotWithMigrations, mergeSnapshots, saveSnapshot, snapshotExists, validateSnapshot } from './snapshot.cjs';
3
3
  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 './diff.cjs';
4
4
  export { MigrationGenerator, MigrationGeneratorConfig, createMigrationFileStructure, generate, generateCollectionCreation, generateCollectionPermissions, generateCollectionRules, generateDownMigration, generateFieldAddition, generateFieldDefinitionObject, generateFieldDeletion, generateFieldModification, generateFieldsArray, generateIndexesArray, generateMigrationDescription, generateMigrationFilename, generatePermissionUpdate, generateTimestamp, generateUpMigration, writeMigrationFile } from './generator.cjs';
5
- 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';
6
- 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';
7
- export { F as FIELD_METADATA_KEY, a as FieldMetadata, P as PocketBaseFieldType, e as extractFieldMetadata } from '../fields-RVj26U-O.cjs';
5
+ 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-d0yBwHoN.cjs';
6
+ 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-DsGgZwUo.cjs';
7
+ export { F as FIELD_METADATA_KEY, a as FieldMetadata, P as PocketBaseFieldType, e as extractFieldMetadata } from '../fields-DBBm06VU.cjs';
8
8
  export { A as APIRuleType } from '../permissions-ZHafVSIx.cjs';
9
9
  import 'zod';
10
10
 
@@ -2,9 +2,9 @@ export { SchemaAnalyzer, SchemaAnalyzerConfig, buildFieldDefinition, buildSchema
2
2
  export { SnapshotConfig, SnapshotManager, convertPocketBaseMigration, findLatestSnapshot, getSnapshotPath, getSnapshotVersion, loadBaseMigration, loadSnapshot, loadSnapshotIfExists, loadSnapshotWithMigrations, mergeSnapshots, saveSnapshot, snapshotExists, validateSnapshot } from './snapshot.js';
3
3
  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 './diff.js';
4
4
  export { MigrationGenerator, MigrationGeneratorConfig, createMigrationFileStructure, generate, generateCollectionCreation, generateCollectionPermissions, generateCollectionRules, generateDownMigration, generateFieldAddition, generateFieldDefinitionObject, generateFieldDeletion, generateFieldModification, generateFieldsArray, generateIndexesArray, generateMigrationDescription, generateMigrationFilename, generatePermissionUpdate, generateTimestamp, generateUpMigration, writeMigrationFile } from './generator.js';
5
- 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';
6
- 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';
7
- export { F as FIELD_METADATA_KEY, a as FieldMetadata, P as PocketBaseFieldType, e as extractFieldMetadata } from '../fields-RVj26U-O.js';
5
+ 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-BWhwQxG-.js';
6
+ 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-Dvh4QTM-.js';
7
+ export { F as FIELD_METADATA_KEY, a as FieldMetadata, P as PocketBaseFieldType, e as extractFieldMetadata } from '../fields-DBBm06VU.js';
8
8
  export { A as APIRuleType } from '../permissions-ZHafVSIx.js';
9
9
  import 'zod';
10
10
 
@@ -3075,10 +3075,19 @@ function aggregateChanges(currentSchema, previousSnapshot, config) {
3075
3075
  collectionsToModify.push(modification);
3076
3076
  }
3077
3077
  }
3078
+ const existingCollectionIds = /* @__PURE__ */ new Map();
3079
+ if (previousSnapshot) {
3080
+ for (const [name, collection] of previousSnapshot.collections) {
3081
+ if (collection.id) {
3082
+ existingCollectionIds.set(name, collection.id);
3083
+ }
3084
+ }
3085
+ }
3078
3086
  return {
3079
3087
  collectionsToCreate: collectionsWithIds,
3080
3088
  collectionsToDelete: filteredCollectionsToDelete,
3081
- collectionsToModify
3089
+ collectionsToModify,
3090
+ existingCollectionIds
3082
3091
  };
3083
3092
  }
3084
3093
  function detectDestructiveChanges(diff, config) {
@@ -3471,7 +3480,7 @@ function formatValue(value) {
3471
3480
  return JSON.stringify(value).replace(/","/g, '", "');
3472
3481
  }
3473
3482
  if (typeof value === "object") {
3474
- const entries = Object.entries(value).map(([k, v]) => `${k}: ${formatValue(v)}`).join(", ");
3483
+ const entries = Object.entries(value).filter(([_k, v]) => v !== void 0).map(([k, v]) => `${k}: ${formatValue(v)}`).join(", ");
3475
3484
  return `{ ${entries} }`;
3476
3485
  }
3477
3486
  return String(value);
@@ -3734,7 +3743,7 @@ function generateFieldAddition(collectionName, field, varName, isLast = false, c
3734
3743
  lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
3735
3744
  return lines.join("\n");
3736
3745
  }
3737
- function generateFieldModification(collectionName, modification, varName, isLast = false) {
3746
+ function generateFieldModification(collectionName, modification, varName, isLast = false, collectionIdMap) {
3738
3747
  const lines = [];
3739
3748
  const collectionVar = varName || `collection_${collectionName}_${modification.fieldName}`;
3740
3749
  const fieldVar = `${collectionVar}_field`;
@@ -3749,7 +3758,14 @@ function generateFieldModification(collectionName, modification, varName, isLast
3749
3758
  const relationKey = change.property.replace("relation.", "");
3750
3759
  if (relationKey === "collection") {
3751
3760
  const isUsersCollection = String(change.newValue).toLowerCase() === "users";
3752
- const collectionIdValue = isUsersCollection ? '"_pb_users_auth_"' : `app.findCollectionByNameOrId("${change.newValue}").id`;
3761
+ let collectionIdValue;
3762
+ if (isUsersCollection) {
3763
+ collectionIdValue = '"_pb_users_auth_"';
3764
+ } else if (collectionIdMap && collectionIdMap.has(String(change.newValue))) {
3765
+ collectionIdValue = `"${collectionIdMap.get(String(change.newValue))}"`;
3766
+ } else {
3767
+ collectionIdValue = `app.findCollectionByNameOrId("${change.newValue}").id`;
3768
+ }
3753
3769
  lines.push(` ${fieldVar}.collectionId = ${collectionIdValue};`);
3754
3770
  } else {
3755
3771
  lines.push(` ${fieldVar}.${relationKey} = ${formatValue(change.newValue)};`);
@@ -3765,11 +3781,9 @@ function generateFieldModification(collectionName, modification, varName, isLast
3765
3781
  function generateFieldDeletion(collectionName, fieldName, varName, isLast = false) {
3766
3782
  const lines = [];
3767
3783
  const collectionVar = varName || `collection_${collectionName}_${fieldName}`;
3768
- const fieldVar = `${collectionVar}_field`;
3769
3784
  lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
3770
- lines.push(` const ${fieldVar} = ${collectionVar}.fields.getByName("${fieldName}");`);
3771
3785
  lines.push(``);
3772
- lines.push(` ${collectionVar}.fields.remove(${fieldVar}.id);`);
3786
+ lines.push(` ${collectionVar}.fields.removeByName("${fieldName}");`);
3773
3787
  lines.push(``);
3774
3788
  lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
3775
3789
  return lines.join("\n");
@@ -3827,9 +3841,10 @@ function generateOperationUpMigration(operation, collectionIdMap) {
3827
3841
  const collectionName = typeof operation.collection === "string" ? operation.collection : operation.collection?.name ?? modification.collection;
3828
3842
  let operationCount = 0;
3829
3843
  const totalOperations = modification.fieldsToAdd.length + modification.fieldsToModify.length + modification.fieldsToRemove.length + modification.indexesToAdd.length + modification.indexesToRemove.length + modification.rulesToUpdate.length + modification.permissionsToUpdate.length;
3830
- for (const field of modification.fieldsToAdd) {
3844
+ for (let i = 0; i < modification.fieldsToAdd.length; i++) {
3845
+ const field = modification.fieldsToAdd[i];
3831
3846
  operationCount++;
3832
- const varName = `collection_${collectionName}_add_${field.name}`;
3847
+ const varName = `collection_${collectionName}_add_${field.name}_${i}`;
3833
3848
  const isLast = operationCount === totalOperations;
3834
3849
  lines.push(generateFieldAddition(collectionName, field, varName, isLast, collectionIdMap));
3835
3850
  if (!isLast) lines.push("");
@@ -3838,7 +3853,7 @@ function generateOperationUpMigration(operation, collectionIdMap) {
3838
3853
  operationCount++;
3839
3854
  const varName = `collection_${collectionName}_modify_${fieldMod.fieldName}`;
3840
3855
  const isLast = operationCount === totalOperations;
3841
- lines.push(generateFieldModification(collectionName, fieldMod, varName, isLast));
3856
+ lines.push(generateFieldModification(collectionName, fieldMod, varName, isLast, collectionIdMap));
3842
3857
  if (!isLast) lines.push("");
3843
3858
  }
3844
3859
  for (const field of modification.fieldsToRemove) {
@@ -3887,20 +3902,23 @@ function generateOperationUpMigration(operation, collectionIdMap) {
3887
3902
  lines.push(generateCollectionDeletion(collectionName, varName, true));
3888
3903
  }
3889
3904
  let code = lines.join("\n");
3890
- const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
3891
- const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
3892
- const saveMatches = [...code.matchAll(savePattern)];
3893
- const deleteMatches = [...code.matchAll(deletePattern)];
3894
- const allMatches = [
3895
- ...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
3896
- ...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
3897
- ].sort((a, b) => b.index - a.index);
3898
- if (allMatches.length > 0) {
3899
- const lastMatch = allMatches[0];
3900
- if (lastMatch.type === "save") {
3901
- 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);
3902
- } else {
3903
- 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);
3905
+ const hasReturnStatement = /return\s+app\.(save|delete)\(/m.test(code);
3906
+ if (!hasReturnStatement) {
3907
+ const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
3908
+ const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
3909
+ const saveMatches = [...code.matchAll(savePattern)];
3910
+ const deleteMatches = [...code.matchAll(deletePattern)];
3911
+ const allMatches = [
3912
+ ...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
3913
+ ...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
3914
+ ].sort((a, b) => b.index - a.index);
3915
+ if (allMatches.length > 0) {
3916
+ const lastMatch = allMatches[0];
3917
+ if (lastMatch.type === "save") {
3918
+ 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);
3919
+ } else {
3920
+ 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);
3921
+ }
3904
3922
  }
3905
3923
  }
3906
3924
  return code;
@@ -3989,20 +4007,23 @@ function generateOperationDownMigration(operation, collectionIdMap) {
3989
4007
  }
3990
4008
  }
3991
4009
  let code = lines.join("\n");
3992
- const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
3993
- const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
3994
- const saveMatches = [...code.matchAll(savePattern)];
3995
- const deleteMatches = [...code.matchAll(deletePattern)];
3996
- const allMatches = [
3997
- ...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
3998
- ...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
3999
- ].sort((a, b) => b.index - a.index);
4000
- if (allMatches.length > 0) {
4001
- const lastMatch = allMatches[0];
4002
- if (lastMatch.type === "save") {
4003
- 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);
4004
- } else {
4005
- 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);
4010
+ const hasReturnStatement = /return\s+app\.(save|delete)\(/m.test(code);
4011
+ if (!hasReturnStatement) {
4012
+ const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
4013
+ const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
4014
+ const saveMatches = [...code.matchAll(savePattern)];
4015
+ const deleteMatches = [...code.matchAll(deletePattern)];
4016
+ const allMatches = [
4017
+ ...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
4018
+ ...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
4019
+ ].sort((a, b) => b.index - a.index);
4020
+ if (allMatches.length > 0) {
4021
+ const lastMatch = allMatches[0];
4022
+ if (lastMatch.type === "save") {
4023
+ 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);
4024
+ } else {
4025
+ 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);
4026
+ }
4006
4027
  }
4007
4028
  }
4008
4029
  return code;
@@ -4017,6 +4038,11 @@ function generateUpMigration(diff) {
4017
4038
  collectionIdMap.set(collection.name, collection.id);
4018
4039
  }
4019
4040
  }
4041
+ if (diff.existingCollectionIds) {
4042
+ for (const [name, id] of diff.existingCollectionIds) {
4043
+ collectionIdMap.set(name, id);
4044
+ }
4045
+ }
4020
4046
  if (diff.collectionsToCreate.length > 0) {
4021
4047
  lines.push(` // Create new collections`);
4022
4048
  for (let i = 0; i < diff.collectionsToCreate.length; i++) {
@@ -4032,8 +4058,9 @@ function generateUpMigration(diff) {
4032
4058
  const collectionName = modification.collection;
4033
4059
  if (modification.fieldsToAdd.length > 0) {
4034
4060
  lines.push(` // Add fields to ${collectionName}`);
4035
- for (const field of modification.fieldsToAdd) {
4036
- const varName = `collection_${collectionName}_add_${field.name}`;
4061
+ for (let i = 0; i < modification.fieldsToAdd.length; i++) {
4062
+ const field = modification.fieldsToAdd[i];
4063
+ const varName = `collection_${collectionName}_add_${field.name}_${i}`;
4037
4064
  lines.push(generateFieldAddition(collectionName, field, varName, false, collectionIdMap));
4038
4065
  lines.push(``);
4039
4066
  }
@@ -4042,7 +4069,7 @@ function generateUpMigration(diff) {
4042
4069
  lines.push(` // Modify fields in ${collectionName}`);
4043
4070
  for (const fieldMod of modification.fieldsToModify) {
4044
4071
  const varName = `collection_${collectionName}_modify_${fieldMod.fieldName}`;
4045
- lines.push(generateFieldModification(collectionName, fieldMod, varName));
4072
+ lines.push(generateFieldModification(collectionName, fieldMod, varName, false, collectionIdMap));
4046
4073
  lines.push(``);
4047
4074
  }
4048
4075
  }
@@ -4103,20 +4130,23 @@ function generateUpMigration(diff) {
4103
4130
  lines.push(``);
4104
4131
  }
4105
4132
  let code = lines.join("\n");
4106
- const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
4107
- const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
4108
- const saveMatches = [...code.matchAll(savePattern)];
4109
- const deleteMatches = [...code.matchAll(deletePattern)];
4110
- const allMatches = [
4111
- ...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
4112
- ...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
4113
- ].sort((a, b) => b.index - a.index);
4114
- if (allMatches.length > 0) {
4115
- const lastMatch = allMatches[0];
4116
- if (lastMatch.type === "save") {
4117
- 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);
4118
- } else {
4119
- 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);
4133
+ const hasReturnStatement = /return\s+app\.(save|delete)\(/m.test(code);
4134
+ if (!hasReturnStatement) {
4135
+ const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
4136
+ const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
4137
+ const saveMatches = [...code.matchAll(savePattern)];
4138
+ const deleteMatches = [...code.matchAll(deletePattern)];
4139
+ const allMatches = [
4140
+ ...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
4141
+ ...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
4142
+ ].sort((a, b) => b.index - a.index);
4143
+ if (allMatches.length > 0) {
4144
+ const lastMatch = allMatches[0];
4145
+ if (lastMatch.type === "save") {
4146
+ 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);
4147
+ } else {
4148
+ 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);
4149
+ }
4120
4150
  }
4121
4151
  }
4122
4152
  return code;
@@ -4136,6 +4166,11 @@ function generateDownMigration(diff) {
4136
4166
  collectionIdMap.set(collection.name, collection.id);
4137
4167
  }
4138
4168
  }
4169
+ if (diff.existingCollectionIds) {
4170
+ for (const [name, id] of diff.existingCollectionIds) {
4171
+ collectionIdMap.set(name, id);
4172
+ }
4173
+ }
4139
4174
  if (diff.collectionsToDelete.length > 0) {
4140
4175
  lines.push(` // Recreate deleted collections`);
4141
4176
  for (let i = 0; i < diff.collectionsToDelete.length; i++) {
@@ -4233,20 +4268,23 @@ function generateDownMigration(diff) {
4233
4268
  lines.push(``);
4234
4269
  }
4235
4270
  let code = lines.join("\n");
4236
- const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
4237
- const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
4238
- const saveMatches = [...code.matchAll(savePattern)];
4239
- const deleteMatches = [...code.matchAll(deletePattern)];
4240
- const allMatches = [
4241
- ...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
4242
- ...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
4243
- ].sort((a, b) => b.index - a.index);
4244
- if (allMatches.length > 0) {
4245
- const lastMatch = allMatches[0];
4246
- if (lastMatch.type === "save") {
4247
- 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);
4248
- } else {
4249
- 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);
4271
+ const hasReturnStatement = /return\s+app\.(save|delete)\(/m.test(code);
4272
+ if (!hasReturnStatement) {
4273
+ const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
4274
+ const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
4275
+ const saveMatches = [...code.matchAll(savePattern)];
4276
+ const deleteMatches = [...code.matchAll(deletePattern)];
4277
+ const allMatches = [
4278
+ ...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
4279
+ ...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
4280
+ ].sort((a, b) => b.index - a.index);
4281
+ if (allMatches.length > 0) {
4282
+ const lastMatch = allMatches[0];
4283
+ if (lastMatch.type === "save") {
4284
+ 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);
4285
+ } else {
4286
+ 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);
4287
+ }
4250
4288
  }
4251
4289
  }
4252
4290
  return code;
@@ -4270,6 +4308,11 @@ function generate(diff, config) {
4270
4308
  collectionIdMap.set(collection.name, collection.id);
4271
4309
  }
4272
4310
  }
4311
+ if (diff.existingCollectionIds) {
4312
+ for (const [name, id] of diff.existingCollectionIds) {
4313
+ collectionIdMap.set(name, id);
4314
+ }
4315
+ }
4273
4316
  const baseTimestamp = generateTimestamp(normalizedConfig);
4274
4317
  const operations = splitDiffByCollection(diff, baseTimestamp);
4275
4318
  const filePaths = [];