mirror of
https://github.com/JonasunderscoreJones/jonas_jones-api.git
synced 2025-10-24 17:49:18 +02:00
some progress
This commit is contained in:
parent
aea93a5527
commit
e3c15bd288
1388 changed files with 306946 additions and 68323 deletions
282
node_modules/mongoose/lib/helpers/query/cast$expr.js
generated
vendored
Normal file
282
node_modules/mongoose/lib/helpers/query/cast$expr.js
generated
vendored
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
'use strict';
|
||||
|
||||
const CastError = require('../../error/cast');
|
||||
const StrictModeError = require('../../error/strict');
|
||||
const castNumber = require('../../cast/number');
|
||||
|
||||
const booleanComparison = new Set(['$and', '$or']);
|
||||
const comparisonOperator = new Set(['$cmp', '$eq', '$lt', '$lte', '$gt', '$gte']);
|
||||
const arithmeticOperatorArray = new Set([
|
||||
// avoid casting '$add' or '$subtract', because expressions can be either number or date,
|
||||
// and we don't have a good way of inferring which arguments should be numbers and which should
|
||||
// be dates.
|
||||
'$multiply',
|
||||
'$divide',
|
||||
'$log',
|
||||
'$mod',
|
||||
'$trunc',
|
||||
'$avg',
|
||||
'$max',
|
||||
'$min',
|
||||
'$stdDevPop',
|
||||
'$stdDevSamp',
|
||||
'$sum'
|
||||
]);
|
||||
const arithmeticOperatorNumber = new Set([
|
||||
'$abs',
|
||||
'$exp',
|
||||
'$ceil',
|
||||
'$floor',
|
||||
'$ln',
|
||||
'$log10',
|
||||
'$round',
|
||||
'$sqrt',
|
||||
'$sin',
|
||||
'$cos',
|
||||
'$tan',
|
||||
'$asin',
|
||||
'$acos',
|
||||
'$atan',
|
||||
'$atan2',
|
||||
'$asinh',
|
||||
'$acosh',
|
||||
'$atanh',
|
||||
'$sinh',
|
||||
'$cosh',
|
||||
'$tanh',
|
||||
'$degreesToRadians',
|
||||
'$radiansToDegrees'
|
||||
]);
|
||||
const arrayElementOperators = new Set([
|
||||
'$arrayElemAt',
|
||||
'$first',
|
||||
'$last'
|
||||
]);
|
||||
const dateOperators = new Set([
|
||||
'$year',
|
||||
'$month',
|
||||
'$week',
|
||||
'$dayOfMonth',
|
||||
'$dayOfYear',
|
||||
'$hour',
|
||||
'$minute',
|
||||
'$second',
|
||||
'$isoDayOfWeek',
|
||||
'$isoWeekYear',
|
||||
'$isoWeek',
|
||||
'$millisecond'
|
||||
]);
|
||||
const expressionOperator = new Set(['$not']);
|
||||
|
||||
module.exports = function cast$expr(val, schema, strictQuery) {
|
||||
if (typeof val !== 'object' || val === null) {
|
||||
throw new Error('`$expr` must be an object');
|
||||
}
|
||||
|
||||
return _castExpression(val, schema, strictQuery);
|
||||
};
|
||||
|
||||
function _castExpression(val, schema, strictQuery) {
|
||||
// Preserve the value if it represents a path or if it's null
|
||||
if (isPath(val) || val === null) {
|
||||
return val;
|
||||
}
|
||||
|
||||
if (val.$cond != null) {
|
||||
if (Array.isArray(val.$cond)) {
|
||||
val.$cond = val.$cond.map(expr => _castExpression(expr, schema, strictQuery));
|
||||
} else {
|
||||
val.$cond.if = _castExpression(val.$cond.if, schema, strictQuery);
|
||||
val.$cond.then = _castExpression(val.$cond.then, schema, strictQuery);
|
||||
val.$cond.else = _castExpression(val.$cond.else, schema, strictQuery);
|
||||
}
|
||||
} else if (val.$ifNull != null) {
|
||||
val.$ifNull.map(v => _castExpression(v, schema, strictQuery));
|
||||
} else if (val.$switch != null) {
|
||||
val.branches.map(v => _castExpression(v, schema, strictQuery));
|
||||
val.default = _castExpression(val.default, schema, strictQuery);
|
||||
}
|
||||
|
||||
const keys = Object.keys(val);
|
||||
for (const key of keys) {
|
||||
if (booleanComparison.has(key)) {
|
||||
val[key] = val[key].map(v => _castExpression(v, schema, strictQuery));
|
||||
} else if (comparisonOperator.has(key)) {
|
||||
val[key] = castComparison(val[key], schema, strictQuery);
|
||||
} else if (arithmeticOperatorArray.has(key)) {
|
||||
val[key] = castArithmetic(val[key], schema, strictQuery);
|
||||
} else if (arithmeticOperatorNumber.has(key)) {
|
||||
val[key] = castNumberOperator(val[key], schema, strictQuery);
|
||||
} else if (expressionOperator.has(key)) {
|
||||
val[key] = _castExpression(val[key], schema, strictQuery);
|
||||
}
|
||||
}
|
||||
|
||||
if (val.$in) {
|
||||
val.$in = castIn(val.$in, schema, strictQuery);
|
||||
}
|
||||
if (val.$size) {
|
||||
val.$size = castNumberOperator(val.$size, schema, strictQuery);
|
||||
}
|
||||
|
||||
_omitUndefined(val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
function _omitUndefined(val) {
|
||||
const keys = Object.keys(val);
|
||||
for (let i = 0, len = keys.length; i < len; ++i) {
|
||||
(val[keys[i]] === void 0) && delete val[keys[i]];
|
||||
}
|
||||
}
|
||||
|
||||
// { $op: <number> }
|
||||
function castNumberOperator(val) {
|
||||
if (!isLiteral(val)) {
|
||||
return val;
|
||||
}
|
||||
|
||||
try {
|
||||
return castNumber(val);
|
||||
} catch (err) {
|
||||
throw new CastError('Number', val);
|
||||
}
|
||||
}
|
||||
|
||||
function castIn(val, schema, strictQuery) {
|
||||
const path = val[1];
|
||||
if (!isPath(path)) {
|
||||
return val;
|
||||
}
|
||||
const search = val[0];
|
||||
|
||||
const schematype = schema.path(path.slice(1));
|
||||
if (schematype === null) {
|
||||
if (strictQuery === false) {
|
||||
return val;
|
||||
} else if (strictQuery === 'throw') {
|
||||
throw new StrictModeError('$in');
|
||||
}
|
||||
|
||||
return void 0;
|
||||
}
|
||||
|
||||
if (!schematype.$isMongooseArray) {
|
||||
throw new Error('Path must be an array for $in');
|
||||
}
|
||||
|
||||
return [
|
||||
schematype.$isMongooseDocumentArray ? schematype.$embeddedSchemaType.cast(search) : schematype.caster.cast(search),
|
||||
path
|
||||
];
|
||||
}
|
||||
|
||||
// { $op: [<number>, <number>] }
|
||||
function castArithmetic(val) {
|
||||
if (!Array.isArray(val)) {
|
||||
if (!isLiteral(val)) {
|
||||
return val;
|
||||
}
|
||||
try {
|
||||
return castNumber(val);
|
||||
} catch (err) {
|
||||
throw new CastError('Number', val);
|
||||
}
|
||||
}
|
||||
|
||||
return val.map(v => {
|
||||
if (!isLiteral(v)) {
|
||||
return v;
|
||||
}
|
||||
try {
|
||||
return castNumber(v);
|
||||
} catch (err) {
|
||||
throw new CastError('Number', v);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// { $op: [expression, expression] }
|
||||
function castComparison(val, schema, strictQuery) {
|
||||
if (!Array.isArray(val) || val.length !== 2) {
|
||||
throw new Error('Comparison operator must be an array of length 2');
|
||||
}
|
||||
|
||||
val[0] = _castExpression(val[0], schema, strictQuery);
|
||||
const lhs = val[0];
|
||||
|
||||
if (isLiteral(val[1])) {
|
||||
let path = null;
|
||||
let schematype = null;
|
||||
let caster = null;
|
||||
if (isPath(lhs)) {
|
||||
path = lhs.slice(1);
|
||||
schematype = schema.path(path);
|
||||
} else if (typeof lhs === 'object' && lhs != null) {
|
||||
for (const key of Object.keys(lhs)) {
|
||||
if (dateOperators.has(key) && isPath(lhs[key])) {
|
||||
path = lhs[key].slice(1) + '.' + key;
|
||||
caster = castNumber;
|
||||
} else if (arrayElementOperators.has(key) && isPath(lhs[key])) {
|
||||
path = lhs[key].slice(1) + '.' + key;
|
||||
schematype = schema.path(lhs[key].slice(1));
|
||||
if (schematype != null) {
|
||||
if (schematype.$isMongooseDocumentArray) {
|
||||
schematype = schematype.$embeddedSchemaType;
|
||||
} else if (schematype.$isMongooseArray) {
|
||||
schematype = schematype.caster;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const is$literal = typeof val[1] === 'object' && val[1] != null && val[1].$literal != null;
|
||||
if (schematype != null) {
|
||||
if (is$literal) {
|
||||
val[1] = { $literal: schematype.cast(val[1].$literal) };
|
||||
} else {
|
||||
val[1] = schematype.cast(val[1]);
|
||||
}
|
||||
} else if (caster != null) {
|
||||
if (is$literal) {
|
||||
try {
|
||||
val[1] = { $literal: caster(val[1].$literal) };
|
||||
} catch (err) {
|
||||
throw new CastError(caster.name.replace(/^cast/, ''), val[1], path + '.$literal');
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
val[1] = caster(val[1]);
|
||||
} catch (err) {
|
||||
throw new CastError(caster.name.replace(/^cast/, ''), val[1], path);
|
||||
}
|
||||
}
|
||||
} else if (path != null && strictQuery === true) {
|
||||
return void 0;
|
||||
} else if (path != null && strictQuery === 'throw') {
|
||||
throw new StrictModeError(path);
|
||||
}
|
||||
} else {
|
||||
val[1] = _castExpression(val[1]);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
function isPath(val) {
|
||||
return typeof val === 'string' && val[0] === '$';
|
||||
}
|
||||
|
||||
function isLiteral(val) {
|
||||
if (typeof val === 'string' && val[0] === '$') {
|
||||
return false;
|
||||
}
|
||||
if (typeof val === 'object' && val !== null && Object.keys(val).find(key => key[0] === '$')) {
|
||||
// The `$literal` expression can make an object a literal
|
||||
// https://www.mongodb.com/docs/manual/reference/operator/aggregation/literal/#mongodb-expression-exp.-literal
|
||||
return val.$literal != null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue