Skip to content

Commit

Permalink
Merge pull request #15163 from Automattic/vkarpov15/gh-15084
Browse files Browse the repository at this point in the history
feat(document): support schematype-level transform option
  • Loading branch information
vkarpov15 authored Jan 8, 2025
2 parents 12e8431 + 933a283 commit 7cac003
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 8 deletions.
13 changes: 7 additions & 6 deletions lib/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -4256,24 +4256,25 @@ function applySchemaTypeTransforms(self, json) {

for (const path of paths) {
const schematype = schema.paths[path];
if (typeof schematype.options.transform === 'function') {
const topLevelTransformFunction = schematype.options.transform ?? schematype.constructor?.defaultOptions?.transform;
const embeddedSchemaTypeTransformFunction = schematype.$embeddedSchemaType?.options?.transform
?? schematype.$embeddedSchemaType?.constructor?.defaultOptions?.transform;
if (typeof topLevelTransformFunction === 'function') {
const val = self.$get(path);
if (val === undefined) {
continue;
}
const transformedValue = schematype.options.transform.call(self, val);
const transformedValue = topLevelTransformFunction.call(self, val);
throwErrorIfPromise(path, transformedValue);
utils.setValue(path, transformedValue, json);
} else if (schematype.$embeddedSchemaType != null &&
typeof schematype.$embeddedSchemaType.options.transform === 'function') {
} else if (typeof embeddedSchemaTypeTransformFunction === 'function') {
const val = self.$get(path);
if (val === undefined) {
continue;
}
const vals = [].concat(val);
const transform = schematype.$embeddedSchemaType.options.transform;
for (let i = 0; i < vals.length; ++i) {
const transformedValue = transform.call(self, vals[i]);
const transformedValue = embeddedSchemaTypeTransformFunction.call(self, vals[i]);
vals[i] = transformedValue;
throwErrorIfPromise(path, transformedValue);
}
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
"devDependencies": {
"@babel/core": "7.26.0",
"@babel/preset-env": "7.26.0",
"@typescript-eslint/eslint-plugin": "^8.18.0",
"@typescript-eslint/parser": "^8.18.0",
"@typescript-eslint/eslint-plugin": "8.18.0",
"@typescript-eslint/parser": "8.18.0",
"acquit": "1.3.0",
"acquit-ignore": "0.2.1",
"acquit-require": "0.1.1",
Expand Down
40 changes: 40 additions & 0 deletions test/document.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14225,6 +14225,46 @@ describe('document', function() {
assert.strictEqual(duplicateKeyError.message, 'Email must be unique');
assert.strictEqual(duplicateKeyError.cause.code, 11000);
});

it('supports global transforms per schematype (gh-15084)', async function() {
class SchemaCustomType extends mongoose.SchemaType {
constructor(key, options) {
super(key, options, 'CustomType');
}

cast(value) {
if (value === null) return null;
return new CustomType(value);
}
}
SchemaCustomType.schemaName = 'CustomType';

class CustomType {
constructor(value) {
this.value = value;
}
}

mongoose.Schema.Types.CustomType = SchemaCustomType;

const Model = db.model(
'Test',
new mongoose.Schema({
value: { type: mongoose.Schema.Types.CustomType }
})
);

const _id = new mongoose.Types.ObjectId('0'.repeat(24));
const doc = new Model({ _id });
doc.value = 1;

mongoose.Schema.Types.CustomType.set('transform', v => v == null ? v : v.value);

assert.deepStrictEqual(doc.toJSON(), { _id, value: 1 });
assert.deepStrictEqual(doc.toObject(), { _id, value: 1 });

delete mongoose.Schema.Types.CustomType;
});
});

describe('Check if instance function that is supplied in schema option is available', function() {
Expand Down

0 comments on commit 7cac003

Please sign in to comment.