mirror of
https://github.com/JonasunderscoreJones/jonas_jones-api.git
synced 2025-10-24 01:29:19 +02:00
some progress
This commit is contained in:
parent
aea93a5527
commit
e3c15bd288
1388 changed files with 306946 additions and 68323 deletions
52
node_modules/mongoose/lib/helpers/model/applyDefaultsToPOJO.js
generated
vendored
Normal file
52
node_modules/mongoose/lib/helpers/model/applyDefaultsToPOJO.js
generated
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = function applyDefaultsToPOJO(doc, schema) {
|
||||
const paths = Object.keys(schema.paths);
|
||||
const plen = paths.length;
|
||||
|
||||
for (let i = 0; i < plen; ++i) {
|
||||
let curPath = '';
|
||||
const p = paths[i];
|
||||
|
||||
const type = schema.paths[p];
|
||||
const path = type.splitPath();
|
||||
const len = path.length;
|
||||
let doc_ = doc;
|
||||
for (let j = 0; j < len; ++j) {
|
||||
if (doc_ == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
const piece = path[j];
|
||||
curPath += (!curPath.length ? '' : '.') + piece;
|
||||
|
||||
if (j === len - 1) {
|
||||
if (typeof doc_[piece] !== 'undefined') {
|
||||
if (type.$isSingleNested) {
|
||||
applyDefaultsToPOJO(doc_[piece], type.caster.schema);
|
||||
} else if (type.$isMongooseDocumentArray && Array.isArray(doc_[piece])) {
|
||||
doc_[piece].forEach(el => applyDefaultsToPOJO(el, type.schema));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
const def = type.getDefault(doc, false, { skipCast: true });
|
||||
if (typeof def !== 'undefined') {
|
||||
doc_[piece] = def;
|
||||
|
||||
if (type.$isSingleNested) {
|
||||
applyDefaultsToPOJO(def, type.caster.schema);
|
||||
} else if (type.$isMongooseDocumentArray && Array.isArray(def)) {
|
||||
def.forEach(el => applyDefaultsToPOJO(el, type.schema));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (doc_[piece] == null) {
|
||||
doc_[piece] = {};
|
||||
}
|
||||
doc_ = doc_[piece];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
149
node_modules/mongoose/lib/helpers/model/applyHooks.js
generated
vendored
Normal file
149
node_modules/mongoose/lib/helpers/model/applyHooks.js
generated
vendored
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
'use strict';
|
||||
|
||||
const symbols = require('../../schema/symbols');
|
||||
const promiseOrCallback = require('../promiseOrCallback');
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
module.exports = applyHooks;
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
applyHooks.middlewareFunctions = [
|
||||
'deleteOne',
|
||||
'save',
|
||||
'validate',
|
||||
'remove',
|
||||
'updateOne',
|
||||
'init'
|
||||
];
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
const alreadyHookedFunctions = new Set(applyHooks.middlewareFunctions.flatMap(fn => ([fn, `$__${fn}`])));
|
||||
|
||||
/**
|
||||
* Register hooks for this model
|
||||
*
|
||||
* @param {Model} model
|
||||
* @param {Schema} schema
|
||||
* @param {Object} options
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function applyHooks(model, schema, options) {
|
||||
options = options || {};
|
||||
|
||||
const kareemOptions = {
|
||||
useErrorHandlers: true,
|
||||
numCallbackParams: 1,
|
||||
nullResultByDefault: true,
|
||||
contextParameter: true
|
||||
};
|
||||
const objToDecorate = options.decorateDoc ? model : model.prototype;
|
||||
|
||||
model.$appliedHooks = true;
|
||||
for (const key of Object.keys(schema.paths)) {
|
||||
const type = schema.paths[key];
|
||||
let childModel = null;
|
||||
if (type.$isSingleNested) {
|
||||
childModel = type.caster;
|
||||
} else if (type.$isMongooseDocumentArray) {
|
||||
childModel = type.Constructor;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (childModel.$appliedHooks) {
|
||||
continue;
|
||||
}
|
||||
|
||||
applyHooks(childModel, type.schema, options);
|
||||
if (childModel.discriminators != null) {
|
||||
const keys = Object.keys(childModel.discriminators);
|
||||
for (const key of keys) {
|
||||
applyHooks(childModel.discriminators[key],
|
||||
childModel.discriminators[key].schema, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Built-in hooks rely on hooking internal functions in order to support
|
||||
// promises and make it so that `doc.save.toString()` provides meaningful
|
||||
// information.
|
||||
|
||||
const middleware = schema.s.hooks.
|
||||
filter(hook => {
|
||||
if (hook.name === 'updateOne' || hook.name === 'deleteOne') {
|
||||
return !!hook['document'];
|
||||
}
|
||||
if (hook.name === 'remove' || hook.name === 'init') {
|
||||
return hook['document'] == null || !!hook['document'];
|
||||
}
|
||||
if (hook.query != null || hook.document != null) {
|
||||
return hook.document !== false;
|
||||
}
|
||||
return true;
|
||||
}).
|
||||
filter(hook => {
|
||||
// If user has overwritten the method, don't apply built-in middleware
|
||||
if (schema.methods[hook.name]) {
|
||||
return !hook.fn[symbols.builtInMiddleware];
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
model._middleware = middleware;
|
||||
|
||||
objToDecorate.$__originalValidate = objToDecorate.$__originalValidate || objToDecorate.$__validate;
|
||||
|
||||
for (const method of ['save', 'validate', 'remove', 'deleteOne']) {
|
||||
const toWrap = method === 'validate' ? '$__originalValidate' : `$__${method}`;
|
||||
const wrapped = middleware.
|
||||
createWrapper(method, objToDecorate[toWrap], null, kareemOptions);
|
||||
objToDecorate[`$__${method}`] = wrapped;
|
||||
}
|
||||
objToDecorate.$__init = middleware.
|
||||
createWrapperSync('init', objToDecorate.$__init, null, kareemOptions);
|
||||
|
||||
// Support hooks for custom methods
|
||||
const customMethods = Object.keys(schema.methods);
|
||||
const customMethodOptions = Object.assign({}, kareemOptions, {
|
||||
// Only use `checkForPromise` for custom methods, because mongoose
|
||||
// query thunks are not as consistent as I would like about returning
|
||||
// a nullish value rather than the query. If a query thunk returns
|
||||
// a query, `checkForPromise` causes infinite recursion
|
||||
checkForPromise: true
|
||||
});
|
||||
for (const method of customMethods) {
|
||||
if (alreadyHookedFunctions.has(method)) {
|
||||
continue;
|
||||
}
|
||||
if (!middleware.hasHooks(method)) {
|
||||
// Don't wrap if there are no hooks for the custom method to avoid
|
||||
// surprises. Also, `createWrapper()` enforces consistent async,
|
||||
// so wrapping a sync method would break it.
|
||||
continue;
|
||||
}
|
||||
const originalMethod = objToDecorate[method];
|
||||
objToDecorate[method] = function() {
|
||||
const args = Array.prototype.slice.call(arguments);
|
||||
const cb = args.slice(-1).pop();
|
||||
const argsWithoutCallback = typeof cb === 'function' ?
|
||||
args.slice(0, args.length - 1) : args;
|
||||
return promiseOrCallback(cb, callback => {
|
||||
return this[`$__${method}`].apply(this,
|
||||
argsWithoutCallback.concat([callback]));
|
||||
}, model.events);
|
||||
};
|
||||
objToDecorate[`$__${method}`] = middleware.
|
||||
createWrapper(method, originalMethod, null, customMethodOptions);
|
||||
}
|
||||
}
|
||||
70
node_modules/mongoose/lib/helpers/model/applyMethods.js
generated
vendored
Normal file
70
node_modules/mongoose/lib/helpers/model/applyMethods.js
generated
vendored
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
'use strict';
|
||||
|
||||
const get = require('../get');
|
||||
const utils = require('../../utils');
|
||||
|
||||
/**
|
||||
* Register methods for this model
|
||||
*
|
||||
* @param {Model} model
|
||||
* @param {Schema} schema
|
||||
* @api private
|
||||
*/
|
||||
|
||||
module.exports = function applyMethods(model, schema) {
|
||||
const Model = require('../../model');
|
||||
|
||||
function apply(method, schema) {
|
||||
Object.defineProperty(model.prototype, method, {
|
||||
get: function() {
|
||||
const h = {};
|
||||
for (const k in schema.methods[method]) {
|
||||
h[k] = schema.methods[method][k].bind(this);
|
||||
}
|
||||
return h;
|
||||
},
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
for (const method of Object.keys(schema.methods)) {
|
||||
const fn = schema.methods[method];
|
||||
if (schema.tree.hasOwnProperty(method)) {
|
||||
throw new Error('You have a method and a property in your schema both ' +
|
||||
'named "' + method + '"');
|
||||
}
|
||||
|
||||
// Avoid making custom methods if user sets a method to itself, e.g.
|
||||
// `schema.method(save, Document.prototype.save)`. Can happen when
|
||||
// calling `loadClass()` with a class that `extends Document`. See gh-12254
|
||||
if (typeof fn === 'function' &&
|
||||
Model.prototype[method] === fn) {
|
||||
delete schema.methods[method];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (schema.reserved[method] &&
|
||||
!get(schema, `methodOptions.${method}.suppressWarning`, false)) {
|
||||
utils.warn(`mongoose: the method name "${method}" is used by mongoose ` +
|
||||
'internally, overwriting it may cause bugs. If you\'re sure you know ' +
|
||||
'what you\'re doing, you can suppress this error by using ' +
|
||||
`\`schema.method('${method}', fn, { suppressWarning: true })\`.`);
|
||||
}
|
||||
if (typeof fn === 'function') {
|
||||
model.prototype[method] = fn;
|
||||
} else {
|
||||
apply(method, schema);
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively call `applyMethods()` on child schemas
|
||||
model.$appliedMethods = true;
|
||||
for (const key of Object.keys(schema.paths)) {
|
||||
const type = schema.paths[key];
|
||||
if (type.$isSingleNested && !type.caster.$appliedMethods) {
|
||||
applyMethods(type.caster, type.schema);
|
||||
}
|
||||
if (type.$isMongooseDocumentArray && !type.Constructor.$appliedMethods) {
|
||||
applyMethods(type.Constructor, type.schema);
|
||||
}
|
||||
}
|
||||
};
|
||||
71
node_modules/mongoose/lib/helpers/model/applyStaticHooks.js
generated
vendored
Normal file
71
node_modules/mongoose/lib/helpers/model/applyStaticHooks.js
generated
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
'use strict';
|
||||
|
||||
const middlewareFunctions = require('../query/applyQueryMiddleware').middlewareFunctions;
|
||||
const promiseOrCallback = require('../promiseOrCallback');
|
||||
|
||||
module.exports = function applyStaticHooks(model, hooks, statics) {
|
||||
const kareemOptions = {
|
||||
useErrorHandlers: true,
|
||||
numCallbackParams: 1
|
||||
};
|
||||
|
||||
hooks = hooks.filter(hook => {
|
||||
// If the custom static overwrites an existing query middleware, don't apply
|
||||
// middleware to it by default. This avoids a potential backwards breaking
|
||||
// change with plugins like `mongoose-delete` that use statics to overwrite
|
||||
// built-in Mongoose functions.
|
||||
if (middlewareFunctions.indexOf(hook.name) !== -1) {
|
||||
return !!hook.model;
|
||||
}
|
||||
return hook.model !== false;
|
||||
});
|
||||
|
||||
model.$__insertMany = hooks.createWrapper('insertMany',
|
||||
model.$__insertMany, model, kareemOptions);
|
||||
|
||||
for (const key of Object.keys(statics)) {
|
||||
if (hooks.hasHooks(key)) {
|
||||
const original = model[key];
|
||||
|
||||
model[key] = function() {
|
||||
const numArgs = arguments.length;
|
||||
const lastArg = numArgs > 0 ? arguments[numArgs - 1] : null;
|
||||
const cb = typeof lastArg === 'function' ? lastArg : null;
|
||||
const args = Array.prototype.slice.
|
||||
call(arguments, 0, cb == null ? numArgs : numArgs - 1);
|
||||
// Special case: can't use `Kareem#wrap()` because it doesn't currently
|
||||
// support wrapped functions that return a promise.
|
||||
return promiseOrCallback(cb, callback => {
|
||||
hooks.execPre(key, model, args, function(err) {
|
||||
if (err != null) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
let postCalled = 0;
|
||||
const ret = original.apply(model, args.concat(post));
|
||||
if (ret != null && typeof ret.then === 'function') {
|
||||
ret.then(res => post(null, res), err => post(err));
|
||||
}
|
||||
|
||||
function post(error, res) {
|
||||
if (postCalled++ > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (error != null) {
|
||||
return callback(error);
|
||||
}
|
||||
|
||||
hooks.execPost(key, model, [res], function(error) {
|
||||
if (error != null) {
|
||||
return callback(error);
|
||||
}
|
||||
callback(null, res);
|
||||
});
|
||||
}
|
||||
});
|
||||
}, model.events);
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
13
node_modules/mongoose/lib/helpers/model/applyStatics.js
generated
vendored
Normal file
13
node_modules/mongoose/lib/helpers/model/applyStatics.js
generated
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* Register statics for this model
|
||||
* @param {Model} model
|
||||
* @param {Schema} schema
|
||||
* @api private
|
||||
*/
|
||||
module.exports = function applyStatics(model, schema) {
|
||||
for (const i in schema.statics) {
|
||||
model[i] = schema.statics[i];
|
||||
}
|
||||
};
|
||||
240
node_modules/mongoose/lib/helpers/model/castBulkWrite.js
generated
vendored
Normal file
240
node_modules/mongoose/lib/helpers/model/castBulkWrite.js
generated
vendored
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
'use strict';
|
||||
|
||||
const getDiscriminatorByValue = require('../../helpers/discriminator/getDiscriminatorByValue');
|
||||
const applyTimestampsToChildren = require('../update/applyTimestampsToChildren');
|
||||
const applyTimestampsToUpdate = require('../update/applyTimestampsToUpdate');
|
||||
const cast = require('../../cast');
|
||||
const castUpdate = require('../query/castUpdate');
|
||||
const setDefaultsOnInsert = require('../setDefaultsOnInsert');
|
||||
|
||||
/**
|
||||
* Given a model and a bulkWrite op, return a thunk that handles casting and
|
||||
* validating the individual op.
|
||||
* @param {Model} originalModel
|
||||
* @param {Object} op
|
||||
* @param {Object} [options]
|
||||
* @api private
|
||||
*/
|
||||
|
||||
module.exports = function castBulkWrite(originalModel, op, options) {
|
||||
const now = originalModel.base.now();
|
||||
|
||||
if (op['insertOne']) {
|
||||
return (callback) => {
|
||||
const model = decideModelByObject(originalModel, op['insertOne']['document']);
|
||||
|
||||
const doc = new model(op['insertOne']['document']);
|
||||
if (model.schema.options.timestamps && options.timestamps !== false) {
|
||||
doc.initializeTimestamps();
|
||||
}
|
||||
if (options.session != null) {
|
||||
doc.$session(options.session);
|
||||
}
|
||||
op['insertOne']['document'] = doc;
|
||||
|
||||
if (options.skipValidation || op['insertOne'].skipValidation) {
|
||||
callback(null);
|
||||
return;
|
||||
}
|
||||
|
||||
op['insertOne']['document'].$validate().then(
|
||||
() => { callback(null); },
|
||||
err => { callback(err, null); }
|
||||
);
|
||||
};
|
||||
} else if (op['updateOne']) {
|
||||
return (callback) => {
|
||||
try {
|
||||
if (!op['updateOne']['filter']) {
|
||||
throw new Error('Must provide a filter object.');
|
||||
}
|
||||
if (!op['updateOne']['update']) {
|
||||
throw new Error('Must provide an update object.');
|
||||
}
|
||||
|
||||
const model = decideModelByObject(originalModel, op['updateOne']['filter']);
|
||||
const schema = model.schema;
|
||||
const strict = options.strict != null ? options.strict : model.schema.options.strict;
|
||||
|
||||
_addDiscriminatorToObject(schema, op['updateOne']['filter']);
|
||||
|
||||
if (model.schema.$timestamps != null && op['updateOne'].timestamps !== false) {
|
||||
const createdAt = model.schema.$timestamps.createdAt;
|
||||
const updatedAt = model.schema.$timestamps.updatedAt;
|
||||
applyTimestampsToUpdate(now, createdAt, updatedAt, op['updateOne']['update'], {});
|
||||
}
|
||||
|
||||
applyTimestampsToChildren(now, op['updateOne']['update'], model.schema);
|
||||
|
||||
if (op['updateOne'].setDefaultsOnInsert !== false) {
|
||||
setDefaultsOnInsert(op['updateOne']['filter'], model.schema, op['updateOne']['update'], {
|
||||
setDefaultsOnInsert: true,
|
||||
upsert: op['updateOne'].upsert
|
||||
});
|
||||
}
|
||||
|
||||
op['updateOne']['filter'] = cast(model.schema, op['updateOne']['filter'], {
|
||||
strict: strict,
|
||||
upsert: op['updateOne'].upsert
|
||||
});
|
||||
|
||||
op['updateOne']['update'] = castUpdate(model.schema, op['updateOne']['update'], {
|
||||
strict: strict,
|
||||
overwrite: false,
|
||||
upsert: op['updateOne'].upsert
|
||||
}, model, op['updateOne']['filter']);
|
||||
} catch (error) {
|
||||
return callback(error, null);
|
||||
}
|
||||
|
||||
callback(null);
|
||||
};
|
||||
} else if (op['updateMany']) {
|
||||
return (callback) => {
|
||||
try {
|
||||
if (!op['updateMany']['filter']) {
|
||||
throw new Error('Must provide a filter object.');
|
||||
}
|
||||
if (!op['updateMany']['update']) {
|
||||
throw new Error('Must provide an update object.');
|
||||
}
|
||||
|
||||
const model = decideModelByObject(originalModel, op['updateMany']['filter']);
|
||||
const schema = model.schema;
|
||||
const strict = options.strict != null ? options.strict : model.schema.options.strict;
|
||||
|
||||
if (op['updateMany'].setDefaultsOnInsert !== false) {
|
||||
setDefaultsOnInsert(op['updateMany']['filter'], model.schema, op['updateMany']['update'], {
|
||||
setDefaultsOnInsert: true,
|
||||
upsert: op['updateMany'].upsert
|
||||
});
|
||||
}
|
||||
|
||||
if (model.schema.$timestamps != null && op['updateMany'].timestamps !== false) {
|
||||
const createdAt = model.schema.$timestamps.createdAt;
|
||||
const updatedAt = model.schema.$timestamps.updatedAt;
|
||||
applyTimestampsToUpdate(now, createdAt, updatedAt, op['updateMany']['update'], {});
|
||||
}
|
||||
|
||||
applyTimestampsToChildren(now, op['updateMany']['update'], model.schema);
|
||||
|
||||
_addDiscriminatorToObject(schema, op['updateMany']['filter']);
|
||||
|
||||
op['updateMany']['filter'] = cast(model.schema, op['updateMany']['filter'], {
|
||||
strict: strict,
|
||||
upsert: op['updateMany'].upsert
|
||||
});
|
||||
|
||||
op['updateMany']['update'] = castUpdate(model.schema, op['updateMany']['update'], {
|
||||
strict: strict,
|
||||
overwrite: false,
|
||||
upsert: op['updateMany'].upsert
|
||||
}, model, op['updateMany']['filter']);
|
||||
} catch (error) {
|
||||
return callback(error, null);
|
||||
}
|
||||
|
||||
callback(null);
|
||||
};
|
||||
} else if (op['replaceOne']) {
|
||||
return (callback) => {
|
||||
const model = decideModelByObject(originalModel, op['replaceOne']['filter']);
|
||||
const schema = model.schema;
|
||||
const strict = options.strict != null ? options.strict : model.schema.options.strict;
|
||||
|
||||
_addDiscriminatorToObject(schema, op['replaceOne']['filter']);
|
||||
try {
|
||||
op['replaceOne']['filter'] = cast(model.schema, op['replaceOne']['filter'], {
|
||||
strict: strict,
|
||||
upsert: op['replaceOne'].upsert
|
||||
});
|
||||
} catch (error) {
|
||||
return callback(error, null);
|
||||
}
|
||||
|
||||
// set `skipId`, otherwise we get "_id field cannot be changed"
|
||||
const doc = new model(op['replaceOne']['replacement'], strict, true);
|
||||
if (model.schema.options.timestamps) {
|
||||
doc.initializeTimestamps();
|
||||
}
|
||||
if (options.session != null) {
|
||||
doc.$session(options.session);
|
||||
}
|
||||
op['replaceOne']['replacement'] = doc;
|
||||
|
||||
if (options.skipValidation || op['replaceOne'].skipValidation) {
|
||||
op['replaceOne']['replacement'] = op['replaceOne']['replacement'].toBSON();
|
||||
callback(null);
|
||||
return;
|
||||
}
|
||||
|
||||
op['replaceOne']['replacement'].$validate().then(
|
||||
() => {
|
||||
op['replaceOne']['replacement'] = op['replaceOne']['replacement'].toBSON();
|
||||
callback(null);
|
||||
},
|
||||
error => {
|
||||
callback(error, null);
|
||||
}
|
||||
);
|
||||
};
|
||||
} else if (op['deleteOne']) {
|
||||
return (callback) => {
|
||||
const model = decideModelByObject(originalModel, op['deleteOne']['filter']);
|
||||
const schema = model.schema;
|
||||
|
||||
_addDiscriminatorToObject(schema, op['deleteOne']['filter']);
|
||||
|
||||
try {
|
||||
op['deleteOne']['filter'] = cast(model.schema,
|
||||
op['deleteOne']['filter']);
|
||||
} catch (error) {
|
||||
return callback(error, null);
|
||||
}
|
||||
|
||||
callback(null);
|
||||
};
|
||||
} else if (op['deleteMany']) {
|
||||
return (callback) => {
|
||||
const model = decideModelByObject(originalModel, op['deleteMany']['filter']);
|
||||
const schema = model.schema;
|
||||
|
||||
_addDiscriminatorToObject(schema, op['deleteMany']['filter']);
|
||||
|
||||
try {
|
||||
op['deleteMany']['filter'] = cast(model.schema,
|
||||
op['deleteMany']['filter']);
|
||||
} catch (error) {
|
||||
return callback(error, null);
|
||||
}
|
||||
|
||||
callback(null);
|
||||
};
|
||||
} else {
|
||||
return (callback) => {
|
||||
callback(new Error('Invalid op passed to `bulkWrite()`'), null);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
function _addDiscriminatorToObject(schema, obj) {
|
||||
if (schema == null) {
|
||||
return;
|
||||
}
|
||||
if (schema.discriminatorMapping && !schema.discriminatorMapping.isRoot) {
|
||||
obj[schema.discriminatorMapping.key] = schema.discriminatorMapping.value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gets discriminator model if discriminator key is present in object
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function decideModelByObject(model, object) {
|
||||
const discriminatorKey = model.schema.options.discriminatorKey;
|
||||
if (object != null && object.hasOwnProperty(discriminatorKey)) {
|
||||
model = getDiscriminatorByValue(model.discriminators, object[discriminatorKey]) || model;
|
||||
}
|
||||
return model;
|
||||
}
|
||||
213
node_modules/mongoose/lib/helpers/model/discriminator.js
generated
vendored
Normal file
213
node_modules/mongoose/lib/helpers/model/discriminator.js
generated
vendored
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
'use strict';
|
||||
|
||||
const Mixed = require('../../schema/mixed');
|
||||
const applyBuiltinPlugins = require('../schema/applyBuiltinPlugins');
|
||||
const clone = require('../clone');
|
||||
const defineKey = require('../document/compile').defineKey;
|
||||
const get = require('../get');
|
||||
const utils = require('../../utils');
|
||||
const mergeDiscriminatorSchema = require('../../helpers/discriminator/mergeDiscriminatorSchema');
|
||||
|
||||
const CUSTOMIZABLE_DISCRIMINATOR_OPTIONS = {
|
||||
toJSON: true,
|
||||
toObject: true,
|
||||
_id: true,
|
||||
id: true,
|
||||
virtuals: true,
|
||||
methods: true
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
module.exports = function discriminator(model, name, schema, tiedValue, applyPlugins, mergeHooks) {
|
||||
if (!(schema && schema.instanceOfSchema)) {
|
||||
throw new Error('You must pass a valid discriminator Schema');
|
||||
}
|
||||
|
||||
mergeHooks = mergeHooks == null ? true : mergeHooks;
|
||||
|
||||
if (model.schema.discriminatorMapping &&
|
||||
!model.schema.discriminatorMapping.isRoot) {
|
||||
throw new Error('Discriminator "' + name +
|
||||
'" can only be a discriminator of the root model');
|
||||
}
|
||||
|
||||
if (applyPlugins) {
|
||||
const applyPluginsToDiscriminators = get(model.base,
|
||||
'options.applyPluginsToDiscriminators', false) || !mergeHooks;
|
||||
// Even if `applyPluginsToDiscriminators` isn't set, we should still apply
|
||||
// global plugins to schemas embedded in the discriminator schema (gh-7370)
|
||||
model.base._applyPlugins(schema, {
|
||||
skipTopLevel: !applyPluginsToDiscriminators
|
||||
});
|
||||
} else if (!mergeHooks) {
|
||||
applyBuiltinPlugins(schema);
|
||||
}
|
||||
|
||||
const key = model.schema.options.discriminatorKey;
|
||||
|
||||
const existingPath = model.schema.path(key);
|
||||
if (existingPath != null) {
|
||||
if (!utils.hasUserDefinedProperty(existingPath.options, 'select')) {
|
||||
existingPath.options.select = true;
|
||||
}
|
||||
existingPath.options.$skipDiscriminatorCheck = true;
|
||||
} else {
|
||||
const baseSchemaAddition = {};
|
||||
baseSchemaAddition[key] = {
|
||||
default: void 0,
|
||||
select: true,
|
||||
$skipDiscriminatorCheck: true
|
||||
};
|
||||
baseSchemaAddition[key][model.schema.options.typeKey] = String;
|
||||
model.schema.add(baseSchemaAddition);
|
||||
defineKey({
|
||||
prop: key,
|
||||
prototype: model.prototype,
|
||||
options: model.schema.options
|
||||
});
|
||||
}
|
||||
|
||||
if (schema.path(key) && schema.path(key).options.$skipDiscriminatorCheck !== true) {
|
||||
throw new Error('Discriminator "' + name +
|
||||
'" cannot have field with name "' + key + '"');
|
||||
}
|
||||
|
||||
let value = name;
|
||||
if ((typeof tiedValue === 'string' && tiedValue.length) || tiedValue != null) {
|
||||
value = tiedValue;
|
||||
}
|
||||
|
||||
function merge(schema, baseSchema) {
|
||||
// Retain original schema before merging base schema
|
||||
schema._baseSchema = baseSchema;
|
||||
if (baseSchema.paths._id &&
|
||||
baseSchema.paths._id.options &&
|
||||
!baseSchema.paths._id.options.auto) {
|
||||
schema.remove('_id');
|
||||
}
|
||||
|
||||
// Find conflicting paths: if something is a path in the base schema
|
||||
// and a nested path in the child schema, overwrite the base schema path.
|
||||
// See gh-6076
|
||||
const baseSchemaPaths = Object.keys(baseSchema.paths);
|
||||
const conflictingPaths = [];
|
||||
|
||||
for (const path of baseSchemaPaths) {
|
||||
if (schema.nested[path]) {
|
||||
conflictingPaths.push(path);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (path.indexOf('.') === -1) {
|
||||
continue;
|
||||
}
|
||||
const sp = path.split('.').slice(0, -1);
|
||||
let cur = '';
|
||||
for (const piece of sp) {
|
||||
cur += (cur.length ? '.' : '') + piece;
|
||||
if (schema.paths[cur] instanceof Mixed ||
|
||||
schema.singleNestedPaths[cur] instanceof Mixed) {
|
||||
conflictingPaths.push(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mergeDiscriminatorSchema(schema, baseSchema);
|
||||
|
||||
// Clean up conflicting paths _after_ merging re: gh-6076
|
||||
for (const conflictingPath of conflictingPaths) {
|
||||
delete schema.paths[conflictingPath];
|
||||
}
|
||||
|
||||
// Rebuild schema models because schemas may have been merged re: #7884
|
||||
schema.childSchemas.forEach(obj => {
|
||||
obj.model.prototype.$__setSchema(obj.schema);
|
||||
});
|
||||
|
||||
const obj = {};
|
||||
obj[key] = {
|
||||
default: value,
|
||||
select: true,
|
||||
set: function(newName) {
|
||||
if (newName === value || (Array.isArray(value) && utils.deepEqual(newName, value))) {
|
||||
return value;
|
||||
}
|
||||
throw new Error('Can\'t set discriminator key "' + key + '"');
|
||||
},
|
||||
$skipDiscriminatorCheck: true
|
||||
};
|
||||
obj[key][schema.options.typeKey] = existingPath ? existingPath.options[schema.options.typeKey] : String;
|
||||
schema.add(obj);
|
||||
|
||||
schema.discriminatorMapping = { key: key, value: value, isRoot: false };
|
||||
|
||||
if (baseSchema.options.collection) {
|
||||
schema.options.collection = baseSchema.options.collection;
|
||||
}
|
||||
const toJSON = schema.options.toJSON;
|
||||
const toObject = schema.options.toObject;
|
||||
const _id = schema.options._id;
|
||||
const id = schema.options.id;
|
||||
|
||||
const keys = Object.keys(schema.options);
|
||||
schema.options.discriminatorKey = baseSchema.options.discriminatorKey;
|
||||
const userProvidedOptions = schema._userProvidedOptions;
|
||||
for (const _key of keys) {
|
||||
if (!CUSTOMIZABLE_DISCRIMINATOR_OPTIONS[_key]) {
|
||||
// Use `schema.options` in `deepEqual()` because of `discriminatorKey`
|
||||
// set above. We don't allow customizing discriminator key, always
|
||||
// overwrite. See gh-9238
|
||||
if (_key in userProvidedOptions && !utils.deepEqual(schema.options[_key], baseSchema.options[_key])) {
|
||||
throw new Error('Can\'t customize discriminator option ' + _key +
|
||||
' (can only modify ' +
|
||||
Object.keys(CUSTOMIZABLE_DISCRIMINATOR_OPTIONS).join(', ') +
|
||||
')');
|
||||
}
|
||||
}
|
||||
}
|
||||
schema.options = clone(baseSchema.options);
|
||||
|
||||
for (const _key of Object.keys(userProvidedOptions)) {
|
||||
schema.options[_key] = userProvidedOptions[_key];
|
||||
}
|
||||
if (toJSON) schema.options.toJSON = toJSON;
|
||||
if (toObject) schema.options.toObject = toObject;
|
||||
if (typeof _id !== 'undefined') {
|
||||
schema.options._id = _id;
|
||||
}
|
||||
schema.options.id = id;
|
||||
if (mergeHooks) {
|
||||
schema.s.hooks = model.schema.s.hooks.merge(schema.s.hooks);
|
||||
}
|
||||
if (applyPlugins) {
|
||||
schema.plugins = Array.prototype.slice.call(baseSchema.plugins);
|
||||
}
|
||||
schema.callQueue = baseSchema.callQueue.concat(schema.callQueue);
|
||||
delete schema._requiredpaths; // reset just in case Schema#requiredPaths() was called on either schema
|
||||
}
|
||||
|
||||
// merges base schema into new discriminator schema and sets new type field.
|
||||
merge(schema, model.schema);
|
||||
|
||||
if (!model.discriminators) {
|
||||
model.discriminators = {};
|
||||
}
|
||||
|
||||
if (!model.schema.discriminatorMapping) {
|
||||
model.schema.discriminatorMapping = { key: key, value: null, isRoot: true };
|
||||
}
|
||||
if (!model.schema.discriminators) {
|
||||
model.schema.discriminators = {};
|
||||
}
|
||||
|
||||
model.schema.discriminators[name] = schema;
|
||||
|
||||
if (model.discriminators[name] && !schema.options.overwriteModels) {
|
||||
throw new Error('Discriminator with name "' + name + '" already exists');
|
||||
}
|
||||
|
||||
return schema;
|
||||
};
|
||||
15
node_modules/mongoose/lib/helpers/model/pushNestedArrayPaths.js
generated
vendored
Normal file
15
node_modules/mongoose/lib/helpers/model/pushNestedArrayPaths.js
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = function pushNestedArrayPaths(paths, nestedArray, path) {
|
||||
if (nestedArray == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < nestedArray.length; ++i) {
|
||||
if (Array.isArray(nestedArray[i])) {
|
||||
pushNestedArrayPaths(paths, nestedArray[i], path + '.' + i);
|
||||
} else {
|
||||
paths.push(path + '.' + i);
|
||||
}
|
||||
}
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue