mongo-dot-notation
Advanced tools
Comparing version 3.0.1 to 3.1.0
@@ -38,13 +38,32 @@ import { $currentDate } from './field'; | ||
/** | ||
* 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: <T extends Record<string, any>>(value: T) => import("./operator").Operator; | ||
/** | ||
* @see {@link $inc} | ||
*/ | ||
$inc: <T>(value?: T | undefined) => import("./operator").Operator; | ||
$inc: <T_1>(value?: T_1 | undefined) => import("./operator").Operator; | ||
/** | ||
* @see {@link $mul} | ||
*/ | ||
$mul: <T_1>(value?: T_1 | undefined) => import("./operator").Operator; | ||
$mul: <T_2>(value?: T_2 | undefined) => import("./operator").Operator; | ||
/** | ||
* @see {@link $set} | ||
*/ | ||
$set: <T_2>(value: T_2) => import("./operator").Operator; | ||
$set: <T_3>(value: T_3) => import("./operator").Operator; | ||
/** | ||
@@ -61,7 +80,7 @@ * @see {@link $unset} | ||
*/ | ||
$min: <T_3>(value: T_3) => import("./operator").Operator; | ||
$min: <T_4>(value: T_4) => import("./operator").Operator; | ||
/** | ||
* @see {@link $max} | ||
*/ | ||
$max: <T_4>(value: T_4) => import("./operator").Operator; | ||
$max: <T_5>(value: T_5) => import("./operator").Operator; | ||
/** | ||
@@ -68,0 +87,0 @@ * @see {@link $currentDate} |
@@ -18,2 +18,5 @@ "use strict"; | ||
} | ||
if (field === '') { | ||
return '$'; | ||
} | ||
return `$.${field}`; | ||
@@ -110,2 +113,21 @@ }; | ||
/** | ||
* 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} | ||
@@ -112,0 +134,0 @@ */ |
@@ -68,3 +68,16 @@ "use strict"; | ||
exports.flatten = flatten; | ||
const mergeInner = (obj, field, inner, value) => (Object.assign(Object.assign({}, obj), { [field]: Object.assign(Object.assign({}, obj[field]), { [inner]: value }) })); | ||
const dot = (options) => { | ||
const merge = (instructions, operator, field, value) => { | ||
if (!(0, operator_1.isOperator)(value)) { | ||
return mergeInner(instructions, operator, field, value); | ||
} | ||
if ((0, operator_1.getType)(value) === 'merge') { | ||
const mergeValue = (0, operator_1.getValue)(value); | ||
return isNullOrUndefined(mergeValue) | ||
? instructions | ||
: dotMerge(instructions, `${field}.${operator}`, mergeValue); | ||
} | ||
return mergeInner(instructions, (0, operator_1.getType)(value), `${field}.${operator}`, (0, operator_1.getValue)(value)); | ||
}; | ||
const visit = (instructions, field, value) => { | ||
@@ -87,8 +100,3 @@ const tail = isAtomic(value) || (Array.isArray(value) && !options.array); | ||
}; | ||
const merge = (instructions, operator, field, value) => { | ||
if ((0, operator_1.isOperator)(value)) { | ||
return merge(instructions, (0, operator_1.getType)(value), `${field}.${operator}`, (0, operator_1.getValue)(value)); | ||
} | ||
return Object.assign(Object.assign({}, instructions), { [operator]: Object.assign(Object.assign({}, instructions[operator]), { [field]: value }) }); | ||
}; | ||
const dotMerge = dot({ array: true, skipEmptyObjects: true }); | ||
const isAtomic = (value) => isPrimitive(value) || isBsonType(value); | ||
@@ -101,8 +109,7 @@ const TYPEOF_PRIMITIVES = ['number', 'string', 'boolean', 'symbol', 'bigint']; | ||
const isPrimitive = (value) => { | ||
if (value === null || typeof value === 'undefined') { | ||
return true; | ||
} | ||
return (TYPEOF_PRIMITIVES.some((type) => typeof value === type) || | ||
return (isNullOrUndefined(value) || | ||
TYPEOF_PRIMITIVES.some((type) => typeof value === type) || | ||
INSTANCEOF_PRIMITIVES.some((type) => value instanceof type)); | ||
}; | ||
const isNullOrUndefined = (value) => value === null || typeof value === 'undefined'; | ||
const isBsonType = (value) => '_bsontype' in value; |
{ | ||
"name": "mongo-dot-notation", | ||
"version": "3.0.1", | ||
"description": "Transform objects to mongo update instructions", | ||
"version": "3.1.0", | ||
"description": "Transform objects to MongoDB update instructions", | ||
"author": { | ||
@@ -6,0 +6,0 @@ "name": "Dumitru Deveatii", |
201
README.md
@@ -5,5 +5,5 @@ # mongo-dot-notation | ||
[](https://npmjs.org/package/mongo-dot-notation) | ||
[](https://github.com/dimadeveatii/mongo-dot-notation/actions/workflows/ci.yml?query=branch%3Amain++) | ||
[](https://coveralls.io/github/dimadeveatii/mongo-dot-notation?branch=main) | ||
[](https://npmjs.org/package/mongo-dot-notation) | ||
[](https://npmjs.org/package/mongo-dot-notation) | ||
@@ -47,6 +47,6 @@ | ||
- Fully supported MongoDB [update operators](https://www.mongodb.com/docs/manual/reference/operator/update/) | ||
- _Field_ | ||
- _Array_ | ||
- _Bitwise_ | ||
- Supports all MongoDB [update operators](https://www.mongodb.com/docs/manual/reference/operator/update/) | ||
- Field update operators | ||
- Array update operators | ||
- Bitwise update operators | ||
- No `npm` dependency on `mongo` | ||
@@ -118,3 +118,3 @@ - Written in TypeScript | ||
```ts | ||
import { flatten } from 'mongo-dot-notation'; | ||
import { flatten, $, $inc } from 'mongo-dot-notation'; | ||
@@ -136,3 +136,3 @@ const student = { | ||
```ts | ||
import { flatten } from 'mongo-dot-notation'; | ||
import { flatten, $, $inc } from 'mongo-dot-notation'; | ||
@@ -154,3 +154,3 @@ const student = { | ||
```ts | ||
import { flatten } from 'mongo-dot-notation'; | ||
import { flatten, $, $inc } from 'mongo-dot-notation'; | ||
@@ -171,3 +171,3 @@ const student = { | ||
```ts | ||
import { flatten } from 'mongo-dot-notation'; | ||
import { flatten, $, $inc } from 'mongo-dot-notation'; | ||
@@ -188,3 +188,3 @@ const student = { | ||
```ts | ||
import { flatten, $mul } from 'mongo-dot-notation'; | ||
import { flatten, $, $mul } from 'mongo-dot-notation'; | ||
@@ -206,3 +206,3 @@ const student = { | ||
```ts | ||
import { flatten, $mul } from 'mongo-dot-notation'; | ||
import { flatten, $, $mul } from 'mongo-dot-notation'; | ||
@@ -217,6 +217,72 @@ const student = { | ||
flatten(student), // { $mul: { "grades.$[element].value" : 10 } } | ||
{ arrayFilters: [{ element: { $lte: 9 } }] } | ||
{ arrayFilters: [{ 'element.value': { $lte: 9 } }] } | ||
); | ||
``` | ||
### Merge array documents | ||
Using positional operator to merge fields into the matched element: | ||
```ts | ||
import { flatten, $, $inc, $currentDate } from 'mongo-dot-notation'; | ||
const student = { | ||
grades: $().merge({ | ||
class: '101', | ||
prof: 'Alice', | ||
value: $inc(), | ||
date: $currentDate(), | ||
}), | ||
}; | ||
flatten(student); | ||
``` | ||
Result: | ||
```json | ||
{ | ||
"$set": { | ||
"grades.$.class": "101", | ||
"grades.$.prof": "Alice" | ||
}, | ||
"$inc": { | ||
"grades.$.value": 1 | ||
}, | ||
"$currentDate": { | ||
"grades.$.date": { "$type": "date" } | ||
} | ||
} | ||
``` | ||
To update all elements, use `$('[]')` instead of `$()` in the above example. | ||
### Update nested arrays | ||
Using positional operator to update nested arrays: | ||
```ts | ||
import { flatten, $, $mul } from 'mongo-dot-notation'; | ||
const student = { | ||
grades: $().merge({ | ||
questions: $('[]').merge({ | ||
value: $mul(100), | ||
}), | ||
}), | ||
}; | ||
flatten(student); | ||
``` | ||
Calling `flatten(student)` results in: | ||
```json | ||
{ | ||
"$mul": { | ||
"grades.$.questions.$[].value": 100 | ||
} | ||
} | ||
``` | ||
See the [end-to-end](tests/mongo.e2e.ts) tests file for more examples. | ||
@@ -294,6 +360,6 @@ | ||
| Option | Description | | ||
| ------- | -------------------------------------------------------- | | ||
| obj | _(required)_ the input object to transform | | ||
| options | _(optional)_ additional options, see [Options](#options) | | ||
| Param | Description | | ||
| --------- | -------------------------------------------------------- | | ||
| `obj` | _(required)_ the input object to transform | | ||
| `options` | _(optional)_ additional options, see [Options](#options) | | ||
@@ -321,2 +387,6 @@ **Example:** | ||
| Param | Description | | ||
| ----- | -------------------------------------- | | ||
| `obj` | _(required)_ the input object to check | | ||
**Example:** | ||
@@ -377,5 +447,5 @@ | ||
| Param | Description | | ||
| ----- | ----------------------------- | | ||
| value | _(default 1)_ increment value | | ||
| Param | Description | | ||
| ------- | ----------------------------- | | ||
| `value` | _(default 1)_ increment value | | ||
@@ -399,5 +469,5 @@ **Example:** | ||
| Param | Description | | ||
| ----- | ---------------------- | | ||
| value | _(required)_ min value | | ||
| Param | Description | | ||
| ------- | ---------------------- | | ||
| `value` | _(required)_ min value | | ||
@@ -420,5 +490,5 @@ **Example:** | ||
| Param | Description | | ||
| ----- | ---------------------- | | ||
| value | _(required)_ max value | | ||
| Param | Description | | ||
| ------- | ---------------------- | | ||
| `value` | _(required)_ max value | | ||
@@ -441,5 +511,5 @@ **Example:** | ||
| Param | Description | | ||
| ----- | ----------------------------- | | ||
| value | _(default 1)_ multiply factor | | ||
| Param | Description | | ||
| ------- | ----------------------------- | | ||
| `value` | _(default 1)_ multiply factor | | ||
@@ -462,5 +532,5 @@ **Example:** | ||
| Param | Description | | ||
| ----- | --------------------------- | | ||
| field | _(required)_ new field name | | ||
| Param | Description | | ||
| ------- | --------------------------- | | ||
| `field` | _(required)_ new field name | | ||
@@ -486,5 +556,5 @@ **Example:** | ||
| Param | Description | | ||
| ----- | ------------------------------ | | ||
| value | _(required)_ replacement value | | ||
| Param | Description | | ||
| ------- | ------------------------------ | | ||
| `value` | _(required)_ replacement value | | ||
@@ -520,5 +590,5 @@ **Example:** | ||
| Param | Description | | ||
| ----- | -------------------------------------------------- | | ||
| value | _(required)_ the value to set on document creation | | ||
| Param | Description | | ||
| ------- | -------------------------------------------------- | | ||
| `value` | _(required)_ the value to set on document creation | | ||
@@ -564,5 +634,5 @@ **Example:** | ||
| Param | Description | | ||
| ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| field | _(optional)_ when empty - performs the update on array's element, when a number or a string starting with a number - specifies the index of the element to update or its field, when starts with "[]" or "[query]" specifies that this is an _all positional_ operator | | ||
| Param | Description | | ||
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | ||
| `field` | _(optional)_ when empty - performs the update on array's element; <br/>when a number or a string starting with a number, specifies the index of the element to update or its field;<br/>when starts with `"[]"` or `"[query]"`, specifies that this is an _all positional_ operator; | | ||
@@ -591,2 +661,4 @@ **Example:** | ||
See [update nested arrays](#update-nested-arrays) for examples using `$().merge`. | ||
[MongoDB manual](https://www.mongodb.com/docs/manual/reference/operator/update/positional/) | ||
@@ -601,5 +673,5 @@ | ||
| Param | Description | | ||
| ----- | ---------------------------------------- | | ||
| value | _(required)_ the value to add to the set | | ||
| Param | Description | | ||
| ------- | ---------------------------------------- | | ||
| `value` | _(required)_ the value to add to the set | | ||
@@ -627,5 +699,5 @@ Note that while `$addToSet([1, 2])` adds the entire array as single element, | ||
| Param | Description | | ||
| ----- | -------------------------------------------------------------------------------------- | | ||
| value | _(default 1)_ specify `-1` to remove the first element, `1` to remove the last element | | ||
| Param | Description | | ||
| ------- | -------------------------------------------------------------------------------------- | | ||
| `value` | _(default 1)_ specify `-1` to remove the first element, `1` to remove the last element | | ||
@@ -639,2 +711,7 @@ **Example:** | ||
flatten({ grades: $pop().first() }); | ||
// remove the last element from the array | ||
flatten({ scores: $pop(1) }); | ||
// equivalent to: | ||
flatten({ scores: $pop().last() }); | ||
``` | ||
@@ -651,5 +728,5 @@ | ||
| Param | Description | | ||
| ----- | ------------------------------------------------------------------------ | | ||
| value | _(required)_ the value(s) or condition to match to remove from the array | | ||
| Param | Description | | ||
| ------- | ---------------------------------------------------------------------------------- | | ||
| `value` | _(required)_ the value(s) to remove or the condition to match for removed elements | | ||
@@ -681,5 +758,5 @@ **Example:** | ||
| Param | Description | | ||
| ----- | ------------------------------------------------ | | ||
| value | _(optional)_ the value(s) to append to the array | | ||
| Param | Description | | ||
| ------- | ------------------------------------------------ | | ||
| `value` | _(optional)_ the value(s) to append to the array | | ||
@@ -713,5 +790,5 @@ **Example:** | ||
| Param | Description | | ||
| ----- | -------------------------------------------------- | | ||
| value | _(required)_ the value(s) to remove from the array | | ||
| Param | Description | | ||
| ------- | -------------------------------------------------- | | ||
| `value` | _(required)_ the value(s) to remove from the array | | ||
@@ -737,5 +814,5 @@ **Example:** | ||
| Param | Description | | ||
| ----- | --------------------------------------- | | ||
| count | _(required)_ number of elements to take | | ||
| Param | Description | | ||
| ------- | --------------------------------------- | | ||
| `count` | _(required)_ number of elements to take | | ||
@@ -764,5 +841,5 @@ **Example:** | ||
| Param | Description | | ||
| ------------- | -------------------------------- | | ||
| specification | _(default 1)_ sort specification | | ||
| Param | Description | | ||
| --------------- | -------------------------------- | | ||
| `specification` | _(default 1)_ sort specification | | ||
@@ -793,3 +870,3 @@ **Example:** | ||
Performs a bitwise update of a field. | ||
Should be chained with the a logical operator. | ||
Should be chained with a logical operator. | ||
@@ -796,0 +873,0 @@ **Example:** |
76877
1429
910