diff --git a/lib/schema.js b/lib/schema.js index 62061f97ed9..9ca0b207e23 100644 --- a/lib/schema.js +++ b/lib/schema.js @@ -189,6 +189,34 @@ function aliasFields(schema, paths) { const prop = schema.paths[path].path; + if (Array.isArray(alias)) { + for (const a of alias) { + if (typeof a !== 'string') { + throw new Error('Invalid value for alias option on ' + prop + ', got ' + a); + } + + schema.aliases[a] = prop; + + schema. + virtual(a). + get((function(p) { + return function() { + if (typeof this.get === 'function') { + return this.get(p); + } + return this[p]; + }; + })(prop)). + set((function(p) { + return function(v) { + return this.$set(p, v); + }; + })(prop)); + } + + continue; + } + if (typeof alias !== 'string') { throw new Error('Invalid value for alias option on ' + prop + ', got ' + alias); } diff --git a/test/schema.alias.test.js b/test/schema.alias.test.js index 5cdfdab9306..ca25511e2e5 100644 --- a/test/schema.alias.test.js +++ b/test/schema.alias.test.js @@ -159,4 +159,34 @@ describe('schema alias option', function() { done(); // acquit:ignore:end }); + + it('array of aliases (gh-12368)', function() { + const productSchema = new Schema({ + n: { + type: String, + alias: ['name', 'product_name'] + } + }); + + const Product = db.model('Test', productSchema); + const doc = new Product({}); + + doc['product_name'] = 'Turbo Man'; + assert.equal(doc.n, 'Turbo Man'); + assert.equal(doc.name, 'Turbo Man'); + }); + + it('alias() method (gh-12368)', function() { + const schema = new Schema({ name: String }); + + schema.alias('name', 'otherName'); + assert.equal(schema.aliases['otherName'], 'name'); + assert.ok(schema.virtuals['otherName']); + + schema.alias('name', ['name1', 'name2']); + assert.equal(schema.aliases['name1'], 'name'); + assert.equal(schema.aliases['name2'], 'name'); + assert.ok(schema.virtuals['name1']); + assert.ok(schema.virtuals['name2']); + }); }); diff --git a/test/schema.test.js b/test/schema.test.js index f73aaccce14..36368c58b2d 100644 --- a/test/schema.test.js +++ b/test/schema.test.js @@ -2868,21 +2868,6 @@ describe('schema', function() { assert.equal(doc1.domain, doc2.domain); }); - - it('alias (gh-12368)', function() { - const schema = new Schema({ name: String }); - - schema.alias('name', 'otherName'); - assert.equal(schema.aliases['otherName'], 'name'); - assert.ok(schema.virtuals['otherName']); - - schema.alias('name', ['name1', 'name2']); - assert.equal(schema.aliases['name1'], 'name'); - assert.equal(schema.aliases['name2'], 'name'); - assert.ok(schema.virtuals['name1']); - assert.ok(schema.virtuals['name2']); - }); - it('allows defining ObjectIds and Decimal128s using Types.* (gh-12205)', function() { const schema = new Schema({ testId: mongoose.Types.ObjectId, diff --git a/types/index.d.ts b/types/index.d.ts index 300657604d7..9acecd1fe65 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -196,6 +196,12 @@ declare module 'mongoose' { /** Adds key path / schema type pairs to this schema. */ add(obj: SchemaDefinition> | Schema, prefix?: string): this; + /** + * Add an alias for `path`. This means getting or setting the `alias` + * is equivalent to getting or setting the `path`. + */ + alias(path: string, alias: string | string[]): this; + /** * Array of child schemas (from document arrays and single nested subdocs) * and their corresponding compiled models. Each element of the array is diff --git a/types/schematypes.d.ts b/types/schematypes.d.ts index 75e2258a7a4..899660d9fe6 100644 --- a/types/schematypes.d.ts +++ b/types/schematypes.d.ts @@ -57,7 +57,7 @@ declare module 'mongoose' { T | typeof SchemaType | Schema | SchemaDefinition | Function | AnyArray; /** Defines a virtual with the given name that gets/sets this path. */ - alias?: string; + alias?: string | string[]; /** Function or object describing how to validate this schematype. See [validation docs](https://mongoosejs.com/docs/validation.html). */ validate?: SchemaValidator | AnyArray>;