@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.
@@ -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
+ }