@valkey/valkey-glide-darwin-arm64 1.3.0-rc1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build-ts/src/server-modules/GlideJson.d.ts +5 -5
- package/build-ts/src/server-modules/GlideJson.js +7 -7
- package/build-ts/src/server-modules/GlideJson.js.map +1 -1
- package/node_modules/glide-rs/glide-rs.darwin-arm64.node +0 -0
- package/npm/glide/index.ts +2 -0
- package/package.json +1 -1
- package/rust-client/node_modules/mingo/README.md +81 -42
- package/rust-client/node_modules/mingo/dist/cjs/aggregator.js +10 -14
- package/rust-client/node_modules/mingo/dist/cjs/core.js +8 -13
- package/rust-client/node_modules/mingo/dist/cjs/cursor.js +24 -12
- package/rust-client/node_modules/mingo/dist/cjs/operators/_predicates.js +0 -1
- package/rust-client/node_modules/mingo/dist/cjs/operators/accumulator/bottomN.js +3 -2
- package/rust-client/node_modules/mingo/dist/cjs/operators/accumulator/topN.js +3 -4
- package/rust-client/node_modules/mingo/dist/cjs/operators/expression/array/sortArray.js +3 -2
- package/rust-client/node_modules/mingo/dist/cjs/operators/pipeline/fill.js +1 -1
- package/rust-client/node_modules/mingo/dist/cjs/operators/pipeline/lookup.js +3 -4
- package/rust-client/node_modules/mingo/dist/cjs/operators/pipeline/project.js +78 -85
- package/rust-client/node_modules/mingo/dist/cjs/operators/update/_internal.js +22 -0
- package/rust-client/node_modules/mingo/dist/cjs/operators/update/addToSet.js +1 -1
- package/rust-client/node_modules/mingo/dist/cjs/operators/update/bit.js +1 -1
- package/rust-client/node_modules/mingo/dist/cjs/operators/update/currentDate.js +1 -1
- package/rust-client/node_modules/mingo/dist/cjs/operators/update/inc.js +1 -1
- package/rust-client/node_modules/mingo/dist/cjs/operators/update/max.js +1 -1
- package/rust-client/node_modules/mingo/dist/cjs/operators/update/min.js +1 -1
- package/rust-client/node_modules/mingo/dist/cjs/operators/update/mul.js +1 -1
- package/rust-client/node_modules/mingo/dist/cjs/operators/update/pop.js +1 -1
- package/rust-client/node_modules/mingo/dist/cjs/operators/update/pull.js +1 -1
- package/rust-client/node_modules/mingo/dist/cjs/operators/update/pullAll.js +2 -1
- package/rust-client/node_modules/mingo/dist/cjs/operators/update/push.js +1 -1
- package/rust-client/node_modules/mingo/dist/cjs/operators/update/rename.js +1 -1
- package/rust-client/node_modules/mingo/dist/cjs/operators/update/set.js +1 -1
- package/rust-client/node_modules/mingo/dist/cjs/operators/update/unset.js +1 -1
- package/rust-client/node_modules/mingo/dist/cjs/query.js +10 -14
- package/rust-client/node_modules/mingo/dist/cjs/updater.js +5 -19
- package/rust-client/node_modules/mingo/dist/cjs/util.js +30 -18
- package/rust-client/node_modules/mingo/dist/esm/aggregator.js +11 -15
- package/rust-client/node_modules/mingo/dist/esm/core.js +8 -13
- package/rust-client/node_modules/mingo/dist/esm/cursor.js +27 -13
- package/rust-client/node_modules/mingo/dist/esm/operators/_predicates.js +0 -1
- package/rust-client/node_modules/mingo/dist/esm/operators/accumulator/bottomN.js +3 -2
- package/rust-client/node_modules/mingo/dist/esm/operators/accumulator/topN.js +3 -4
- package/rust-client/node_modules/mingo/dist/esm/operators/expression/array/sortArray.js +3 -2
- package/rust-client/node_modules/mingo/dist/esm/operators/pipeline/fill.js +1 -1
- package/rust-client/node_modules/mingo/dist/esm/operators/pipeline/lookup.js +3 -4
- package/rust-client/node_modules/mingo/dist/esm/operators/pipeline/project.js +80 -87
- package/rust-client/node_modules/mingo/dist/esm/operators/update/_internal.js +11 -0
- package/rust-client/node_modules/mingo/dist/esm/operators/update/addToSet.js +7 -2
- package/rust-client/node_modules/mingo/dist/esm/operators/update/bit.js +6 -2
- package/rust-client/node_modules/mingo/dist/esm/operators/update/currentDate.js +6 -2
- package/rust-client/node_modules/mingo/dist/esm/operators/update/inc.js +2 -2
- package/rust-client/node_modules/mingo/dist/esm/operators/update/max.js +6 -2
- package/rust-client/node_modules/mingo/dist/esm/operators/update/min.js +6 -2
- package/rust-client/node_modules/mingo/dist/esm/operators/update/mul.js +6 -2
- package/rust-client/node_modules/mingo/dist/esm/operators/update/pop.js +6 -2
- package/rust-client/node_modules/mingo/dist/esm/operators/update/pull.js +6 -2
- package/rust-client/node_modules/mingo/dist/esm/operators/update/pullAll.js +2 -1
- package/rust-client/node_modules/mingo/dist/esm/operators/update/push.js +7 -2
- package/rust-client/node_modules/mingo/dist/esm/operators/update/rename.js +6 -2
- package/rust-client/node_modules/mingo/dist/esm/operators/update/set.js +7 -2
- package/rust-client/node_modules/mingo/dist/esm/operators/update/unset.js +2 -2
- package/rust-client/node_modules/mingo/dist/esm/query.js +11 -15
- package/rust-client/node_modules/mingo/dist/esm/updater.js +5 -19
- package/rust-client/node_modules/mingo/dist/esm/util.js +30 -18
- package/rust-client/node_modules/mingo/dist/types/aggregator.d.ts +1 -1
- package/rust-client/node_modules/mingo/dist/types/core.d.ts +10 -35
- package/rust-client/node_modules/mingo/dist/types/operators/pipeline/project.d.ts +2 -1
- package/rust-client/node_modules/mingo/dist/types/operators/update/_internal.d.ts +1 -0
- package/rust-client/node_modules/mingo/dist/types/query.d.ts +1 -1
- package/rust-client/node_modules/mingo/dist/types/util.d.ts +3 -3
- package/rust-client/node_modules/mingo/package.json +1 -1
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
ProcessingMode
|
|
5
5
|
} from "./core";
|
|
6
6
|
import { Lazy } from "./lazy";
|
|
7
|
-
import { assert, cloneDeep,
|
|
7
|
+
import { assert, cloneDeep, isEmpty } from "./util";
|
|
8
8
|
class Aggregator {
|
|
9
9
|
#pipeline;
|
|
10
10
|
#options;
|
|
@@ -15,34 +15,30 @@ class Aggregator {
|
|
|
15
15
|
/**
|
|
16
16
|
* Returns an {@link Iterator} for lazy evaluation of the pipeline.
|
|
17
17
|
*
|
|
18
|
-
* @param
|
|
18
|
+
* @param collection An array or iterator object
|
|
19
19
|
* @returns {Iterator} an iterator object
|
|
20
20
|
*/
|
|
21
21
|
stream(collection, options) {
|
|
22
|
-
let
|
|
22
|
+
let iter = Lazy(collection);
|
|
23
23
|
const opts = options ?? this.#options;
|
|
24
24
|
const mode = opts.processingMode;
|
|
25
|
-
if (mode
|
|
26
|
-
iterator.map(cloneDeep);
|
|
27
|
-
}
|
|
25
|
+
if (mode & ProcessingMode.CLONE_INPUT) iter.map(cloneDeep);
|
|
28
26
|
const stages = new Array();
|
|
29
27
|
if (!isEmpty(this.#pipeline)) {
|
|
30
|
-
for (const
|
|
31
|
-
const
|
|
32
|
-
const opName =
|
|
28
|
+
for (const opExpr of this.#pipeline) {
|
|
29
|
+
const opKeys = Object.keys(opExpr);
|
|
30
|
+
const opName = opKeys[0];
|
|
33
31
|
const call = getOperator("pipeline", opName, opts);
|
|
34
32
|
assert(
|
|
35
|
-
|
|
33
|
+
opKeys.length === 1 && !!call,
|
|
36
34
|
`invalid pipeline operator ${opName}`
|
|
37
35
|
);
|
|
38
36
|
stages.push(opName);
|
|
39
|
-
|
|
37
|
+
iter = call(iter, opExpr[opName], opts);
|
|
40
38
|
}
|
|
41
39
|
}
|
|
42
|
-
if (mode
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
return iterator;
|
|
40
|
+
if (mode & ProcessingMode.CLONE_OUTPUT) iter.map(cloneDeep);
|
|
41
|
+
return iter;
|
|
46
42
|
}
|
|
47
43
|
/**
|
|
48
44
|
* Return the results of the aggregation as an array.
|
|
@@ -10,10 +10,10 @@ import {
|
|
|
10
10
|
resolve
|
|
11
11
|
} from "./util";
|
|
12
12
|
var ProcessingMode = /* @__PURE__ */ ((ProcessingMode2) => {
|
|
13
|
-
ProcessingMode2["
|
|
14
|
-
ProcessingMode2["CLONE_INPUT"] = "CLONE_INPUT";
|
|
15
|
-
ProcessingMode2["CLONE_OUTPUT"] = "CLONE_OUTPUT";
|
|
16
|
-
ProcessingMode2["
|
|
13
|
+
ProcessingMode2[ProcessingMode2["CLONE_OFF"] = 0] = "CLONE_OFF";
|
|
14
|
+
ProcessingMode2[ProcessingMode2["CLONE_INPUT"] = 1] = "CLONE_INPUT";
|
|
15
|
+
ProcessingMode2[ProcessingMode2["CLONE_OUTPUT"] = 2] = "CLONE_OUTPUT";
|
|
16
|
+
ProcessingMode2[ProcessingMode2["CLONE_ALL"] = 3] = "CLONE_ALL";
|
|
17
17
|
return ProcessingMode2;
|
|
18
18
|
})(ProcessingMode || {});
|
|
19
19
|
class ComputeOptions {
|
|
@@ -27,23 +27,18 @@ class ComputeOptions {
|
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
29
|
* Initialize new ComputeOptions.
|
|
30
|
-
*
|
|
31
|
-
* @param options
|
|
32
|
-
* @param root
|
|
33
|
-
* @param local
|
|
34
30
|
* @returns {ComputeOptions}
|
|
35
31
|
*/
|
|
36
32
|
static init(options, root, local) {
|
|
37
|
-
return options instanceof ComputeOptions ? new ComputeOptions(options.#options, options.root ?? root, {
|
|
33
|
+
return !(options instanceof ComputeOptions) ? new ComputeOptions(options, root, local) : new ComputeOptions(options.#options, options.root ?? root, {
|
|
38
34
|
...options.#local,
|
|
39
35
|
...local,
|
|
40
|
-
// retain existing variables
|
|
41
36
|
variables: Object.assign(
|
|
42
37
|
{},
|
|
43
38
|
options.#local?.variables,
|
|
44
39
|
local?.variables
|
|
45
40
|
)
|
|
46
|
-
})
|
|
41
|
+
});
|
|
47
42
|
}
|
|
48
43
|
/**
|
|
49
44
|
* Updates the internal state.
|
|
@@ -85,7 +80,7 @@ class ComputeOptions {
|
|
|
85
80
|
return this.#options?.collation;
|
|
86
81
|
}
|
|
87
82
|
get processingMode() {
|
|
88
|
-
return this.#options?.processingMode ||
|
|
83
|
+
return this.#options?.processingMode || 0 /* CLONE_OFF */;
|
|
89
84
|
}
|
|
90
85
|
get useStrictMode() {
|
|
91
86
|
return this.#options?.useStrictMode;
|
|
@@ -118,7 +113,7 @@ function initOptions(options) {
|
|
|
118
113
|
scriptEnabled: true,
|
|
119
114
|
useStrictMode: true,
|
|
120
115
|
useGlobalContext: true,
|
|
121
|
-
processingMode:
|
|
116
|
+
processingMode: 0 /* CLONE_OFF */,
|
|
122
117
|
...options,
|
|
123
118
|
context: options?.context ? Context.from(options?.context) : Context.init()
|
|
124
119
|
});
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
ProcessingMode
|
|
3
|
+
} from "./core";
|
|
2
4
|
import { concat, Lazy } from "./lazy";
|
|
3
|
-
import {
|
|
5
|
+
import { $limit } from "./operators/pipeline/limit";
|
|
6
|
+
import { $project } from "./operators/pipeline/project";
|
|
7
|
+
import { $skip } from "./operators/pipeline/skip";
|
|
8
|
+
import { $sort } from "./operators/pipeline/sort";
|
|
9
|
+
import { cloneDeep, has } from "./util";
|
|
10
|
+
const OPERATORS = { $sort, $skip, $limit };
|
|
4
11
|
class Cursor {
|
|
5
12
|
#source;
|
|
6
13
|
#predicate;
|
|
7
14
|
#projection;
|
|
8
15
|
#options;
|
|
9
|
-
#operators =
|
|
16
|
+
#operators = {};
|
|
10
17
|
#result = null;
|
|
11
18
|
#buffer = [];
|
|
12
19
|
constructor(source, predicate, projection, options) {
|
|
@@ -18,15 +25,22 @@ class Cursor {
|
|
|
18
25
|
/** Returns the iterator from running the query */
|
|
19
26
|
fetch() {
|
|
20
27
|
if (this.#result) return this.#result;
|
|
21
|
-
if (isObject(this.#projection)) {
|
|
22
|
-
this.#operators.push({ $project: this.#projection });
|
|
23
|
-
}
|
|
24
28
|
this.#result = Lazy(this.#source).filter(this.#predicate);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
)
|
|
29
|
+
const mode = this.#options.processingMode;
|
|
30
|
+
if (mode & ProcessingMode.CLONE_INPUT) this.#result.map(cloneDeep);
|
|
31
|
+
for (const op of ["$sort", "$skip", "$limit"]) {
|
|
32
|
+
if (has(this.#operators, op)) {
|
|
33
|
+
this.#result = OPERATORS[op](
|
|
34
|
+
this.#result,
|
|
35
|
+
this.#operators[op],
|
|
36
|
+
this.#options
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (Object.keys(this.#projection).length) {
|
|
41
|
+
this.#result = $project(this.#result, this.#projection, this.#options);
|
|
29
42
|
}
|
|
43
|
+
if (mode & ProcessingMode.CLONE_OUTPUT) this.#result.map(cloneDeep);
|
|
30
44
|
return this.#result;
|
|
31
45
|
}
|
|
32
46
|
/** Returns an iterator with the buffered data included */
|
|
@@ -55,7 +69,7 @@ class Cursor {
|
|
|
55
69
|
* @return {Cursor} Returns the cursor, so you can chain this call.
|
|
56
70
|
*/
|
|
57
71
|
skip(n) {
|
|
58
|
-
this.#operators
|
|
72
|
+
this.#operators["$skip"] = n;
|
|
59
73
|
return this;
|
|
60
74
|
}
|
|
61
75
|
/**
|
|
@@ -64,7 +78,7 @@ class Cursor {
|
|
|
64
78
|
* @return {Cursor} Returns the cursor, so you can chain this call.
|
|
65
79
|
*/
|
|
66
80
|
limit(n) {
|
|
67
|
-
this.#operators
|
|
81
|
+
this.#operators["$limit"] = n;
|
|
68
82
|
return this;
|
|
69
83
|
}
|
|
70
84
|
/**
|
|
@@ -73,7 +87,7 @@ class Cursor {
|
|
|
73
87
|
* @return {Cursor} Returns the cursor, so you can chain this call.
|
|
74
88
|
*/
|
|
75
89
|
sort(modifier) {
|
|
76
|
-
this.#operators
|
|
90
|
+
this.#operators["$sort"] = modifier;
|
|
77
91
|
return this;
|
|
78
92
|
}
|
|
79
93
|
/**
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { Aggregator } from "../../aggregator";
|
|
2
1
|
import {
|
|
3
2
|
ComputeOptions,
|
|
4
3
|
computeValue
|
|
5
4
|
} from "../../core";
|
|
5
|
+
import { Lazy } from "../../lazy";
|
|
6
|
+
import { $sort } from "../pipeline/sort";
|
|
6
7
|
import { $push } from "./push";
|
|
7
8
|
const $bottomN = (collection, expr, options) => {
|
|
8
9
|
const copts = ComputeOptions.init(options);
|
|
@@ -12,7 +13,7 @@ const $bottomN = (collection, expr, options) => {
|
|
|
12
13
|
null,
|
|
13
14
|
copts
|
|
14
15
|
);
|
|
15
|
-
const result =
|
|
16
|
+
const result = $sort(Lazy(collection), sortBy, options).value();
|
|
16
17
|
const m = result.length;
|
|
17
18
|
const p = n;
|
|
18
19
|
return $push(m <= p ? result : result.slice(m - p), expr.output, copts);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { Aggregator } from "../../aggregator";
|
|
2
1
|
import {
|
|
3
2
|
ComputeOptions,
|
|
4
3
|
computeValue
|
|
5
4
|
} from "../../core";
|
|
5
|
+
import { Lazy } from "../../lazy";
|
|
6
|
+
import { $sort } from "../pipeline/sort";
|
|
6
7
|
import { $push } from "./push";
|
|
7
8
|
const $topN = (collection, expr, options) => {
|
|
8
9
|
const copts = ComputeOptions.init(options);
|
|
@@ -12,9 +13,7 @@ const $topN = (collection, expr, options) => {
|
|
|
12
13
|
null,
|
|
13
14
|
copts
|
|
14
15
|
);
|
|
15
|
-
const result =
|
|
16
|
-
collection
|
|
17
|
-
);
|
|
16
|
+
const result = $sort(Lazy(collection), sortBy, options).take(n).value();
|
|
18
17
|
return $push(result, expr.output, copts);
|
|
19
18
|
};
|
|
20
19
|
export {
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { Aggregator } from "../../../aggregator";
|
|
2
1
|
import { computeValue } from "../../../core";
|
|
2
|
+
import { Lazy } from "../../../lazy";
|
|
3
3
|
import { assert, compare, isArray, isNil, isObject } from "../../../util";
|
|
4
|
+
import { $sort } from "../../pipeline/sort";
|
|
4
5
|
const $sortArray = (obj, expr, options) => {
|
|
5
6
|
const { input, sortBy } = computeValue(obj, expr, null, options);
|
|
6
7
|
if (isNil(input)) return null;
|
|
7
8
|
assert(isArray(input), "$sortArray expression must resolve to an array");
|
|
8
9
|
if (isObject(sortBy)) {
|
|
9
|
-
return
|
|
10
|
+
return $sort(Lazy(input), sortBy, options).value();
|
|
10
11
|
}
|
|
11
12
|
const result = [...input];
|
|
12
13
|
result.sort(compare);
|
|
@@ -26,7 +26,7 @@ const $fill = (collection, expr, options) => {
|
|
|
26
26
|
options = initOptions(options);
|
|
27
27
|
options.context.addExpressionOps({ $ifNull });
|
|
28
28
|
options.context.addWindowOps({ $locf, $linearFill });
|
|
29
|
-
const partitionExpr = expr.partitionBy || expr?.partitionByFields?.map((s) =>
|
|
29
|
+
const partitionExpr = expr.partitionBy || expr?.partitionByFields?.map((s) => "$" + s);
|
|
30
30
|
const valueExpr = {};
|
|
31
31
|
const methodExpr = {};
|
|
32
32
|
for (const [k, m] of Object.entries(expr.output)) {
|
|
@@ -47,11 +47,10 @@ const $lookup = (collection, expr, options) => {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
const agg = new Aggregator(subQueryPipeline, options);
|
|
50
|
+
const opts = { ...options };
|
|
50
51
|
return collection.map((obj) => {
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
variables: { ...options.variables, ...variables }
|
|
54
|
-
});
|
|
52
|
+
const vars = computeValue(obj, letExpr, null, options);
|
|
53
|
+
opts.variables = { ...options.variables, ...vars };
|
|
55
54
|
const [ok, res] = lookupEq(obj);
|
|
56
55
|
return {
|
|
57
56
|
...obj,
|
|
@@ -8,138 +8,131 @@ import {
|
|
|
8
8
|
ensureArray,
|
|
9
9
|
filterMissing,
|
|
10
10
|
has,
|
|
11
|
-
into,
|
|
12
11
|
isArray,
|
|
12
|
+
isBoolean,
|
|
13
13
|
isEmpty,
|
|
14
|
-
isNil,
|
|
15
14
|
isNumber,
|
|
16
15
|
isObject,
|
|
17
16
|
isOperator,
|
|
18
17
|
isString,
|
|
19
18
|
merge,
|
|
20
19
|
removeValue,
|
|
20
|
+
resolve,
|
|
21
21
|
resolveGraph,
|
|
22
22
|
setValue
|
|
23
23
|
} from "../../util";
|
|
24
|
-
const DESCRIPTORS = new Set(Array.from([0, 1, false, true]));
|
|
25
24
|
const $project = (collection, expr, options) => {
|
|
26
25
|
if (isEmpty(expr)) return collection;
|
|
27
|
-
const expressionKeys = Object.keys(expr);
|
|
28
26
|
validateExpression(expr, options);
|
|
29
|
-
|
|
30
|
-
if (!expressionKeys.includes(ID_KEY)) {
|
|
31
|
-
expressionKeys.push(ID_KEY);
|
|
32
|
-
}
|
|
33
|
-
const copts = ComputeOptions.init(options);
|
|
34
|
-
return collection.map((obj) => processObject(obj, expr, copts.update(obj), expressionKeys));
|
|
27
|
+
return collection.map(createHandler(expr, ComputeOptions.init(options)));
|
|
35
28
|
};
|
|
36
|
-
function
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
if (idOnlyExcluded) {
|
|
43
|
-
dropKeys.push(options.idKey);
|
|
44
|
-
}
|
|
29
|
+
function createHandler(expr, options, isRoot = true) {
|
|
30
|
+
const idKey = options.idKey;
|
|
31
|
+
const expressionKeys = Object.keys(expr);
|
|
32
|
+
const excludedKeys = new Array();
|
|
33
|
+
const includedKeys = new Array();
|
|
34
|
+
const handlers = {};
|
|
45
35
|
for (const key of expressionKeys) {
|
|
46
|
-
let value = void 0;
|
|
47
36
|
const subExpr = expr[key];
|
|
48
|
-
if (
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
value = computeValue(obj, subExpr, key, options);
|
|
55
|
-
} else if (subExpr === 1 || subExpr === true) {
|
|
37
|
+
if (isNumber(subExpr) || isBoolean(subExpr)) {
|
|
38
|
+
if (subExpr) {
|
|
39
|
+
includedKeys.push(key);
|
|
40
|
+
} else {
|
|
41
|
+
excludedKeys.push(key);
|
|
42
|
+
}
|
|
56
43
|
} else if (isArray(subExpr)) {
|
|
57
|
-
|
|
58
|
-
const r = computeValue(obj, v, null, options);
|
|
59
|
-
if (isNil(r)) return null;
|
|
60
|
-
return r;
|
|
61
|
-
});
|
|
44
|
+
handlers[key] = (o) => subExpr.map((v) => computeValue(o, v, null, options.update(o)) ?? null);
|
|
62
45
|
} else if (isObject(subExpr)) {
|
|
63
|
-
const subExprObj = subExpr;
|
|
64
46
|
const subExprKeys = Object.keys(subExpr);
|
|
65
47
|
const operator = subExprKeys.length == 1 ? subExprKeys[0] : "";
|
|
66
|
-
const
|
|
48
|
+
const projectFn = getOperator(
|
|
67
49
|
"projection",
|
|
68
50
|
operator,
|
|
69
51
|
options
|
|
70
52
|
);
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
foundSlice = true;
|
|
76
|
-
} else {
|
|
77
|
-
value = computeValue(obj, subExprObj, key, options);
|
|
78
|
-
}
|
|
53
|
+
if (projectFn) {
|
|
54
|
+
const foundSlice = operator === "$slice";
|
|
55
|
+
if (foundSlice && !ensureArray(subExpr[operator]).every(isNumber)) {
|
|
56
|
+
handlers[key] = (o) => computeValue(o, subExpr, key, options.update(o));
|
|
79
57
|
} else {
|
|
80
|
-
|
|
58
|
+
handlers[key] = (o) => projectFn(o, subExpr[operator], key, options.update(o));
|
|
81
59
|
}
|
|
82
60
|
} else if (isOperator(operator)) {
|
|
83
|
-
|
|
84
|
-
} else if (has(obj, key)) {
|
|
85
|
-
validateExpression(subExprObj, options);
|
|
86
|
-
let target = obj[key];
|
|
87
|
-
if (isArray(target)) {
|
|
88
|
-
value = target.map(
|
|
89
|
-
(o) => processObject(o, subExprObj, options, subExprKeys)
|
|
90
|
-
);
|
|
91
|
-
} else {
|
|
92
|
-
target = isObject(target) ? target : obj;
|
|
93
|
-
value = processObject(
|
|
94
|
-
target,
|
|
95
|
-
subExprObj,
|
|
96
|
-
options,
|
|
97
|
-
subExprKeys
|
|
98
|
-
);
|
|
99
|
-
}
|
|
61
|
+
handlers[key] = (o) => computeValue(o, subExpr[operator], operator, options);
|
|
100
62
|
} else {
|
|
101
|
-
|
|
63
|
+
validateExpression(subExpr, options);
|
|
64
|
+
handlers[key] = (o) => {
|
|
65
|
+
if (!has(o, key)) return computeValue(o, subExpr, null, options);
|
|
66
|
+
if (isRoot) options.update(o);
|
|
67
|
+
const target = resolve(o, key);
|
|
68
|
+
const fn = createHandler(subExpr, options, false);
|
|
69
|
+
if (isArray(target)) return target.map(fn);
|
|
70
|
+
if (isObject(target)) return fn(target);
|
|
71
|
+
return fn(o);
|
|
72
|
+
};
|
|
102
73
|
}
|
|
103
74
|
} else {
|
|
104
|
-
|
|
105
|
-
continue;
|
|
75
|
+
handlers[key] = isString(subExpr) && subExpr[0] === "$" ? (o) => computeValue(o, subExpr, key, options) : (_) => subExpr;
|
|
106
76
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
77
|
+
}
|
|
78
|
+
const handlerKeys = Object.keys(handlers);
|
|
79
|
+
const idKeyExcluded = excludedKeys.includes(idKey);
|
|
80
|
+
const idKeyOnlyExcluded = isRoot && idKeyExcluded && excludedKeys.length === 1 && !includedKeys.length && !handlerKeys.length;
|
|
81
|
+
if (idKeyOnlyExcluded) {
|
|
82
|
+
return (o) => {
|
|
83
|
+
const newObj = { ...o };
|
|
84
|
+
delete newObj[idKey];
|
|
85
|
+
return newObj;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
const idKeyImplicit = isRoot && !idKeyExcluded && !includedKeys.includes(idKey);
|
|
89
|
+
const opts = {
|
|
90
|
+
preserveMissing: true
|
|
91
|
+
};
|
|
92
|
+
return (o) => {
|
|
93
|
+
const newObj = {};
|
|
94
|
+
if (excludedKeys.length && !includedKeys.length) {
|
|
95
|
+
merge(newObj, o);
|
|
96
|
+
for (const k of excludedKeys) {
|
|
97
|
+
removeValue(newObj, k, { descendArray: true });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
for (const k of includedKeys) {
|
|
101
|
+
const pathObj = resolveGraph(o, k, opts) ?? {};
|
|
102
|
+
merge(newObj, pathObj);
|
|
112
103
|
}
|
|
113
|
-
if (
|
|
104
|
+
if (includedKeys.length) filterMissing(newObj);
|
|
105
|
+
for (const k of handlerKeys) {
|
|
106
|
+
const value = handlers[k](o);
|
|
114
107
|
if (value === void 0) {
|
|
115
|
-
removeValue(newObj,
|
|
108
|
+
removeValue(newObj, k, { descendArray: true });
|
|
116
109
|
} else {
|
|
117
|
-
setValue(newObj,
|
|
110
|
+
setValue(newObj, k, value);
|
|
118
111
|
}
|
|
119
112
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
if (foundSlice || foundExclusion || idOnlyExcluded) {
|
|
123
|
-
newObj = into({}, obj, newObj);
|
|
124
|
-
if (dropKeys.length > 0) {
|
|
125
|
-
for (const k of dropKeys) {
|
|
126
|
-
removeValue(newObj, k, { descendArray: true });
|
|
127
|
-
}
|
|
113
|
+
if (idKeyImplicit && has(o, idKey)) {
|
|
114
|
+
newObj[idKey] = resolve(o, idKey);
|
|
128
115
|
}
|
|
129
|
-
|
|
130
|
-
|
|
116
|
+
return newObj;
|
|
117
|
+
};
|
|
131
118
|
}
|
|
132
119
|
function validateExpression(expr, options) {
|
|
133
|
-
|
|
120
|
+
let exclusions = false;
|
|
121
|
+
let inclusions = false;
|
|
134
122
|
for (const [k, v] of Object.entries(expr)) {
|
|
135
|
-
|
|
123
|
+
assert(!k.startsWith("$"), "Field names may not start with '$'.");
|
|
124
|
+
assert(
|
|
125
|
+
!k.endsWith(".$"),
|
|
126
|
+
"Positional projection operator '$' is not supported."
|
|
127
|
+
);
|
|
128
|
+
if (k === options?.idKey) continue;
|
|
136
129
|
if (v === 0 || v === false) {
|
|
137
|
-
|
|
130
|
+
exclusions = true;
|
|
138
131
|
} else if (v === 1 || v === true) {
|
|
139
|
-
|
|
132
|
+
inclusions = true;
|
|
140
133
|
}
|
|
141
134
|
assert(
|
|
142
|
-
!(
|
|
135
|
+
!(exclusions && inclusions),
|
|
143
136
|
"Projection cannot have a mix of inclusion and exclusion."
|
|
144
137
|
);
|
|
145
138
|
}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { Context, initOptions } from "../../core";
|
|
2
|
+
import * as booleanOperators from "../../operators/expression/boolean";
|
|
3
|
+
import * as comparisonOperators from "../../operators/expression/comparison";
|
|
4
|
+
import * as queryOperators from "../../operators/query";
|
|
1
5
|
import { Query } from "../../query";
|
|
2
6
|
import {
|
|
3
7
|
assert,
|
|
@@ -9,6 +13,12 @@ import {
|
|
|
9
13
|
resolve,
|
|
10
14
|
walk
|
|
11
15
|
} from "../../util";
|
|
16
|
+
const UPDATE_OPTIONS = {
|
|
17
|
+
cloneMode: "copy",
|
|
18
|
+
queryOptions: initOptions({
|
|
19
|
+
context: Context.init().addQueryOps(queryOperators).addExpressionOps(booleanOperators).addExpressionOps(comparisonOperators)
|
|
20
|
+
})
|
|
21
|
+
};
|
|
12
22
|
const clone = (mode, val) => {
|
|
13
23
|
switch (mode) {
|
|
14
24
|
case "deep":
|
|
@@ -87,6 +97,7 @@ function walkExpression(expr, arrayFilter, options, callback) {
|
|
|
87
97
|
return res;
|
|
88
98
|
}
|
|
89
99
|
export {
|
|
100
|
+
UPDATE_OPTIONS,
|
|
90
101
|
applyUpdate,
|
|
91
102
|
clone,
|
|
92
103
|
tokenizePath,
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { has, intersection, isObject, unique } from "../../util";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
applyUpdate,
|
|
4
|
+
clone,
|
|
5
|
+
UPDATE_OPTIONS,
|
|
6
|
+
walkExpression
|
|
7
|
+
} from "./_internal";
|
|
8
|
+
const $addToSet = (obj, expr, arrayFilters = [], options = UPDATE_OPTIONS) => {
|
|
4
9
|
return walkExpression(expr, arrayFilters, options, (val, node, queries) => {
|
|
5
10
|
const args = { $each: [val] };
|
|
6
11
|
if (isObject(val) && has(val, "$each")) {
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { assert, isNumber } from "../../util";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
applyUpdate,
|
|
4
|
+
UPDATE_OPTIONS,
|
|
5
|
+
walkExpression
|
|
6
|
+
} from "./_internal";
|
|
3
7
|
const BIT_OPS = /* @__PURE__ */ new Set(["and", "or", "xor"]);
|
|
4
|
-
const $bit = (obj, expr, arrayFilters = [], options =
|
|
8
|
+
const $bit = (obj, expr, arrayFilters = [], options = UPDATE_OPTIONS) => {
|
|
5
9
|
return walkExpression(expr, arrayFilters, options, (val, node, queries) => {
|
|
6
10
|
const op = Object.keys(val);
|
|
7
11
|
assert(
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
applyUpdate,
|
|
3
|
+
UPDATE_OPTIONS,
|
|
4
|
+
walkExpression
|
|
5
|
+
} from "./_internal";
|
|
6
|
+
const $currentDate = (obj, expr, arrayFilters = [], options = UPDATE_OPTIONS) => {
|
|
3
7
|
const now = Date.now();
|
|
4
8
|
return walkExpression(expr, arrayFilters, options, (_, node, queries) => {
|
|
5
9
|
return applyUpdate(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { assert, isNumber, resolve } from "../../util";
|
|
2
|
-
import { applyUpdate, walkExpression } from "./_internal";
|
|
3
|
-
const $inc = (obj, expr, arrayFilters = [], options =
|
|
2
|
+
import { applyUpdate, UPDATE_OPTIONS, walkExpression } from "./_internal";
|
|
3
|
+
const $inc = (obj, expr, arrayFilters = [], options = UPDATE_OPTIONS) => {
|
|
4
4
|
return walkExpression(expr, arrayFilters, options, (val, node, queries) => {
|
|
5
5
|
if (!node.child) {
|
|
6
6
|
const n = resolve(obj, node.parent);
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { compare } from "../../util";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
applyUpdate,
|
|
4
|
+
UPDATE_OPTIONS,
|
|
5
|
+
walkExpression
|
|
6
|
+
} from "./_internal";
|
|
7
|
+
const $max = (obj, expr, arrayFilters = [], options = UPDATE_OPTIONS) => {
|
|
4
8
|
return walkExpression(expr, arrayFilters, options, (val, node, queries) => {
|
|
5
9
|
return applyUpdate(
|
|
6
10
|
obj,
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { compare } from "../../util";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
applyUpdate,
|
|
4
|
+
UPDATE_OPTIONS,
|
|
5
|
+
walkExpression
|
|
6
|
+
} from "./_internal";
|
|
7
|
+
const $min = (obj, expr, arrayFilters = [], options = UPDATE_OPTIONS) => {
|
|
4
8
|
return walkExpression(expr, arrayFilters, options, (val, node, queries) => {
|
|
5
9
|
return applyUpdate(
|
|
6
10
|
obj,
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
applyUpdate,
|
|
3
|
+
UPDATE_OPTIONS,
|
|
4
|
+
walkExpression
|
|
5
|
+
} from "./_internal";
|
|
6
|
+
const $mul = (obj, expr, arrayFilters = [], options = UPDATE_OPTIONS) => {
|
|
3
7
|
return walkExpression(expr, arrayFilters, options, (val, node, queries) => {
|
|
4
8
|
return applyUpdate(
|
|
5
9
|
obj,
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { assert, isArray } from "../../util";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
applyUpdate,
|
|
4
|
+
UPDATE_OPTIONS,
|
|
5
|
+
walkExpression
|
|
6
|
+
} from "./_internal";
|
|
7
|
+
const $pop = (obj, expr, arrayFilters = [], options = UPDATE_OPTIONS) => {
|
|
4
8
|
return walkExpression(expr, arrayFilters, options, (val, node, queries) => {
|
|
5
9
|
return applyUpdate(obj, node, queries, (o, k) => {
|
|
6
10
|
const arr = o[k];
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { Query } from "../../query";
|
|
2
2
|
import { isObject, isOperator } from "../../util";
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import {
|
|
4
|
+
applyUpdate,
|
|
5
|
+
UPDATE_OPTIONS,
|
|
6
|
+
walkExpression
|
|
7
|
+
} from "./_internal";
|
|
8
|
+
const $pull = (obj, expr, arrayFilters = [], options = UPDATE_OPTIONS) => {
|
|
5
9
|
return walkExpression(expr, arrayFilters, options, (val, node, queries) => {
|
|
6
10
|
const wrap = !isObject(val) || Object.keys(val).some(isOperator);
|
|
7
11
|
const query = new Query(
|