UNPKG

mongo-dot-notation

Version:
324 lines (323 loc) 11.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.$sort = exports.$slice = exports.$push = exports.$pull = exports.$pullAll = exports.$pop = exports.$addToSet = exports.$ = void 0; const field_1 = require("./field"); const operator_1 = require("./operator"); const positional = (field) => { if (typeof field === 'undefined') { return '$'; } const isIndex = typeof field === 'number' || /^\d+/.test(field); if (isIndex) { return field.toString(); } const isAll = field.startsWith('['); if (isAll) { return `$${field}`; } if (field === '') { return '$'; } return `$.${field}`; }; const combine = (value, chain1, chain2) => (0, operator_1.create)('$push', value, Object.assign(Object.assign({}, chain1 === null || chain1 === void 0 ? void 0 : chain1(value)), chain2 === null || chain2 === void 0 ? void 0 : chain2(value))); const position = (chain1, chain2) => (value) => (0, operator_1.create)('$push', value, { /** * Specifies the location in the array at which the `$push` operator inserts elements. * @see https://www.mongodb.com/docs/manual/reference/operator/update/position/ * @param index zero-based index * * @example * ```ts * // insert element `10` at position 1 in the array * flatten({ scores: $push(10).$each().$position(1) }); * ``` */ $position: (index) => combine(Object.assign(Object.assign({}, value), { $position: index }), chain1, chain2), }); const slice = (chain1, chain2) => (value) => (0, operator_1.create)('$push', value, { /** * Limits the number of array elements. * @see https://www.mongodb.com/docs/manual/reference/operator/update/slice/ * * @example * ```ts * // leave only the first 3 elements * flatten({ grades: $push().$each().$slice(3) }); * * // leave only the last element * flatten({ grades: $push().$each().$slice(-1) }); * * // empty the array * flatten({ grades: $push().$each().$slice(0) }); * ``` */ $slice: (count) => combine(Object.assign(Object.assign({}, value), { $slice: count }), chain1, chain2), }); const sort = (chain1, chain2) => (value) => (0, operator_1.create)('$push', value, { /** * Orders the elements of an array. * @param value sort specification (default `1`) * @see https://www.mongodb.com/docs/manual/reference/operator/update/sort/ * * @example * ```ts * // sort ascending an array of numbers * flatten({ scores: $push().$each().$sort(1) }); * * // sort descending an array of numbers * flatten({ scores: $push().$each().$sort(-1) }); * * // sort ascending an array of documents with `name` field * flatten({ users: $push().$each().$sort({ name: 1 }) }); * ``` */ $sort: (specification) => combine(Object.assign(Object.assign({}, value), { $sort: specification !== null && specification !== void 0 ? specification : 1 }), chain1, chain2), }); /** * The positional operator identifies **an element** or **multiple elements** matching a * given query condition to be updated in an array. * @param field _(optional)_ field of the array document to update. * * @see https://www.mongodb.com/docs/manual/reference/operator/update/positional/ * @see https://www.mongodb.com/docs/manual/reference/operator/update/positional-all/ * * @example * ```ts * // Increment by one the first element that matches the update query * $().$inc(1); * * // Increment by one the first element's `score` field that matches the update query * $('score').$inc(1); * * // Increment all elements by one * $('[]').$inc(1); * * // Increment all elements' `score` field by one * $('[].score').$inc(1); * * // Find all `grades` documents that have the `std` lower than seven * // and increment their `grade` by ten. * collection.updateOne( * criteria, * flatten({ grades: $('[element].grade').$inc(10) }), * { arrayFilters: [{ 'element.std': { $lt: 7 } }] } * ); * ``` */ const $ = (field) => { const key = positional(field); return (0, operator_1.create)(key, undefined, { /** * Merges the array element(s) identified by the current positional operator * with the given object. * @see https://www.mongodb.com/docs/manual/reference/operator/update/positional-all/#nested-arrays * @param value object to merge * * @example * ```ts * flatten({ points: $('[]').merge({ x: 0, y: 1 }) }); * * // { * // $set: { * // 'points.$[].x': 1, * // 'points.$[].y': 2, * // } * // } * ``` */ merge: (value) => (0, operator_1.create)(key, (0, operator_1.create)('merge', value)), /** * @see {@link $inc} */ $inc: (value) => (0, operator_1.create)(key, (0, field_1.$inc)(value)), /** * @see {@link $mul} */ $mul: (value) => (0, operator_1.create)(key, (0, field_1.$mul)(value)), /** * @see {@link $set} */ $set: (value) => (0, operator_1.create)(key, (0, field_1.$set)(value)), /** * @see {@link $unset} */ $unset: () => (0, operator_1.create)(key, (0, field_1.$unset)()), /** * @see {@link $rename} */ $rename: (field) => (0, operator_1.create)(key, (0, field_1.$rename)(field)), /** * @see {@link $min} */ $min: (value) => (0, operator_1.create)(key, (0, field_1.$min)(value)), /** * @see {@link $max} */ $max: (value) => (0, operator_1.create)(key, (0, field_1.$max)(value)), /** * @see {@link $currentDate} */ $currentDate: (type) => (0, operator_1.create)(key, (0, field_1.$currentDate)(type)), /** * @see {@link $timestamp} */ $timestamp: () => (0, operator_1.create)(key, (0, field_1.$timestamp)()), }); }; exports.$ = $; /** * Adds a value to an array unless the value is already present. * To add multiple values, chain with `$each` operator. * @param value the value to add * @see https://www.mongodb.com/docs/manual/reference/operator/update/addToSet/ * * @example * ```ts * // add just one element * flatten({ permissions: $addToSet('admin') }); * * // add multiple elements * flatten({ permissions: $addToSet(['read', 'write']).$each() }); * ``` */ const $addToSet = (value) => (0, operator_1.create)('$addToSet', value, { /** * Specifies that value to add is an array and that each element should be added. * @see https://www.mongodb.com/docs/manual/reference/operator/update/each/ */ $each: () => (0, operator_1.create)('$addToSet', { $each: Array.isArray(value) ? value : [value] }), }); exports.$addToSet = $addToSet; /** * Removes the first or last element of an array. * @param value specify `-1` to remove the first element, `1` to remove the last element * @see https://www.mongodb.com/docs/manual/reference/operator/update/pop/ * * @example * ```ts * // remove the first element from the array * flatten({ grades: $pop(-1) }); * // same as: * flatten({ grades: $pop().first() }); * ``` */ const $pop = (value = 1) => (0, operator_1.create)('$pop', value, { /** * Removes the first element from the array. */ first: () => (0, operator_1.create)('$pop', -1), /** * Removes the last element from the array. */ last: () => (0, operator_1.create)('$pop', 1), }); exports.$pop = $pop; /** * Removes all instances of the specified values from an existing array. * @param value the value(s) to remove from the array * @see https://www.mongodb.com/docs/manual/reference/operator/update/pullAll/ * * @example * ```ts * // remove all instances of the value `1` and `2` from the array * flatten({ score: $pullAll([1, 2]) }); * ``` */ const $pullAll = (value) => (0, operator_1.create)('$pullAll', Array.isArray(value) ? value : [value]); exports.$pullAll = $pullAll; /** * Removes from an existing array all instances of a value or values that match a specified condition. * Unlike the {@link $pullAll} operator, this operator can be used to remove all instances that match a query. * @param value the value(s) or condition to match to remove from the array * @see https://www.mongodb.com/docs/manual/reference/operator/update/pull/ * * @example * ```ts * // remove all instances of the value `0` and `1` from the array; * // same as using $pullAll * flatten({ scores: $pull([0, 1]) }); * * // remove all instances lower than or equal to `3` * flatten({ scores: $pull({ $lte: 3 }) }) * * // remove all documents with the field `name` equal to `Test` * flatten({ users: $pull({ name: { $eq: 'Test' } }) }) * ``` */ const $pull = (value) => (0, operator_1.create)('$pull', Array.isArray(value) ? { $in: value } : value); exports.$pull = $pull; /** * Appends a specified value to an array. * @param value the value(s) to append to the array * @see https://www.mongodb.com/docs/manual/reference/operator/update/push/ * * @example * ```ts * // append one element * flatten({ scores: $push(1) }); * * // append multiple elements * flatten({ scores: $push([1, 2, 3]).$each() }); * * // append an element and update to leave only the last ten * flatten({ scores: $push(7).$each().$slice(-10) }); * * // append an element and update to leave only the last ten sorted by value * flatten({ scores: $push(7).$each().$sort(1).$slice(-10) }); * * // append an element at position three in the array * flatten({ scores: $push(7).$each().$position(2) }); * ``` */ const $push = (value) => (0, operator_1.create)('$push', value, { /** * Specifies that value to add is an array and that each element should be added. * @see https://www.mongodb.com/docs/manual/reference/operator/update/each/ */ $each: () => { const arr = typeof value === 'undefined' ? [] : Array.isArray(value) ? value : [value]; const eachValue = { $each: arr }; return (0, operator_1.create)('$push', eachValue, Object.assign(Object.assign(Object.assign({}, position(sort(slice()), slice(sort()))(eachValue)), slice(position(sort()), sort(position()))(eachValue)), sort(slice(position()), position(slice()))(eachValue))); }, }); exports.$push = $push; /** * Limits the number of array elements. * Alias for `$push().$each().$slice()`. * @see https://www.mongodb.com/docs/manual/reference/operator/update/slice/ * * @example * ```ts * // leave only the first 3 elements * flatten({ grades: $slice(3) }); * * // leave only the last element * flatten({ grades: $slice(-1) }); * * // empty the array * flatten({ grades: $slice(0) }); * ``` */ const $slice = (count) => (0, exports.$push)().$each().$slice(count); exports.$slice = $slice; /** * Orders the elements of an array. * Alias for `$push().$each().$sort()`. * @param value sort specification (default `1`) * @see https://www.mongodb.com/docs/manual/reference/operator/update/sort/ * * @example * ```ts * // sort ascending an array of numbers * flatten({ scores: $sort(1) }); * * // sort descending an array of numbers * flatten({ scores: $sort(-1) }); * * // sort ascending an array of documents with `name` field * flatten({ users: $sort({ name: 1 }) }); * ``` */ const $sort = (specification) => (0, exports.$push)().$each().$sort(specification); exports.$sort = $sort;