pocketbase-zod-schema 0.3.1 → 0.3.2

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 (56) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/cli/index.cjs +36 -32
  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 +36 -32
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/cli/migrate.cjs +36 -32
  9. package/dist/cli/migrate.cjs.map +1 -1
  10. package/dist/cli/migrate.js +36 -32
  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 +125 -66
  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 +125 -66
  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.d.cts +2 -2
  27. package/dist/migration/diff.d.ts +2 -2
  28. package/dist/migration/generator.cjs +70 -60
  29. package/dist/migration/generator.cjs.map +1 -1
  30. package/dist/migration/generator.d.cts +2 -2
  31. package/dist/migration/generator.d.ts +2 -2
  32. package/dist/migration/generator.js +70 -60
  33. package/dist/migration/generator.js.map +1 -1
  34. package/dist/migration/index.cjs +70 -60
  35. package/dist/migration/index.cjs.map +1 -1
  36. package/dist/migration/index.d.cts +3 -3
  37. package/dist/migration/index.d.ts +3 -3
  38. package/dist/migration/index.js +70 -60
  39. package/dist/migration/index.js.map +1 -1
  40. package/dist/migration/snapshot.d.cts +2 -2
  41. package/dist/migration/snapshot.d.ts +2 -2
  42. package/dist/migration/utils/index.cjs.map +1 -1
  43. package/dist/migration/utils/index.d.cts +2 -2
  44. package/dist/migration/utils/index.d.ts +2 -2
  45. package/dist/migration/utils/index.js.map +1 -1
  46. package/dist/schema.cjs +55 -6
  47. package/dist/schema.cjs.map +1 -1
  48. package/dist/schema.d.cts +1 -1
  49. package/dist/schema.d.ts +1 -1
  50. package/dist/schema.js +55 -6
  51. package/dist/schema.js.map +1 -1
  52. package/dist/{type-mapper-DaBe-1ph.d.cts → type-mapper-DsGgZwUo.d.cts} +1 -1
  53. package/dist/{type-mapper-CZzVeDj7.d.ts → type-mapper-Dvh4QTM-.d.ts} +1 -1
  54. package/dist/{types-D-Fsdn_O.d.cts → types-CVxPCgWX.d.cts} +1 -1
  55. package/dist/{types-CUVzgZ9k.d.ts → types-Dfp-NP2D.d.ts} +1 -1
  56. 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-RVj26U-O.cjs';
4
+ export { j as AutodateField, A as AutodateFieldOptions, d as BoolField, B as ByteSize, i as DateField, D as DateFieldOptions, h as EditorField, E as EmailField, F as FIELD_METADATA_KEY, a as FieldMetadata, l as FileField, b as FileFieldOptions, m as FilesField, c as FilesFieldOptions, G as GeoPointField, J as JSONField, f as NumberField, N as NumberFieldOptions, P as PocketBaseFieldType, k as SelectField, S as SelectFieldOptions, g as TextField, T as TextFieldOptions, U as URLField, e as extractFieldMetadata } from './fields-DBBm06VU.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-D-Fsdn_O.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-CVxPCgWX.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-DaBe-1ph.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-DsGgZwUo.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-RVj26U-O.js';
4
+ export { j as AutodateField, A as AutodateFieldOptions, d as BoolField, B as ByteSize, i as DateField, D as DateFieldOptions, h as EditorField, E as EmailField, F as FIELD_METADATA_KEY, a as FieldMetadata, l as FileField, b as FileFieldOptions, m as FilesField, c as FilesFieldOptions, G as GeoPointField, J as JSONField, f as NumberField, N as NumberFieldOptions, P as PocketBaseFieldType, k as SelectField, S as SelectFieldOptions, g as TextField, T as TextFieldOptions, U as URLField, e as extractFieldMetadata } from './fields-DBBm06VU.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-CUVzgZ9k.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-Dfp-NP2D.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-CZzVeDj7.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-Dvh4QTM-.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
@@ -461,6 +461,45 @@ function extractFieldMetadata(description) {
461
461
  }
462
462
  return null;
463
463
  }
464
+ var MAX_FILE_SIZE_BYTES = 8 * 1024 * 1024 * 1024;
465
+ function parseByteSizeToBytes(value, context) {
466
+ let bytes;
467
+ if (typeof value === "number") {
468
+ if (!Number.isFinite(value)) {
469
+ throw new Error(`${context}: maxSize must be a finite number of bytes`);
470
+ }
471
+ bytes = Math.round(value);
472
+ } else {
473
+ const trimmed = value.trim();
474
+ const match = /^(\d+(?:\.\d+)?)\s*([KMG])$/i.exec(trimmed);
475
+ if (!match) {
476
+ throw new Error(`${context}: maxSize string must be like "10K", "5M", or "1G" (case-insensitive)`);
477
+ }
478
+ const amount = Number(match[1]);
479
+ const unit = match[2].toUpperCase();
480
+ if (!Number.isFinite(amount)) {
481
+ throw new Error(`${context}: maxSize must be a valid number`);
482
+ }
483
+ const multiplier = unit === "K" ? 1024 : unit === "M" ? 1024 * 1024 : 1024 * 1024 * 1024;
484
+ bytes = Math.round(amount * multiplier);
485
+ }
486
+ if (bytes < 0) {
487
+ throw new Error(`${context}: maxSize must be >= 0`);
488
+ }
489
+ if (bytes > MAX_FILE_SIZE_BYTES) {
490
+ throw new Error(`${context}: maxSize cannot exceed 8G (${MAX_FILE_SIZE_BYTES} bytes)`);
491
+ }
492
+ return bytes;
493
+ }
494
+ function normalizeFileFieldOptions(options, context) {
495
+ if (!options) return options;
496
+ if (options.maxSize === void 0) return options;
497
+ return {
498
+ ...options,
499
+ // PocketBase expects bytes; normalize any human-friendly inputs to bytes here.
500
+ maxSize: parseByteSizeToBytes(options.maxSize, context)
501
+ };
502
+ }
464
503
  function BoolField() {
465
504
  const metadata = {
466
505
  [FIELD_METADATA_KEY]: {
@@ -583,11 +622,14 @@ function SelectField(values, options) {
583
622
  return enumSchema.describe(JSON.stringify(metadata));
584
623
  }
585
624
  function FileField(options) {
586
- const schema = z.instanceof(File);
625
+ const schema = z.preprocess((val) => {
626
+ return val instanceof File ? val.name || "" : val;
627
+ }, z.string());
628
+ const normalizedOptions = normalizeFileFieldOptions(options, "FileField");
587
629
  const metadata = {
588
630
  [FIELD_METADATA_KEY]: {
589
631
  type: "file",
590
- options: options || {}
632
+ options: normalizedOptions || {}
591
633
  }
592
634
  };
593
635
  return schema.describe(JSON.stringify(metadata));
@@ -598,17 +640,24 @@ function FilesField(options) {
598
640
  throw new Error("FilesField: minSelect cannot be greater than maxSelect");
599
641
  }
600
642
  }
601
- let schema = z.array(z.instanceof(File));
643
+ let baseArraySchema = z.array(z.string());
602
644
  if (options?.minSelect !== void 0) {
603
- schema = schema.min(options.minSelect);
645
+ baseArraySchema = baseArraySchema.min(options.minSelect);
604
646
  }
605
647
  if (options?.maxSelect !== void 0) {
606
- schema = schema.max(options.maxSelect);
648
+ baseArraySchema = baseArraySchema.max(options.maxSelect);
607
649
  }
650
+ const schema = z.preprocess((val) => {
651
+ if (Array.isArray(val)) {
652
+ return val.map((item) => item instanceof File ? item.name || "" : item);
653
+ }
654
+ return val;
655
+ }, baseArraySchema);
656
+ const normalizedOptions = normalizeFileFieldOptions(options, "FilesField");
608
657
  const metadata = {
609
658
  [FIELD_METADATA_KEY]: {
610
659
  type: "file",
611
- options: options || {}
660
+ options: normalizedOptions || {}
612
661
  }
613
662
  };
614
663
  return schema.describe(JSON.stringify(metadata));
@@ -4168,7 +4217,7 @@ function formatValue(value) {
4168
4217
  return JSON.stringify(value).replace(/","/g, '", "');
4169
4218
  }
4170
4219
  if (typeof value === "object") {
4171
- const entries = Object.entries(value).map(([k, v]) => `${k}: ${formatValue(v)}`).join(", ");
4220
+ const entries = Object.entries(value).filter(([_k, v]) => v !== void 0).map(([k, v]) => `${k}: ${formatValue(v)}`).join(", ");
4172
4221
  return `{ ${entries} }`;
4173
4222
  }
4174
4223
  return String(value);
@@ -4462,11 +4511,9 @@ function generateFieldModification(collectionName, modification, varName, isLast
4462
4511
  function generateFieldDeletion(collectionName, fieldName, varName, isLast = false) {
4463
4512
  const lines = [];
4464
4513
  const collectionVar = varName || `collection_${collectionName}_${fieldName}`;
4465
- const fieldVar = `${collectionVar}_field`;
4466
4514
  lines.push(` const ${collectionVar} = app.findCollectionByNameOrId("${collectionName}");`);
4467
- lines.push(` const ${fieldVar} = ${collectionVar}.fields.getByName("${fieldName}");`);
4468
4515
  lines.push(``);
4469
- lines.push(` ${collectionVar}.fields.remove(${fieldVar}.id);`);
4516
+ lines.push(` ${collectionVar}.fields.removeByName("${fieldName}");`);
4470
4517
  lines.push(``);
4471
4518
  lines.push(isLast ? ` return app.save(${collectionVar});` : ` app.save(${collectionVar});`);
4472
4519
  return lines.join("\n");
@@ -4584,20 +4631,23 @@ function generateOperationUpMigration(operation, collectionIdMap) {
4584
4631
  lines.push(generateCollectionDeletion(collectionName, varName, true));
4585
4632
  }
4586
4633
  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);
4634
+ const hasReturnStatement = /return\s+app\.(save|delete)\(/m.test(code);
4635
+ if (!hasReturnStatement) {
4636
+ const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
4637
+ const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
4638
+ const saveMatches = [...code.matchAll(savePattern)];
4639
+ const deleteMatches = [...code.matchAll(deletePattern)];
4640
+ const allMatches = [
4641
+ ...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
4642
+ ...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
4643
+ ].sort((a, b) => b.index - a.index);
4644
+ if (allMatches.length > 0) {
4645
+ const lastMatch = allMatches[0];
4646
+ if (lastMatch.type === "save") {
4647
+ 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);
4648
+ } else {
4649
+ 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);
4650
+ }
4601
4651
  }
4602
4652
  }
4603
4653
  return code;
@@ -4686,20 +4736,23 @@ function generateOperationDownMigration(operation, collectionIdMap) {
4686
4736
  }
4687
4737
  }
4688
4738
  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);
4739
+ const hasReturnStatement = /return\s+app\.(save|delete)\(/m.test(code);
4740
+ if (!hasReturnStatement) {
4741
+ const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
4742
+ const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
4743
+ const saveMatches = [...code.matchAll(savePattern)];
4744
+ const deleteMatches = [...code.matchAll(deletePattern)];
4745
+ const allMatches = [
4746
+ ...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
4747
+ ...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
4748
+ ].sort((a, b) => b.index - a.index);
4749
+ if (allMatches.length > 0) {
4750
+ const lastMatch = allMatches[0];
4751
+ if (lastMatch.type === "save") {
4752
+ 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);
4753
+ } else {
4754
+ 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);
4755
+ }
4703
4756
  }
4704
4757
  }
4705
4758
  return code;
@@ -4800,20 +4853,23 @@ function generateUpMigration(diff) {
4800
4853
  lines.push(``);
4801
4854
  }
4802
4855
  let code = lines.join("\n");
4803
- const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
4804
- const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
4805
- const saveMatches = [...code.matchAll(savePattern)];
4806
- const deleteMatches = [...code.matchAll(deletePattern)];
4807
- const allMatches = [
4808
- ...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
4809
- ...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
4810
- ].sort((a, b) => b.index - a.index);
4811
- if (allMatches.length > 0) {
4812
- const lastMatch = allMatches[0];
4813
- if (lastMatch.type === "save") {
4814
- 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);
4815
- } else {
4816
- 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);
4856
+ const hasReturnStatement = /return\s+app\.(save|delete)\(/m.test(code);
4857
+ if (!hasReturnStatement) {
4858
+ const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
4859
+ const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
4860
+ const saveMatches = [...code.matchAll(savePattern)];
4861
+ const deleteMatches = [...code.matchAll(deletePattern)];
4862
+ const allMatches = [
4863
+ ...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
4864
+ ...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
4865
+ ].sort((a, b) => b.index - a.index);
4866
+ if (allMatches.length > 0) {
4867
+ const lastMatch = allMatches[0];
4868
+ if (lastMatch.type === "save") {
4869
+ 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);
4870
+ } else {
4871
+ 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);
4872
+ }
4817
4873
  }
4818
4874
  }
4819
4875
  return code;
@@ -4930,20 +4986,23 @@ function generateDownMigration(diff) {
4930
4986
  lines.push(``);
4931
4987
  }
4932
4988
  let code = lines.join("\n");
4933
- const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
4934
- const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
4935
- const saveMatches = [...code.matchAll(savePattern)];
4936
- const deleteMatches = [...code.matchAll(deletePattern)];
4937
- const allMatches = [
4938
- ...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
4939
- ...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
4940
- ].sort((a, b) => b.index - a.index);
4941
- if (allMatches.length > 0) {
4942
- const lastMatch = allMatches[0];
4943
- if (lastMatch.type === "save") {
4944
- 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);
4945
- } else {
4946
- 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);
4989
+ const hasReturnStatement = /return\s+app\.(save|delete)\(/m.test(code);
4990
+ if (!hasReturnStatement) {
4991
+ const savePattern = /^(\s*)app\.save\((\w+)\);$/gm;
4992
+ const deletePattern = /^(\s*)app\.delete\((\w+)\);$/gm;
4993
+ const saveMatches = [...code.matchAll(savePattern)];
4994
+ const deleteMatches = [...code.matchAll(deletePattern)];
4995
+ const allMatches = [
4996
+ ...saveMatches.map((m) => ({ match: m, type: "save", index: m.index })),
4997
+ ...deleteMatches.map((m) => ({ match: m, type: "delete", index: m.index }))
4998
+ ].sort((a, b) => b.index - a.index);
4999
+ if (allMatches.length > 0) {
5000
+ const lastMatch = allMatches[0];
5001
+ if (lastMatch.type === "save") {
5002
+ 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);
5003
+ } else {
5004
+ 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);
5005
+ }
4947
5006
  }
4948
5007
  }
4949
5008
  return code;