@spotto/semantic-query 1.0.70-alpha.18
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/dist/dates.d.ts +32 -0
- package/dist/dates.js +105 -0
- package/dist/dates.js.map +1 -0
- package/dist/evaluate.d.ts +28 -0
- package/dist/evaluate.js +218 -0
- package/dist/evaluate.js.map +1 -0
- package/dist/fixtures.d.ts +248 -0
- package/dist/fixtures.js +156 -0
- package/dist/fixtures.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +48 -0
- package/dist/index.js.map +1 -0
- package/dist/suggest.d.ts +12 -0
- package/dist/suggest.js +70 -0
- package/dist/suggest.js.map +1 -0
- package/dist/types.d.ts +76 -0
- package/dist/types.js +24 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +33 -0
- package/dist/validate.js +487 -0
- package/dist/validate.js.map +1 -0
- package/package.json +29 -0
package/dist/validate.js
ADDED
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.queryUsesCustomFields = exports.validateSemanticQuery = exports.assertSemanticQuery = exports.coerceSemanticValue = exports.findSemanticField = exports.SEMANTIC_TIMESTAMP_FIELD = exports.SEMANTIC_VALUE_SLOT = void 0;
|
|
4
|
+
const contract_1 = require("@spotto/contract");
|
|
5
|
+
const suggest_1 = require("./suggest");
|
|
6
|
+
const dates_1 = require("./dates");
|
|
7
|
+
const types_1 = require("./types");
|
|
8
|
+
/**
|
|
9
|
+
* Every rule of the semantic query language, in one place.
|
|
10
|
+
*
|
|
11
|
+
* This is the gate both back-ends stand behind: nothing executes a query that
|
|
12
|
+
* has not passed through here, so a rule fixed here is fixed for the client's
|
|
13
|
+
* offline evaluation and the server's Mongo read at the same time. Before this
|
|
14
|
+
* package existed the rules lived inside the Mongo compiler — which meant the
|
|
15
|
+
* only way to ask "is this query valid?" was to try to compile it to MongoDB,
|
|
16
|
+
* and a client could not ask at all.
|
|
17
|
+
*
|
|
18
|
+
* Every rule below was paid for with a query that RAN and returned the wrong
|
|
19
|
+
* rows. None of them throw in the ordinary case; all of them exist because the
|
|
20
|
+
* failure they prevent is silent.
|
|
21
|
+
*
|
|
22
|
+
* Fail-fast: the FIRST problem is the answer. The issues array exists because
|
|
23
|
+
* the wire shape has always carried one, not because more than one is ever
|
|
24
|
+
* reported.
|
|
25
|
+
*/
|
|
26
|
+
const LIMITS = contract_1.SEMANTIC_QUERY_LIMITS;
|
|
27
|
+
/** The live storage slots. `valueBool` does not exist; the live key is `valueBoolean`. */
|
|
28
|
+
exports.SEMANTIC_VALUE_SLOT = {
|
|
29
|
+
STRING: 'valueString',
|
|
30
|
+
INTEGER: 'valueInteger',
|
|
31
|
+
DECIMAL: 'valueDecimal',
|
|
32
|
+
BOOLEAN: 'valueBoolean',
|
|
33
|
+
DATE: 'valueDate',
|
|
34
|
+
};
|
|
35
|
+
/** Millisecond-timestamp fields, by condition type. `createdDate` uses the ObjectId. */
|
|
36
|
+
exports.SEMANTIC_TIMESTAMP_FIELD = {
|
|
37
|
+
lastUpdated: 'lastUpdated',
|
|
38
|
+
lastChanged: 'lastChanged',
|
|
39
|
+
lastSeen: 'state.lastSeen',
|
|
40
|
+
firstSeen: 'state.firstSeen',
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* The complete property vocabulary, per condition type. Closed at the
|
|
44
|
+
* PROPERTY level, not just types and operators: a generated
|
|
45
|
+
* `{"type":"and","conditions":[…],"negate":true}` once compiled as a plain
|
|
46
|
+
* AND — the description said "NOT IN" while the query matched exactly the
|
|
47
|
+
* opposite set, with no error anywhere.
|
|
48
|
+
*/
|
|
49
|
+
const TIMESTAMP_KEYS = ['type', 'operator', 'value', 'includeNeverSet'];
|
|
50
|
+
const ALLOWED_KEYS = {
|
|
51
|
+
and: ['type', 'conditions'],
|
|
52
|
+
or: ['type', 'conditions'],
|
|
53
|
+
assetType: ['type', 'path', 'includeSubtypes'],
|
|
54
|
+
location: ['type', 'path', 'includeSublocations'],
|
|
55
|
+
homeLocation: ['type', 'path', 'includeSublocations'],
|
|
56
|
+
withAsset: ['type', 'assetId', 'hasAny'],
|
|
57
|
+
customField: ['type', 'fieldName', 'dataType', 'operator', 'value', 'includeUnset'],
|
|
58
|
+
createdDate: TIMESTAMP_KEYS,
|
|
59
|
+
lastUpdated: TIMESTAMP_KEYS,
|
|
60
|
+
lastChanged: TIMESTAMP_KEYS,
|
|
61
|
+
lastSeen: TIMESTAMP_KEYS,
|
|
62
|
+
firstSeen: TIMESTAMP_KEYS,
|
|
63
|
+
geolocation: ['type', 'exists'],
|
|
64
|
+
tags: ['type', 'operator', 'values'],
|
|
65
|
+
telemetry: ['type', 'field', 'operator', 'value'],
|
|
66
|
+
readiness: ['type', 'level', 'levels'],
|
|
67
|
+
kit: ['type', 'isKit', 'isMember', 'satisfied', 'parentAssetId'],
|
|
68
|
+
locationStatus: ['type', 'values'],
|
|
69
|
+
};
|
|
70
|
+
const HEX24 = /^[0-9a-fA-F]{24}$/;
|
|
71
|
+
function checkProperties(cond, path) {
|
|
72
|
+
// The table is typed against the contract's vocabulary (a new condition type
|
|
73
|
+
// is a compile error until it is listed); the lookup itself takes whatever
|
|
74
|
+
// arbitrary string arrived on the wire.
|
|
75
|
+
const allowed = ALLOWED_KEYS[String(cond.type)];
|
|
76
|
+
if (!allowed)
|
|
77
|
+
return; // unknown type gets its own, better message
|
|
78
|
+
const extra = Object.keys(cond).filter((k) => !allowed.includes(k));
|
|
79
|
+
if (extra.length) {
|
|
80
|
+
(0, types_1.failSemanticValidation)(path, 'UNKNOWN_PROPERTY', `'${cond.type}' does not support ${extra.map((k) => `'${k}'`).join(', ')}` +
|
|
81
|
+
` (allowed: ${allowed.filter((k) => k !== 'type').join(', ') || 'none'})`, extra.includes('negate') || extra.includes('not')
|
|
82
|
+
? 'The query language has no negation. Express the opposite directly, ' +
|
|
83
|
+
'or use notExists for an unset field.'
|
|
84
|
+
: undefined);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function requireString(v, path, field) {
|
|
88
|
+
if (typeof v !== 'string' || v === '') {
|
|
89
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_SHAPE', `'${field}' must be a non-empty string`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Mutually-exclusive properties, enforced here and not only at the wire
|
|
94
|
+
* boundary.
|
|
95
|
+
*
|
|
96
|
+
* Closing key NAMES is not enough. A back-end that merely picked one branch
|
|
97
|
+
* would silently IGNORE the other — a query that runs and returns rows
|
|
98
|
+
* unrelated to half of what it says. Same failure class as the invented
|
|
99
|
+
* `negate` property, one level down.
|
|
100
|
+
*/
|
|
101
|
+
function requireExactlyOne(cond, keys, path, label) {
|
|
102
|
+
const set = keys.filter((k) => cond[k] !== undefined);
|
|
103
|
+
if (set.length !== 1) {
|
|
104
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_SHAPE', set.length === 0
|
|
105
|
+
? `${label} needs exactly one of ${keys.join(', ')}`
|
|
106
|
+
: `${label} takes exactly one of ${keys.join(', ')} — got ${set.join(' and ')}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Boolean-typed properties must be REAL booleans, not truthy stand-ins. This
|
|
111
|
+
* is an axis where the two back-ends part company: the Mongo compiler branches
|
|
112
|
+
* on truthiness while the evaluator compares with `===`, so `isKit: null`
|
|
113
|
+
* matches every non-kit in Mongo and nothing in memory. Worst is
|
|
114
|
+
* `satisfied: null`, which compiles to `{groupSatisfiesKit: null}` — Mongo
|
|
115
|
+
* reads that as "missing OR null", i.e. the whole non-kit fleet: the exact
|
|
116
|
+
* wrong-rows bug the exact-match ruling closed, back through a side door. And
|
|
117
|
+
* even where the engines agree (`includeSubtypes: "false"` reads as true on
|
|
118
|
+
* both sides), the query silently means the opposite of what was written.
|
|
119
|
+
*/
|
|
120
|
+
function requireBooleansIfSet(cond, keys, path) {
|
|
121
|
+
for (const k of keys) {
|
|
122
|
+
const v = cond[k];
|
|
123
|
+
if (v !== undefined && typeof v !== 'boolean') {
|
|
124
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_VALUE', `'${k}' must be true or false — got ${JSON.stringify(v)}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Find a field by name, case-insensitively — the one lookup both back-ends
|
|
130
|
+
* use, so neither can resolve a name to a different field than the other.
|
|
131
|
+
*/
|
|
132
|
+
function findSemanticField(catalogue, fieldName) {
|
|
133
|
+
return catalogue.fields.find((f) => f.name.toLowerCase() === String(fieldName).toLowerCase());
|
|
134
|
+
}
|
|
135
|
+
exports.findSemanticField = findSemanticField;
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
// Leaves
|
|
138
|
+
// ---------------------------------------------------------------------------
|
|
139
|
+
function checkLeaf(cond, ctx, path) {
|
|
140
|
+
// Also checked here, not only in the tree walk: leaves nested inside an
|
|
141
|
+
// `or` reach this function directly.
|
|
142
|
+
checkProperties(cond, path);
|
|
143
|
+
switch (cond.type) {
|
|
144
|
+
case 'assetType':
|
|
145
|
+
requireString(cond.path, path, 'path');
|
|
146
|
+
requireBooleansIfSet(cond, ['includeSubtypes'], path);
|
|
147
|
+
return;
|
|
148
|
+
case 'location':
|
|
149
|
+
case 'homeLocation':
|
|
150
|
+
requireString(cond.path, path, 'path');
|
|
151
|
+
requireBooleansIfSet(cond, ['includeSublocations'], path);
|
|
152
|
+
return;
|
|
153
|
+
case 'withAsset': {
|
|
154
|
+
requireExactlyOne(cond, ['assetId', 'hasAny'], path, 'withAsset');
|
|
155
|
+
requireBooleansIfSet(cond, ['hasAny'], path);
|
|
156
|
+
if (cond.hasAny !== undefined)
|
|
157
|
+
return;
|
|
158
|
+
if (!cond.assetId || !HEX24.test(cond.assetId)) {
|
|
159
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_ASSET_ID', 'withAsset needs a valid assetId (24-hex) or hasAny');
|
|
160
|
+
}
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
case 'geolocation':
|
|
164
|
+
requireBooleansIfSet(cond, ['exists'], path);
|
|
165
|
+
return;
|
|
166
|
+
case 'tags':
|
|
167
|
+
// Both back-ends read anything that is not 'all' as 'any', so an
|
|
168
|
+
// unchecked operator is a typo silently widening all-of to any-of —
|
|
169
|
+
// with the two engines agreeing and both wrong about the intent.
|
|
170
|
+
if (cond.operator !== undefined &&
|
|
171
|
+
!contract_1.semanticSetOperators.includes(cond.operator)) {
|
|
172
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_OPERATOR', `tags operator must be one of ${contract_1.semanticSetOperators.join(', ')} — got '${cond.operator}'`, (0, suggest_1.nearest)(contract_1.semanticSetOperators, String(cond.operator)));
|
|
173
|
+
}
|
|
174
|
+
if (!Array.isArray(cond.values) || cond.values.length === 0) {
|
|
175
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_TAGS', 'tags condition needs a non-empty values array');
|
|
176
|
+
}
|
|
177
|
+
return;
|
|
178
|
+
case 'telemetry': {
|
|
179
|
+
// Re-checked here, not only at the wire boundary: this value becomes part
|
|
180
|
+
// of a document PATH downstream, so an unchecked field name would build a
|
|
181
|
+
// query over an arbitrary key.
|
|
182
|
+
if (!contract_1.semanticTelemetryFields.includes(cond.field)) {
|
|
183
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_VALUE', `Unknown telemetry field '${cond.field}' (allowed: ${contract_1.semanticTelemetryFields.join(', ')})`, (0, suggest_1.nearest)(contract_1.semanticTelemetryFields, String(cond.field)));
|
|
184
|
+
}
|
|
185
|
+
if (!['eq', 'ne', 'gt', 'gte', 'lt', 'lte'].includes(cond.operator)) {
|
|
186
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_OPERATOR', `Unknown telemetry operator '${cond.operator}'`);
|
|
187
|
+
}
|
|
188
|
+
if (typeof cond.value !== 'number') {
|
|
189
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_VALUE', `telemetry '${cond.field}' needs a numeric value`);
|
|
190
|
+
}
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
case 'readiness':
|
|
194
|
+
checkReadiness(cond, path);
|
|
195
|
+
return;
|
|
196
|
+
case 'kit': {
|
|
197
|
+
requireExactlyOne(cond, ['isKit', 'isMember', 'satisfied', 'parentAssetId'], path, 'kit');
|
|
198
|
+
requireBooleansIfSet(cond, ['isKit', 'isMember', 'satisfied'], path);
|
|
199
|
+
if (cond.parentAssetId !== undefined && !HEX24.test(cond.parentAssetId)) {
|
|
200
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_ASSET_ID', 'kit.parentAssetId must be a 24-hex asset id');
|
|
201
|
+
}
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
case 'locationStatus': {
|
|
205
|
+
if (!Array.isArray(cond.values) || cond.values.length === 0) {
|
|
206
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_SHAPE', 'locationStatus needs a non-empty values array');
|
|
207
|
+
}
|
|
208
|
+
const unknown = cond.values.filter((v) => !contract_1.LOCATION_STATUS.includes(v));
|
|
209
|
+
if (unknown.length) {
|
|
210
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_VALUE', `Unknown location status ${unknown.map((v) => `'${v}'`).join(', ')}`, (0, suggest_1.nearest)(contract_1.LOCATION_STATUS, String(unknown[0])));
|
|
211
|
+
}
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
case 'createdDate':
|
|
215
|
+
case 'lastUpdated':
|
|
216
|
+
case 'lastChanged':
|
|
217
|
+
case 'lastSeen':
|
|
218
|
+
case 'firstSeen':
|
|
219
|
+
checkTimestamp(cond, ctx, path);
|
|
220
|
+
return;
|
|
221
|
+
case 'customField':
|
|
222
|
+
checkCustomField(cond, ctx, path);
|
|
223
|
+
return;
|
|
224
|
+
default:
|
|
225
|
+
(0, types_1.failSemanticValidation)(path, 'UNKNOWN_TYPE', `Unknown condition type '${cond.type}'`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
function checkReadiness(cond, path) {
|
|
229
|
+
var _a;
|
|
230
|
+
if (cond.level !== undefined && cond.levels !== undefined) {
|
|
231
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_SHAPE', "readiness takes 'level' or 'levels', not both");
|
|
232
|
+
}
|
|
233
|
+
const levels = (_a = cond.levels) !== null && _a !== void 0 ? _a : (cond.level === undefined ? undefined : [cond.level]);
|
|
234
|
+
if (!levels)
|
|
235
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_SHAPE', "readiness needs 'level' or 'levels'");
|
|
236
|
+
if (!Array.isArray(levels))
|
|
237
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_SHAPE', "'levels' must be an array");
|
|
238
|
+
if (levels.length === 0)
|
|
239
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_SHAPE', "'levels' must be non-empty");
|
|
240
|
+
for (const l of levels) {
|
|
241
|
+
if (l !== 0 && l !== 1 && l !== 2) {
|
|
242
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_VALUE', `readiness level must be 0 (ready), 1 (conditional) or 2 (not ready) — got ${l}`);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
function checkTimestamp(cond, ctx, path) {
|
|
247
|
+
const op = cond.operator;
|
|
248
|
+
if (!['gt', 'gte', 'lt', 'lte'].includes(op)) {
|
|
249
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_OPERATOR', `'${cond.type}' supports gt, gte, lt, lte — got '${op}'`);
|
|
250
|
+
}
|
|
251
|
+
if (cond.value === undefined) {
|
|
252
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_SHAPE', `'${cond.type}' ${op} needs a value`);
|
|
253
|
+
}
|
|
254
|
+
if (cond.includeNeverSet !== undefined && op !== 'lt' && op !== 'lte') {
|
|
255
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_SHAPE', `'includeNeverSet' applies to lt/lte only — a missing timestamp correctly fails ${op}`);
|
|
256
|
+
}
|
|
257
|
+
requireBooleansIfSet(cond, ['includeNeverSet'], path);
|
|
258
|
+
let ms;
|
|
259
|
+
try {
|
|
260
|
+
ms = (0, dates_1.semanticDateBoundaryMs)(cond.value, op, ctx.now, ctx.tz);
|
|
261
|
+
}
|
|
262
|
+
catch (e) {
|
|
263
|
+
return (0, types_1.failSemanticValidation)(path, 'BAD_DATE', e.message);
|
|
264
|
+
}
|
|
265
|
+
if (cond.type === 'createdDate') {
|
|
266
|
+
// Creation time is carried by the ObjectId, whose 4-byte timestamp is
|
|
267
|
+
// unsigned: dates before 1970 or past 2106 have no id to compare against,
|
|
268
|
+
// and must fail as a validation issue rather than as an exception escaping
|
|
269
|
+
// from a back-end. `+1` because the inclusive forms step a second (see the
|
|
270
|
+
// compiler's boundary-second note).
|
|
271
|
+
const second = Math.floor(ms / 1000) + 1;
|
|
272
|
+
if (second < 0 || second > 0xffffffff) {
|
|
273
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_DATE', `'${cond.type}': date is outside the representable range (1970–2106)`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
function checkCustomField(cond, ctx, path) {
|
|
278
|
+
var _a;
|
|
279
|
+
const fdef = findSemanticField(ctx.catalogue, cond.fieldName);
|
|
280
|
+
if (!fdef) {
|
|
281
|
+
(0, types_1.failSemanticValidation)(path, 'UNKNOWN_FIELD', `No custom field named '${cond.fieldName}'`, (0, suggest_1.nearest)(ctx.catalogue.fields.map((f) => f.name), String(cond.fieldName)));
|
|
282
|
+
}
|
|
283
|
+
if (cond.operator === 'exists' || cond.operator === 'notExists') {
|
|
284
|
+
if (cond.value !== undefined) {
|
|
285
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_SHAPE', `'${cond.fieldName}' ${cond.operator} takes no value`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
else if (cond.value === undefined) {
|
|
289
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_SHAPE', `'${cond.fieldName}' ${cond.operator} needs a value`);
|
|
290
|
+
}
|
|
291
|
+
if (cond.includeUnset !== undefined && cond.operator !== 'ne') {
|
|
292
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_SHAPE', "'includeUnset' applies to the ne operator only — it is what decides " +
|
|
293
|
+
'whether an unset field counts as "not equal"');
|
|
294
|
+
}
|
|
295
|
+
requireBooleansIfSet(cond, ['includeUnset'], path);
|
|
296
|
+
// Honest refusal until the DATETIME ruling lands: matching against the wrong
|
|
297
|
+
// slot is a valid query that returns nothing.
|
|
298
|
+
if (fdef.dataType === 'DATETIME') {
|
|
299
|
+
(0, types_1.failSemanticValidation)(path, 'UNSUPPORTED_DATATYPE', `'${fdef.name}' is a date-and-time field, which semantic queries do not support yet`);
|
|
300
|
+
}
|
|
301
|
+
// A dropdown value must match an option exactly, or the query silently
|
|
302
|
+
// returns nothing. Reject with the nearest option instead.
|
|
303
|
+
if (((_a = fdef.options) === null || _a === void 0 ? void 0 : _a.length) && cond.operator === 'eq' && typeof cond.value === 'string') {
|
|
304
|
+
if (!fdef.options.includes(cond.value)) {
|
|
305
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_OPTION', `'${cond.value}' is not an option for '${fdef.name}'`, (0, suggest_1.nearest)(fdef.options, cond.value));
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
if (cond.operator === 'contains') {
|
|
309
|
+
if (fdef.dataType !== 'STRING') {
|
|
310
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_OPERATOR', `'contains' applies to STRING fields only ('${fdef.name}' is ${fdef.dataType})`);
|
|
311
|
+
}
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
if (cond.operator === 'exists' || cond.operator === 'notExists')
|
|
315
|
+
return;
|
|
316
|
+
if (!['eq', 'ne', 'gt', 'gte', 'lt', 'lte'].includes(cond.operator)) {
|
|
317
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_OPERATOR', `Unknown operator '${cond.operator}' on '${fdef.name}'`);
|
|
318
|
+
}
|
|
319
|
+
// The value must be expressible in the slot it will be compared against.
|
|
320
|
+
checkValue(cond, fdef, ctx, path);
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Turn a written value into the form its storage slot actually holds.
|
|
324
|
+
*
|
|
325
|
+
* Shared deliberately: the Mongo compiler and the in-memory evaluator must
|
|
326
|
+
* compare against the SAME value, and this is where a numeric literal for a
|
|
327
|
+
* text field, or a relative date for a DATE field, becomes one concrete thing.
|
|
328
|
+
* Two copies of this would classify the same document differently.
|
|
329
|
+
*
|
|
330
|
+
* Throws a plain Error — the caller decides whether that is a validation issue
|
|
331
|
+
* (it is, at the gate) or an impossible state (it is, after the gate).
|
|
332
|
+
*/
|
|
333
|
+
function coerceSemanticValue(value, dataType, now, tz) {
|
|
334
|
+
switch (dataType) {
|
|
335
|
+
case 'DATE':
|
|
336
|
+
// Confirmed encoding: YYYYMMDD integer, e.g. 20260815.
|
|
337
|
+
return (0, dates_1.semanticCivilToYyyymmdd)((0, dates_1.resolveSemanticDate)(value, now, tz));
|
|
338
|
+
case 'INTEGER':
|
|
339
|
+
case 'DECIMAL': {
|
|
340
|
+
const n = typeof value === 'number' ? value : Number(value);
|
|
341
|
+
if (!Number.isFinite(n)) {
|
|
342
|
+
throw new Error(`is ${dataType} but got '${String(value)}'`);
|
|
343
|
+
}
|
|
344
|
+
return n;
|
|
345
|
+
}
|
|
346
|
+
case 'BOOLEAN': {
|
|
347
|
+
if (typeof value === 'boolean')
|
|
348
|
+
return value;
|
|
349
|
+
if (value === 'true' || value === 'false')
|
|
350
|
+
return value === 'true';
|
|
351
|
+
throw new Error(`is BOOLEAN but got '${String(value)}'`);
|
|
352
|
+
}
|
|
353
|
+
default:
|
|
354
|
+
return typeof value === 'string' ? value : String(value !== null && value !== void 0 ? value : '');
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
exports.coerceSemanticValue = coerceSemanticValue;
|
|
358
|
+
function checkValue(cond, fdef, ctx, path) {
|
|
359
|
+
try {
|
|
360
|
+
coerceSemanticValue(cond.value, fdef.dataType, ctx.now, ctx.tz);
|
|
361
|
+
}
|
|
362
|
+
catch (e) {
|
|
363
|
+
const message = e.message;
|
|
364
|
+
fdef.dataType === 'DATE'
|
|
365
|
+
? (0, types_1.failSemanticValidation)(path, 'BAD_DATE', `'${fdef.name}': ${message}`)
|
|
366
|
+
: (0, types_1.failSemanticValidation)(path, 'BAD_VALUE', `'${fdef.name}' ${message}`);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
// ---------------------------------------------------------------------------
|
|
370
|
+
// Tree
|
|
371
|
+
// ---------------------------------------------------------------------------
|
|
372
|
+
function checkConditions(conds, ctx, depth, budget, path) {
|
|
373
|
+
if (!Array.isArray(conds))
|
|
374
|
+
(0, types_1.failSemanticValidation)(path, 'BAD_SHAPE', 'conditions must be an array');
|
|
375
|
+
if (depth > LIMITS.maxDepth) {
|
|
376
|
+
(0, types_1.failSemanticValidation)(path, 'TOO_DEEP', `Nesting exceeds maximum depth ${LIMITS.maxDepth}`);
|
|
377
|
+
}
|
|
378
|
+
conds.forEach((cond, i) => {
|
|
379
|
+
if (++budget.n > LIMITS.maxConditions) {
|
|
380
|
+
(0, types_1.failSemanticValidation)(path, 'TOO_MANY', `Query exceeds maximum of ${LIMITS.maxConditions} conditions`);
|
|
381
|
+
}
|
|
382
|
+
const p = `${path}[${i}]`;
|
|
383
|
+
if (!cond || typeof cond !== 'object')
|
|
384
|
+
(0, types_1.failSemanticValidation)(p, 'BAD_SHAPE', 'condition must be an object');
|
|
385
|
+
if (cond.type === 'and' || cond.type === 'or') {
|
|
386
|
+
// Leaves are checked inside checkLeaf (the only path an or-branch leaf
|
|
387
|
+
// takes), so groups are checked here and nowhere twice.
|
|
388
|
+
checkProperties(cond, p);
|
|
389
|
+
if (!Array.isArray(cond.conditions) || cond.conditions.length === 0) {
|
|
390
|
+
// An empty group means "always true" — quietly widening the query to
|
|
391
|
+
// everything.
|
|
392
|
+
(0, types_1.failSemanticValidation)(p, 'BAD_SHAPE', `'${cond.type}' needs a non-empty conditions array`);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
if (cond.type === 'and') {
|
|
396
|
+
checkConditions(cond.conditions, ctx, depth + 1, budget, p);
|
|
397
|
+
}
|
|
398
|
+
else if (cond.type === 'or') {
|
|
399
|
+
cond.conditions.forEach((c, j) => {
|
|
400
|
+
const bp = `${p}[${j}]`;
|
|
401
|
+
// Or-branches bypass the top of this walk, so its object guard must
|
|
402
|
+
// run here too — a null branch is a validation issue, not a TypeError
|
|
403
|
+
// out of the property check.
|
|
404
|
+
if (!c || typeof c !== 'object')
|
|
405
|
+
(0, types_1.failSemanticValidation)(bp, 'BAD_SHAPE', 'condition must be an object');
|
|
406
|
+
if (c.type === 'and' || c.type === 'or') {
|
|
407
|
+
// The recursive walk counts the group itself against the budget —
|
|
408
|
+
// counting it here as well double-charged every nested group.
|
|
409
|
+
checkConditions([c], ctx, depth + 1, budget, bp);
|
|
410
|
+
}
|
|
411
|
+
else {
|
|
412
|
+
// Leaves never pass through the walk above, so they are counted
|
|
413
|
+
// here. Uncounted branches were a stored query that a 60-byte GET
|
|
414
|
+
// could replay as tens of thousands of regex arms over the whole
|
|
415
|
+
// collection.
|
|
416
|
+
if (++budget.n > LIMITS.maxConditions) {
|
|
417
|
+
(0, types_1.failSemanticValidation)(p, 'TOO_MANY', `Query exceeds maximum of ${LIMITS.maxConditions} conditions`);
|
|
418
|
+
}
|
|
419
|
+
checkLeaf(c, ctx, bp);
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
checkLeaf(cond, ctx, p);
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
// ---------------------------------------------------------------------------
|
|
429
|
+
// Entry points
|
|
430
|
+
// ---------------------------------------------------------------------------
|
|
431
|
+
/**
|
|
432
|
+
* Assert a query is valid, throwing `SemanticQueryValidationError` on the
|
|
433
|
+
* first problem. This is the gate: a back-end may assume anything that passed
|
|
434
|
+
* through it is safe to execute.
|
|
435
|
+
*/
|
|
436
|
+
function assertSemanticQuery(semanticQuery, catalogue, opts = {}) {
|
|
437
|
+
var _a, _b;
|
|
438
|
+
const ctx = {
|
|
439
|
+
catalogue,
|
|
440
|
+
now: (_a = opts.now) !== null && _a !== void 0 ? _a : new Date(),
|
|
441
|
+
tz: (_b = opts.timeZone) !== null && _b !== void 0 ? _b : 'UTC',
|
|
442
|
+
};
|
|
443
|
+
if (!semanticQuery || !Array.isArray(semanticQuery.conditions)) {
|
|
444
|
+
(0, types_1.failSemanticValidation)('conditions', 'BAD_SHAPE', 'semanticQuery.conditions must be an array');
|
|
445
|
+
}
|
|
446
|
+
// The closed vocabulary applies to the ENVELOPE too. Without this a top-level
|
|
447
|
+
// `{conditions:[…], negate:true}` passes cleanly — the original
|
|
448
|
+
// invented-property failure, one level up from the conditions it guards.
|
|
449
|
+
const envelopeExtra = Object.keys(semanticQuery).filter((k) => k !== 'version' && k !== 'conditions');
|
|
450
|
+
if (envelopeExtra.length) {
|
|
451
|
+
(0, types_1.failSemanticValidation)('', 'UNKNOWN_PROPERTY', `A semantic query has only 'version' and 'conditions' — got ${envelopeExtra
|
|
452
|
+
.map((k) => `'${k}'`)
|
|
453
|
+
.join(', ')}`);
|
|
454
|
+
}
|
|
455
|
+
if (semanticQuery.version !== undefined &&
|
|
456
|
+
semanticQuery.version !== contract_1.SEMANTIC_QUERY_VERSION) {
|
|
457
|
+
(0, types_1.failSemanticValidation)('version', 'BAD_VERSION', `Unsupported semantic query version ${semanticQuery.version} ` +
|
|
458
|
+
`(this build understands version ${contract_1.SEMANTIC_QUERY_VERSION})`);
|
|
459
|
+
}
|
|
460
|
+
checkConditions(semanticQuery.conditions, ctx, 1, { n: 0 }, 'conditions');
|
|
461
|
+
}
|
|
462
|
+
exports.assertSemanticQuery = assertSemanticQuery;
|
|
463
|
+
/** Validate without throwing. Empty array = valid. */
|
|
464
|
+
function validateSemanticQuery(semanticQuery, catalogue, opts = {}) {
|
|
465
|
+
try {
|
|
466
|
+
assertSemanticQuery(semanticQuery, catalogue, opts);
|
|
467
|
+
return [];
|
|
468
|
+
}
|
|
469
|
+
catch (e) {
|
|
470
|
+
if (e instanceof types_1.SemanticQueryValidationError)
|
|
471
|
+
return e.issues;
|
|
472
|
+
throw e;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
exports.validateSemanticQuery = validateSemanticQuery;
|
|
476
|
+
/** True when any condition touches a custom field — both back-ends need to know. */
|
|
477
|
+
function queryUsesCustomFields(semanticQuery) {
|
|
478
|
+
var _a;
|
|
479
|
+
const walk = (conds) => conds.some((c) => {
|
|
480
|
+
var _a;
|
|
481
|
+
return (c === null || c === void 0 ? void 0 : c.type) === 'customField' ||
|
|
482
|
+
(((c === null || c === void 0 ? void 0 : c.type) === 'and' || (c === null || c === void 0 ? void 0 : c.type) === 'or') && walk((_a = c.conditions) !== null && _a !== void 0 ? _a : []));
|
|
483
|
+
});
|
|
484
|
+
return walk((_a = semanticQuery === null || semanticQuery === void 0 ? void 0 : semanticQuery.conditions) !== null && _a !== void 0 ? _a : []);
|
|
485
|
+
}
|
|
486
|
+
exports.queryUsesCustomFields = queryUsesCustomFields;
|
|
487
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@spotto/semantic-query",
|
|
3
|
+
"version": "1.0.70-alpha.18",
|
|
4
|
+
"description": "The Spotto semantic query language — one shared statement of what a query MEANS (validation, resolution, evaluation, dates), consumed by both the API and the client. Mongo emission deliberately stays server-side.",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist/**/*"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "shx rm -rf dist && tsc --project tsconfig.json",
|
|
12
|
+
"clean": "shx rm -rf node_modules dist",
|
|
13
|
+
"test": "jest -w 1"
|
|
14
|
+
},
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@spotto/contract": "^1.0.70-alpha.18",
|
|
20
|
+
"dayjs": "^1.11.1"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/jest": "^28.1.1",
|
|
24
|
+
"jest": "^28.0.2",
|
|
25
|
+
"shx": "^0.3.4",
|
|
26
|
+
"ts-jest": "^28.0.1"
|
|
27
|
+
},
|
|
28
|
+
"gitHead": "efd838e345380e064fc8963773d2a72e4fc0f293"
|
|
29
|
+
}
|