@es-joy/jsoe 0.28.1 → 0.29.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/CHANGES.md +23 -0
- package/README.md +2 -0
- package/badges/coverage-badge.svg +1 -1
- package/badges/tests-badge.svg +1 -1
- package/dist/deepEqual.d.ts +3 -0
- package/dist/deepEqual.d.ts.map +1 -0
- package/dist/formatAndTypeChoices.d.ts +6 -6
- package/dist/formatAndTypeChoices.d.ts.map +1 -1
- package/dist/formats/schema.d.ts +5 -0
- package/dist/formats/schema.d.ts.map +1 -1
- package/dist/formats.d.ts +2 -2
- package/dist/formats.d.ts.map +1 -1
- package/dist/fundamentalTypes/dateType.d.ts +21 -2
- package/dist/fundamentalTypes/dateType.d.ts.map +1 -1
- package/dist/fundamentalTypes/domexceptionType.d.ts +7 -0
- package/dist/fundamentalTypes/domexceptionType.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/jtltExtensions.d.ts +112 -0
- package/dist/jtltExtensions.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/arraySearchType.d.ts +15 -0
- package/dist/search/fundamentalTypes/arraySearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/bigintSearchType.d.ts +10 -0
- package/dist/search/fundamentalTypes/bigintSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/blobSearchType.d.ts +19 -0
- package/dist/search/fundamentalTypes/blobSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/booleanSearchType.d.ts +11 -0
- package/dist/search/fundamentalTypes/booleanSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/catchSearchType.d.ts +18 -0
- package/dist/search/fundamentalTypes/catchSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/dateSearchType.d.ts +10 -0
- package/dist/search/fundamentalTypes/dateSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/domexceptionSearchType.d.ts +16 -0
- package/dist/search/fundamentalTypes/domexceptionSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/enumSearchType.d.ts +22 -0
- package/dist/search/fundamentalTypes/enumSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/errorSearchType.d.ts +9 -0
- package/dist/search/fundamentalTypes/errorSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/fileSearchType.d.ts +19 -0
- package/dist/search/fundamentalTypes/fileSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/filelistSearchType.d.ts +32 -0
- package/dist/search/fundamentalTypes/filelistSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/functionSearchType.d.ts +18 -0
- package/dist/search/fundamentalTypes/functionSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/mapSearchType.d.ts +18 -0
- package/dist/search/fundamentalTypes/mapSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/nanSearchType.d.ts +7 -0
- package/dist/search/fundamentalTypes/nanSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/nullSearchType.d.ts +7 -0
- package/dist/search/fundamentalTypes/nullSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/numberSearchType.d.ts +11 -0
- package/dist/search/fundamentalTypes/numberSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/objectSearchType.d.ts +15 -0
- package/dist/search/fundamentalTypes/objectSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/promiseSearchType.d.ts +20 -0
- package/dist/search/fundamentalTypes/promiseSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/regexpSearchType.d.ts +14 -0
- package/dist/search/fundamentalTypes/regexpSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/setSearchType.d.ts +14 -0
- package/dist/search/fundamentalTypes/setSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/stringSearchType.d.ts +13 -0
- package/dist/search/fundamentalTypes/stringSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/symbolSearchType.d.ts +16 -0
- package/dist/search/fundamentalTypes/symbolSearchType.d.ts.map +1 -0
- package/dist/search/fundamentalTypes/undefinedSearchType.d.ts +7 -0
- package/dist/search/fundamentalTypes/undefinedSearchType.d.ts.map +1 -0
- package/dist/search/index.d.ts +60 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/queryTree.d.ts +180 -0
- package/dist/search/queryTree.d.ts.map +1 -0
- package/dist/search/queryTreeBuilders.d.ts +168 -0
- package/dist/search/queryTreeBuilders.d.ts.map +1 -0
- package/dist/search/searchDispatch.d.ts +121 -0
- package/dist/search/searchDispatch.d.ts.map +1 -0
- package/dist/search/searchElementUtils.d.ts +97 -0
- package/dist/search/searchElementUtils.d.ts.map +1 -0
- package/dist/search/searchUtils.d.ts +225 -0
- package/dist/search/searchUtils.d.ts.map +1 -0
- package/dist/search/subTypes/blobHTMLSearchType.d.ts +16 -0
- package/dist/search/subTypes/blobHTMLSearchType.d.ts.map +1 -0
- package/dist/search/subTypes/recordSearchType.d.ts +18 -0
- package/dist/search/subTypes/recordSearchType.d.ts.map +1 -0
- package/dist/search/subTypes/tupleSearchType.d.ts +21 -0
- package/dist/search/subTypes/tupleSearchType.d.ts.map +1 -0
- package/dist/search/superTypes/SpecialRealNumberSearchType.d.ts +14 -0
- package/dist/search/superTypes/SpecialRealNumberSearchType.d.ts.map +1 -0
- package/dist/search/superTypes/buffersourceSearchType.d.ts +17 -0
- package/dist/search/superTypes/buffersourceSearchType.d.ts.map +1 -0
- package/dist/search/superTypes/dommatrixSearchType.d.ts +11 -0
- package/dist/search/superTypes/dommatrixSearchType.d.ts.map +1 -0
- package/dist/search/superTypes/dompointSearchType.d.ts +9 -0
- package/dist/search/superTypes/dompointSearchType.d.ts.map +1 -0
- package/dist/search/superTypes/domrectSearchType.d.ts +9 -0
- package/dist/search/superTypes/domrectSearchType.d.ts.map +1 -0
- package/dist/search/superTypes/errorsSpecialSearchType.d.ts +11 -0
- package/dist/search/superTypes/errorsSpecialSearchType.d.ts.map +1 -0
- package/dist/search/unions/discriminatedUnionSearchType.d.ts +12 -0
- package/dist/search/unions/discriminatedUnionSearchType.d.ts.map +1 -0
- package/dist/search/unions/unionFamilySearchType.d.ts +36 -0
- package/dist/search/unions/unionFamilySearchType.d.ts.map +1 -0
- package/dist/search/unions/unionSearchType.d.ts +8 -0
- package/dist/search/unions/unionSearchType.d.ts.map +1 -0
- package/dist/search/unions/xorSearchType.d.ts +12 -0
- package/dist/search/unions/xorSearchType.d.ts.map +1 -0
- package/dist/superTypes/buffersourceType.d.ts.map +1 -1
- package/dist/typeChoices.d.ts +3 -3
- package/dist/typeChoices.d.ts.map +1 -1
- package/dist/types.d.ts +3 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/rawTypesonEditor.d.ts.map +1 -1
- package/docs/proposals/search-plan.md +166 -0
- package/package.json +5 -4
- package/pnpm-workspace.yaml +1 -1
- package/rollup.config.js +12 -0
- package/src/formatAndTypeChoices.js +4 -4
- package/src/formats/schema.js +2 -1
- package/src/formats.js +1 -1
- package/src/fundamentalTypes/dateType.js +35 -14
- package/src/fundamentalTypes/domexceptionType.js +41 -33
- package/src/index.js +6 -0
- package/src/jtltExtensions.js +103 -0
- package/src/search/fundamentalTypes/arraySearchType.js +66 -0
- package/src/search/fundamentalTypes/bigintSearchType.js +62 -0
- package/src/search/fundamentalTypes/blobSearchType.js +41 -0
- package/src/search/fundamentalTypes/booleanSearchType.js +40 -0
- package/src/search/fundamentalTypes/catchSearchType.js +59 -0
- package/src/search/fundamentalTypes/dateSearchType.js +73 -0
- package/src/search/fundamentalTypes/domexceptionSearchType.js +55 -0
- package/src/search/fundamentalTypes/enumSearchType.js +58 -0
- package/src/search/fundamentalTypes/errorSearchType.js +11 -0
- package/src/search/fundamentalTypes/fileSearchType.js +41 -0
- package/src/search/fundamentalTypes/filelistSearchType.js +78 -0
- package/src/search/fundamentalTypes/functionSearchType.js +78 -0
- package/src/search/fundamentalTypes/mapSearchType.js +87 -0
- package/src/search/fundamentalTypes/nanSearchType.js +11 -0
- package/src/search/fundamentalTypes/nullSearchType.js +11 -0
- package/src/search/fundamentalTypes/numberSearchType.js +52 -0
- package/src/search/fundamentalTypes/objectSearchType.js +148 -0
- package/src/search/fundamentalTypes/promiseSearchType.js +61 -0
- package/src/search/fundamentalTypes/regexpSearchType.js +48 -0
- package/src/search/fundamentalTypes/setSearchType.js +65 -0
- package/src/search/fundamentalTypes/stringSearchType.js +35 -0
- package/src/search/fundamentalTypes/symbolSearchType.js +38 -0
- package/src/search/fundamentalTypes/undefinedSearchType.js +11 -0
- package/src/search/index.js +79 -0
- package/src/search/queryTree.js +235 -0
- package/src/search/queryTreeBuilders.js +224 -0
- package/src/search/searchDispatch.js +291 -0
- package/src/search/searchElementUtils.js +289 -0
- package/src/search/searchUtils.js +355 -0
- package/src/search/subTypes/blobHTMLSearchType.js +65 -0
- package/src/search/subTypes/recordSearchType.js +84 -0
- package/src/search/subTypes/tupleSearchType.js +111 -0
- package/src/search/superTypes/SpecialRealNumberSearchType.js +42 -0
- package/src/search/superTypes/buffersourceSearchType.js +47 -0
- package/src/search/superTypes/dommatrixSearchType.js +24 -0
- package/src/search/superTypes/dompointSearchType.js +15 -0
- package/src/search/superTypes/domrectSearchType.js +15 -0
- package/src/search/superTypes/errorsSpecialSearchType.js +15 -0
- package/src/search/unions/discriminatedUnionSearchType.js +16 -0
- package/src/search/unions/unionFamilySearchType.js +160 -0
- package/src/search/unions/unionSearchType.js +12 -0
- package/src/search/unions/xorSearchType.js +16 -0
- package/src/superTypes/buffersourceType.js +13 -15
- package/src/typeChoices.js +2 -2
- package/src/types.js +2 -2
- package/src/utils/rawTypesonEditor.js +12 -2
- package/tsconfig-prod.json +12 -0
- package/tsconfig.json +5 -10
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSDoc-only typedefs for the schema-driven search query tree. No runtime
|
|
3
|
+
* exports live here; construct nodes through `queryTreeBuilders.js` instead
|
|
4
|
+
* so every search module (and every test fixture) goes through one place.
|
|
5
|
+
*
|
|
6
|
+
* Leaf `path` values reuse the existing JSON-Pointer convention from
|
|
7
|
+
* `src/utils/jsonPointer.js` (`makeJSONPointer`/`getJSONPointerParts`)
|
|
8
|
+
* rather than Mongo's dot-notation, so the search tree shares a path format
|
|
9
|
+
* with the rest of jsoe (e.g. `arrayType.js`'s `currentPath`).
|
|
10
|
+
*
|
|
11
|
+
* The leaf vocabulary borrows MongoDB's own operator names (`$and`/`$or`,
|
|
12
|
+
* `$gt`/`$gte`/`$lt`/`$lte`, `$in`/`$nin`, `$regex`/`$options`, `$exists`)
|
|
13
|
+
* wherever a leaf kind has a clean Mongo equivalent, so a host can adapt the
|
|
14
|
+
* common cases to `sift()` (or real MongoDB) almost for free - this is not a
|
|
15
|
+
* claim of full drop-in Mongo query-document compatibility: several
|
|
16
|
+
* jsoe-specific leaf kinds have no Mongo equivalent and stay custom, and
|
|
17
|
+
* every leaf keeps jsoe's own `kind`-discriminated, path-carrying shape
|
|
18
|
+
* rather than Mongo's field-keyed document shape.
|
|
19
|
+
*
|
|
20
|
+
* A path segment of `*` (e.g. `#/tags/*`) means "any element of the array
|
|
21
|
+
* at this point" - `arraySearchType.js`/`setSearchType.js`/`filelistSearchType.js`
|
|
22
|
+
* (element/value length/count constraint aside) and `tupleSearchType.js`'s
|
|
23
|
+
* `rest` portion use it when recursing into their element/value schema's
|
|
24
|
+
* own search widget, so a single nested leaf expresses "the collection
|
|
25
|
+
* contains at least one element matching this" (Mongo's `$elemMatch` is the
|
|
26
|
+
* natural translation target for a host walking a path that contains this
|
|
27
|
+
* segment) without needing a dedicated wrapper leaf kind - the collection's
|
|
28
|
+
* own `lengthSize` leaf and the recursed element leaf simply combine via
|
|
29
|
+
* `$and`. `recordSearchType.js`/`mapSearchType.js` similarly recurse into
|
|
30
|
+
* their `key`/`value` schemas at `*key`/`*value` segments, feeding the
|
|
31
|
+
* results into a single `mapRecordJoint` leaf (below) rather than combining
|
|
32
|
+
* via `$and`, since a host needs to know whether the two must match the
|
|
33
|
+
* same entry. `functionSearchType.js` recurses into its `input`/`output`
|
|
34
|
+
* schemas at `*args`/`*output` segments (the former itself a tuple, so its
|
|
35
|
+
* own per-position segments nest under `*args`), combined via `$and`.
|
|
36
|
+
* `promiseSearchType.js`/`catchSearchType.js` recurse into their wrapped
|
|
37
|
+
* value/`innerType` at the same path (there being exactly one value, no
|
|
38
|
+
* segment to add) and wrap the result in a `passThrough` leaf (below)
|
|
39
|
+
* rather than returning it bare, so the tree keeps visible that the leaf
|
|
40
|
+
* was reached through one of these transparent wrappers.
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @typedef {{$and: QueryNode[]}} QueryAnd
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @typedef {{$or: QueryNode[]}} QueryOr
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* `object` (via `$exists: true/false`).
|
|
53
|
+
* @typedef {{kind: 'hasProperty', path: string, $exists: boolean}} QueryHasPropertyLeaf
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* `array`/`set`/tuple-with-rest/`filelist` (via `$size`, or a range of
|
|
58
|
+
* operators when the schema doesn't pin an exact length), +`sparseCheck`
|
|
59
|
+
* for array sparse/not-sparse.
|
|
60
|
+
* @typedef {{
|
|
61
|
+
* kind: 'lengthSize',
|
|
62
|
+
* path: string,
|
|
63
|
+
* $size?: number,
|
|
64
|
+
* $gt?: number, $gte?: number, $lt?: number, $lte?: number,
|
|
65
|
+
* sparseCheck?: boolean
|
|
66
|
+
* }} QueryLengthSizeLeaf
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* `number`/`NumberObject`/`bigint`/`date`/`buffersource`, with `valueType`
|
|
71
|
+
* distinguishing them. Bounds are Mongo-style `$gt`/`$gte`/`$lt`/`$lte`
|
|
72
|
+
* rather than a `min`/`max` pair plus an inclusive boolean - inclusivity is
|
|
73
|
+
* simply which operator is present. The README's "Is Not Range" variant
|
|
74
|
+
* wraps the same leaf in `$not` rather than being a separate kind.
|
|
75
|
+
* @typedef {{
|
|
76
|
+
* kind: 'range',
|
|
77
|
+
* path: string,
|
|
78
|
+
* valueType: 'number'|'NumberObject'|'bigint'|'date'|'buffersource',
|
|
79
|
+
* $gt?: number|bigint|string,
|
|
80
|
+
* $gte?: number|bigint|string,
|
|
81
|
+
* $lt?: number|bigint|string,
|
|
82
|
+
* $lte?: number|bigint|string
|
|
83
|
+
* }} QueryRangeLeaf
|
|
84
|
+
*/
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @typedef {{kind: 'not', query: QueryNode}} QueryNotLeaf
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* `number`/`NumberObject`: is/is-not an integer.
|
|
92
|
+
* @typedef {{kind: 'integerCheck', path: string, isInteger: boolean}} QueryIntegerCheckLeaf
|
|
93
|
+
*/
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* `string`/`StringObject`/`Blob`/`File`/regexp-source/symbol-description
|
|
97
|
+
* (via `$in`/`$nin`).
|
|
98
|
+
* @typedef {{
|
|
99
|
+
* kind: 'literalSet',
|
|
100
|
+
* path: string,
|
|
101
|
+
* $in?: unknown[],
|
|
102
|
+
* $nin?: unknown[]
|
|
103
|
+
* }} QueryLiteralSetLeaf
|
|
104
|
+
*/
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* `string`/`StringObject`/`Blob`/`File`/regexp-source/symbol-description
|
|
108
|
+
* (via `$regex`/`$options`, matching Mongo's own field names).
|
|
109
|
+
* @typedef {{
|
|
110
|
+
* kind: 'regex',
|
|
111
|
+
* path: string,
|
|
112
|
+
* $regex: string,
|
|
113
|
+
* $options?: string
|
|
114
|
+
* }} QueryRegexLeaf
|
|
115
|
+
*/
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* `string`/`StringObject`/`Blob`/`File`/regexp-source/symbol-description:
|
|
119
|
+
* a substring the value must not contain.
|
|
120
|
+
* @typedef {{
|
|
121
|
+
* kind: 'notContains',
|
|
122
|
+
* path: string,
|
|
123
|
+
* value: string
|
|
124
|
+
* }} QueryNotContainsLeaf
|
|
125
|
+
*/
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* `enum`, SpecialNumber's `Infinity`/`-Infinity`/`NaN`/`-0` (via
|
|
129
|
+
* `$in`/`$nin`).
|
|
130
|
+
* @typedef {{
|
|
131
|
+
* kind: 'multiSelect',
|
|
132
|
+
* path: string,
|
|
133
|
+
* $in?: unknown[],
|
|
134
|
+
* $nin?: unknown[]
|
|
135
|
+
* }} QueryMultiSelectLeaf
|
|
136
|
+
*/
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Native enum key-vs-value; no Mongo equivalent, stays custom.
|
|
140
|
+
* @typedef {{
|
|
141
|
+
* kind: 'keyValueEnum',
|
|
142
|
+
* path: string,
|
|
143
|
+
* matchKeys: boolean,
|
|
144
|
+
* values: unknown[]
|
|
145
|
+
* }} QueryKeyValueEnumLeaf
|
|
146
|
+
*/
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Union/xor/discriminatedUnion "has type", carrying `discriminatorValue`
|
|
150
|
+
* when applicable, including when nested under a Map/Record key or value;
|
|
151
|
+
* no Mongo equivalent, stays custom.
|
|
152
|
+
* @typedef {{
|
|
153
|
+
* kind: 'typeOf',
|
|
154
|
+
* path: string,
|
|
155
|
+
* searchType: string,
|
|
156
|
+
* discriminatorValue?: unknown
|
|
157
|
+
* }} QueryTypeOfLeaf
|
|
158
|
+
*/
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* XPath/CSS-selector/full-text/raw-HTML-regex; no Mongo equivalent.
|
|
162
|
+
* @typedef {{
|
|
163
|
+
* kind: 'blobHTML',
|
|
164
|
+
* path: string,
|
|
165
|
+
* mode: 'xpath'|'cssSelector'|'fullText'|'rawHTMLRegex',
|
|
166
|
+
* value: string
|
|
167
|
+
* }} QueryBlobHTMLLeaf
|
|
168
|
+
*/
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Per-dimension ranges for DOMRect/Point/Matrix, each dimension itself a
|
|
172
|
+
* `range` leaf, + `readonlyCheck`/`dimensionCheck` (is/is-not readonly,
|
|
173
|
+
* is/is-not 3d); no Mongo equivalent.
|
|
174
|
+
* @typedef {{
|
|
175
|
+
* kind: 'domShape',
|
|
176
|
+
* path: string,
|
|
177
|
+
* dimensions: {[dimension: string]: QueryRangeLeaf},
|
|
178
|
+
* readonlyCheck?: boolean,
|
|
179
|
+
* dimensionCheck?: 2|3
|
|
180
|
+
* }} QueryDomShapeLeaf
|
|
181
|
+
*/
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Paired key+value leaves with a joint-match flag; no Mongo equivalent.
|
|
185
|
+
* @typedef {{
|
|
186
|
+
* kind: 'mapRecordJoint',
|
|
187
|
+
* path: string,
|
|
188
|
+
* keyQuery?: QueryNode,
|
|
189
|
+
* valueQuery?: QueryNode,
|
|
190
|
+
* joint: boolean
|
|
191
|
+
* }} QueryMapRecordJointLeaf
|
|
192
|
+
*/
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Promise/literal/catch/function: forwards to a nested `QueryNode` for the
|
|
196
|
+
* child schema so the tree stays uniform even where a type adds no
|
|
197
|
+
* constraint of its own; purely structural, no Mongo equivalent.
|
|
198
|
+
* @typedef {{
|
|
199
|
+
* kind: 'passThrough',
|
|
200
|
+
* path: string,
|
|
201
|
+
* query?: QueryNode
|
|
202
|
+
* }} QueryPassThroughLeaf
|
|
203
|
+
*/
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Undefined/void/null (via `$exists`).
|
|
207
|
+
* @typedef {{kind: 'presence', path: string, $exists: boolean}} QueryPresenceLeaf
|
|
208
|
+
*/
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Boolean/BooleanObject - Mongo would normally express this as a bare
|
|
212
|
+
* `{field: true}` shorthand, which doesn't fit our path-carrying leaf
|
|
213
|
+
* shape, so this stays a custom kind.
|
|
214
|
+
* @typedef {{
|
|
215
|
+
* kind: 'booleanEquals',
|
|
216
|
+
* path: string,
|
|
217
|
+
* value: boolean
|
|
218
|
+
* }} QueryBooleanEqualsLeaf
|
|
219
|
+
*/
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* @typedef {QueryHasPropertyLeaf|QueryLengthSizeLeaf|QueryRangeLeaf|
|
|
223
|
+
* QueryNotLeaf|QueryIntegerCheckLeaf|QueryLiteralSetLeaf|QueryRegexLeaf|
|
|
224
|
+
* QueryNotContainsLeaf|QueryMultiSelectLeaf|QueryKeyValueEnumLeaf|
|
|
225
|
+
* QueryTypeOfLeaf|QueryBlobHTMLLeaf|QueryDomShapeLeaf|
|
|
226
|
+
* QueryMapRecordJointLeaf|QueryPassThroughLeaf|QueryPresenceLeaf|
|
|
227
|
+
* QueryBooleanEqualsLeaf
|
|
228
|
+
* } QueryLeaf
|
|
229
|
+
*/
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* @typedef {QueryAnd|QueryOr|QueryLeaf} QueryNode
|
|
233
|
+
*/
|
|
234
|
+
|
|
235
|
+
export {};
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The only runtime pieces for building `queryTree.js` nodes - every search
|
|
3
|
+
* module builds nodes through these factories rather than hand-rolling leaf
|
|
4
|
+
* objects, so tests can import the same constructors to build expected-value
|
|
5
|
+
* fixtures.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {import('./queryTree.js').QueryNode[]} nodes
|
|
10
|
+
* @returns {import('./queryTree.js').QueryAnd}
|
|
11
|
+
*/
|
|
12
|
+
export function makeAndNode (nodes) {
|
|
13
|
+
return {$and: nodes};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Combines the leaves a single widget contributes (e.g. a number leaf's
|
|
18
|
+
* range plus its separate "Is/Is Not Integer" check) into one `QueryNode`:
|
|
19
|
+
* drops any `undefined` (no constraint entered there), returns `undefined`
|
|
20
|
+
* if nothing is left, the bare node if only one is left, else an `$and` of
|
|
21
|
+
* the rest - so a widget with several independent controls still honors
|
|
22
|
+
* `getQuery`'s "`undefined` means no constraint" convention without every
|
|
23
|
+
* such widget re-implementing this collapsing logic itself.
|
|
24
|
+
* @param {(import('./queryTree.js').QueryNode|undefined)[]} nodes
|
|
25
|
+
* @returns {import('./queryTree.js').QueryNode|undefined}
|
|
26
|
+
*/
|
|
27
|
+
export function combineAnd (nodes) {
|
|
28
|
+
const filtered = /** @type {import('./queryTree.js').QueryNode[]} */ (
|
|
29
|
+
nodes.filter((node) => node !== undefined)
|
|
30
|
+
);
|
|
31
|
+
if (filtered.length === 0) {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
if (filtered.length === 1) {
|
|
35
|
+
return filtered[0];
|
|
36
|
+
}
|
|
37
|
+
return makeAndNode(filtered);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @param {import('./queryTree.js').QueryNode[]} nodes
|
|
42
|
+
* @returns {import('./queryTree.js').QueryOr}
|
|
43
|
+
*/
|
|
44
|
+
export function makeOrNode (nodes) {
|
|
45
|
+
return {$or: nodes};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @param {string} path
|
|
50
|
+
* @param {boolean} $exists
|
|
51
|
+
* @returns {import('./queryTree.js').QueryHasPropertyLeaf}
|
|
52
|
+
*/
|
|
53
|
+
export function makeHasPropertyLeaf (path, $exists) {
|
|
54
|
+
return {kind: 'hasProperty', path, $exists};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @param {string} path
|
|
59
|
+
* @param {{
|
|
60
|
+
* $size?: number,
|
|
61
|
+
* $gt?: number, $gte?: number, $lt?: number, $lte?: number,
|
|
62
|
+
* sparseCheck?: boolean
|
|
63
|
+
* }} cfg
|
|
64
|
+
* @returns {import('./queryTree.js').QueryLengthSizeLeaf}
|
|
65
|
+
*/
|
|
66
|
+
export function makeLengthSizeLeaf (path, cfg = {}) {
|
|
67
|
+
return {kind: 'lengthSize', path, ...cfg};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @param {string} path
|
|
72
|
+
* @param {import('./queryTree.js').QueryRangeLeaf['valueType']} valueType
|
|
73
|
+
* @param {{
|
|
74
|
+
* $gt?: number|bigint|string, $gte?: number|bigint|string,
|
|
75
|
+
* $lt?: number|bigint|string, $lte?: number|bigint|string
|
|
76
|
+
* }} cfg
|
|
77
|
+
* @returns {import('./queryTree.js').QueryRangeLeaf}
|
|
78
|
+
*/
|
|
79
|
+
export function makeRangeLeaf (path, valueType, cfg = {}) {
|
|
80
|
+
return {kind: 'range', path, valueType, ...cfg};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @param {import('./queryTree.js').QueryNode} query
|
|
85
|
+
* @returns {import('./queryTree.js').QueryNotLeaf}
|
|
86
|
+
*/
|
|
87
|
+
export function makeNotLeaf (query) {
|
|
88
|
+
return {kind: 'not', query};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @param {string} path
|
|
93
|
+
* @param {boolean} isInteger
|
|
94
|
+
* @returns {import('./queryTree.js').QueryIntegerCheckLeaf}
|
|
95
|
+
*/
|
|
96
|
+
export function makeIntegerCheckLeaf (path, isInteger) {
|
|
97
|
+
return {kind: 'integerCheck', path, isInteger};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @param {string} path
|
|
102
|
+
* @param {{$in?: unknown[], $nin?: unknown[]}} cfg
|
|
103
|
+
* @returns {import('./queryTree.js').QueryLiteralSetLeaf}
|
|
104
|
+
*/
|
|
105
|
+
export function makeLiteralSetLeaf (path, cfg = {}) {
|
|
106
|
+
return {kind: 'literalSet', path, ...cfg};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @param {string} path
|
|
111
|
+
* @param {string} $regex
|
|
112
|
+
* @param {string} [$options]
|
|
113
|
+
* @returns {import('./queryTree.js').QueryRegexLeaf}
|
|
114
|
+
*/
|
|
115
|
+
export function makeRegexLeaf (path, $regex, $options) {
|
|
116
|
+
return {kind: 'regex', path, $regex, ...($options ? {$options} : {})};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @param {string} path
|
|
121
|
+
* @param {string} value
|
|
122
|
+
* @returns {import('./queryTree.js').QueryNotContainsLeaf}
|
|
123
|
+
*/
|
|
124
|
+
export function makeNotContainsLeaf (path, value) {
|
|
125
|
+
return {kind: 'notContains', path, value};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* @param {string} path
|
|
130
|
+
* @param {{$in?: unknown[], $nin?: unknown[]}} cfg
|
|
131
|
+
* @returns {import('./queryTree.js').QueryMultiSelectLeaf}
|
|
132
|
+
*/
|
|
133
|
+
export function makeMultiSelectLeaf (path, cfg = {}) {
|
|
134
|
+
return {kind: 'multiSelect', path, ...cfg};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* @param {string} path
|
|
139
|
+
* @param {boolean} matchKeys
|
|
140
|
+
* @param {unknown[]} values
|
|
141
|
+
* @returns {import('./queryTree.js').QueryKeyValueEnumLeaf}
|
|
142
|
+
*/
|
|
143
|
+
export function makeKeyValueEnumLeaf (path, matchKeys, values) {
|
|
144
|
+
return {kind: 'keyValueEnum', path, matchKeys, values};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* @param {string} path
|
|
149
|
+
* @param {string} searchType
|
|
150
|
+
* @param {unknown} [discriminatorValue]
|
|
151
|
+
* @returns {import('./queryTree.js').QueryTypeOfLeaf}
|
|
152
|
+
*/
|
|
153
|
+
export function makeTypeOfLeaf (path, searchType, discriminatorValue) {
|
|
154
|
+
return {
|
|
155
|
+
kind: 'typeOf',
|
|
156
|
+
path,
|
|
157
|
+
searchType,
|
|
158
|
+
...(discriminatorValue === undefined ? {} : {discriminatorValue})
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* @param {string} path
|
|
164
|
+
* @param {import('./queryTree.js').QueryBlobHTMLLeaf['mode']} mode
|
|
165
|
+
* @param {string} value
|
|
166
|
+
* @returns {import('./queryTree.js').QueryBlobHTMLLeaf}
|
|
167
|
+
*/
|
|
168
|
+
export function makeBlobHTMLLeaf (path, mode, value) {
|
|
169
|
+
return {kind: 'blobHTML', path, mode, value};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* @param {string} path
|
|
174
|
+
* @param {{[dimension: string]: import('./queryTree.js').QueryRangeLeaf}} dimensions
|
|
175
|
+
* @param {{readonlyCheck?: boolean, dimensionCheck?: 2|3}} [cfg]
|
|
176
|
+
* @returns {import('./queryTree.js').QueryDomShapeLeaf}
|
|
177
|
+
*/
|
|
178
|
+
export function makeDomShapeLeaf (path, dimensions, cfg = {}) {
|
|
179
|
+
return {kind: 'domShape', path, dimensions, ...cfg};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* @param {string} path
|
|
184
|
+
* @param {boolean} joint
|
|
185
|
+
* @param {import('./queryTree.js').QueryNode} [keyQuery]
|
|
186
|
+
* @param {import('./queryTree.js').QueryNode} [valueQuery]
|
|
187
|
+
* @returns {import('./queryTree.js').QueryMapRecordJointLeaf}
|
|
188
|
+
*/
|
|
189
|
+
export function makeMapRecordJointLeaf (path, joint, keyQuery, valueQuery) {
|
|
190
|
+
return {
|
|
191
|
+
kind: 'mapRecordJoint',
|
|
192
|
+
path,
|
|
193
|
+
joint,
|
|
194
|
+
...(keyQuery ? {keyQuery} : {}),
|
|
195
|
+
...(valueQuery ? {valueQuery} : {})
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* @param {string} path
|
|
201
|
+
* @param {import('./queryTree.js').QueryNode} [query]
|
|
202
|
+
* @returns {import('./queryTree.js').QueryPassThroughLeaf}
|
|
203
|
+
*/
|
|
204
|
+
export function makePassThroughLeaf (path, query) {
|
|
205
|
+
return {kind: 'passThrough', path, ...(query ? {query} : {})};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* @param {string} path
|
|
210
|
+
* @param {boolean} $exists
|
|
211
|
+
* @returns {import('./queryTree.js').QueryPresenceLeaf}
|
|
212
|
+
*/
|
|
213
|
+
export function makePresenceLeaf (path, $exists) {
|
|
214
|
+
return {kind: 'presence', path, $exists};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* @param {string} path
|
|
219
|
+
* @param {boolean} value
|
|
220
|
+
* @returns {import('./queryTree.js').QueryBooleanEqualsLeaf}
|
|
221
|
+
*/
|
|
222
|
+
export function makeBooleanEqualsLeaf (path, value) {
|
|
223
|
+
return {kind: 'booleanEquals', path, value};
|
|
224
|
+
}
|