@webda/ql 4.0.0-beta.5 → 4.0.0-beta.6

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.
Files changed (55) hide show
  1. package/README.md +68 -27
  2. package/lib/WebdaQLLexer.d.ts +44 -30
  3. package/lib/WebdaQLLexer.d.ts.map +1 -1
  4. package/lib/WebdaQLLexer.js +257 -152
  5. package/lib/WebdaQLLexer.js.map +1 -1
  6. package/lib/WebdaQLParserLexer.d.ts +44 -30
  7. package/lib/WebdaQLParserLexer.d.ts.map +1 -1
  8. package/lib/WebdaQLParserLexer.js +257 -152
  9. package/lib/WebdaQLParserLexer.js.map +1 -1
  10. package/lib/WebdaQLParserListener.d.ts +203 -30
  11. package/lib/WebdaQLParserListener.d.ts.map +1 -1
  12. package/lib/WebdaQLParserParser.d.ts +242 -44
  13. package/lib/WebdaQLParserParser.d.ts.map +1 -1
  14. package/lib/WebdaQLParserParser.js +2054 -715
  15. package/lib/WebdaQLParserParser.js.map +1 -1
  16. package/lib/WebdaQLParserVisitor.d.ts +126 -17
  17. package/lib/WebdaQLParserVisitor.d.ts.map +1 -1
  18. package/lib/aggregation-query.d.ts +95 -0
  19. package/lib/aggregation-query.d.ts.map +1 -0
  20. package/lib/aggregation-query.js +104 -0
  21. package/lib/aggregation-query.js.map +1 -0
  22. package/lib/aggregation-select.spec.d.ts +2 -0
  23. package/lib/aggregation-select.spec.d.ts.map +1 -0
  24. package/lib/aggregation-select.spec.js +164 -0
  25. package/lib/aggregation-select.spec.js.map +1 -0
  26. package/lib/aggregation.d.ts +97 -0
  27. package/lib/aggregation.d.ts.map +1 -0
  28. package/lib/aggregation.js +241 -0
  29. package/lib/aggregation.js.map +1 -0
  30. package/lib/aggregation.spec.d.ts +2 -0
  31. package/lib/aggregation.spec.d.ts.map +1 -0
  32. package/lib/aggregation.spec.js +360 -0
  33. package/lib/aggregation.spec.js.map +1 -0
  34. package/lib/bind.d.ts.map +1 -1
  35. package/lib/bind.js +29 -0
  36. package/lib/bind.js.map +1 -1
  37. package/lib/index.d.ts +1 -0
  38. package/lib/index.d.ts.map +1 -1
  39. package/lib/index.js +1 -0
  40. package/lib/index.js.map +1 -1
  41. package/lib/query.d.ts +162 -8
  42. package/lib/query.d.ts.map +1 -1
  43. package/lib/query.js +489 -45
  44. package/lib/query.js.map +1 -1
  45. package/lib/query.spec.js +6 -4
  46. package/lib/query.spec.js.map +1 -1
  47. package/lib/statements.spec.d.ts +2 -0
  48. package/lib/statements.spec.d.ts.map +1 -0
  49. package/lib/statements.spec.js +422 -0
  50. package/lib/statements.spec.js.map +1 -0
  51. package/lib/webdaql-string.d.ts +9 -0
  52. package/lib/webdaql-string.d.ts.map +1 -1
  53. package/lib/webdaql-string.js +9 -8
  54. package/lib/webdaql-string.js.map +1 -1
  55. package/package.json +2 -2
@@ -0,0 +1,422 @@
1
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
2
+ var useValue = arguments.length > 2;
3
+ for (var i = 0; i < initializers.length; i++) {
4
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
5
+ }
6
+ return useValue ? value : void 0;
7
+ };
8
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
9
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
10
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
11
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
12
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
13
+ var _, done = false;
14
+ for (var i = decorators.length - 1; i >= 0; i--) {
15
+ var context = {};
16
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
17
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
18
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
19
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
20
+ if (kind === "accessor") {
21
+ if (result === void 0) continue;
22
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
23
+ if (_ = accept(result.get)) descriptor.get = _;
24
+ if (_ = accept(result.set)) descriptor.set = _;
25
+ if (_ = accept(result.init)) initializers.unshift(_);
26
+ }
27
+ else if (_ = accept(result)) {
28
+ if (kind === "field") initializers.unshift(_);
29
+ else descriptor[key] = _;
30
+ }
31
+ }
32
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
33
+ done = true;
34
+ };
35
+ import { suite, test } from "@webda/test";
36
+ import * as assert from "assert";
37
+ import * as WebdaQL from "./query.js";
38
+ import { bind } from "./bind.js";
39
+ import { WebdaQLError } from "./webdaql-string.js";
40
+ /**
41
+ * Parse a query, print it and parse it back: both parses must describe the same query
42
+ * @param query - the query
43
+ * @returns the printed form
44
+ */
45
+ function roundTrip(query) {
46
+ const first = WebdaQL.parse(query);
47
+ const printed = first.toString();
48
+ const second = WebdaQL.parse(printed);
49
+ for (const key of ["type", "fields", "assignments", "limit", "continuationToken", "orderBy"]) {
50
+ assert.deepStrictEqual(second[key], first[key], `${key} of ${query} => ${printed}`);
51
+ }
52
+ assert.strictEqual(second.filter.toString(), first.filter.toString(), `filter of ${query} => ${printed}`);
53
+ assert.strictEqual(second.toString(), printed, `stable print of ${query}`);
54
+ // The validator prints the same canonical form
55
+ assert.strictEqual(new WebdaQL.QueryValidator(query).toString(), printed);
56
+ return printed;
57
+ }
58
+ let StatementsTest = (() => {
59
+ let _classDecorators = [suite];
60
+ let _classDescriptor;
61
+ let _classExtraInitializers = [];
62
+ let _classThis;
63
+ let _instanceExtraInitializers = [];
64
+ let _deleteStatement_decorators;
65
+ let _updateStatement_decorators;
66
+ let _selectStatement_decorators;
67
+ let _plainFilterIsImplicitSelect_decorators;
68
+ let _keywordsAreUppercaseOnly_decorators;
69
+ let _lowercaseFieldsAreNotReserved_decorators;
70
+ let _toStringRoundTrips_decorators;
71
+ let _prependConditionOnStatements_decorators;
72
+ let _allowedFields_decorators;
73
+ let _assertFilterQuery_decorators;
74
+ let _parametersInStatements_decorators;
75
+ let _limitZeroIsKept_decorators;
76
+ let _normalizeQueryRejectsForgedObjects_decorators;
77
+ let _normalizeQueryReadsEachPartOnce_decorators;
78
+ var StatementsTest = class {
79
+ static { _classThis = this; }
80
+ static {
81
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
82
+ _deleteStatement_decorators = [test];
83
+ _updateStatement_decorators = [test];
84
+ _selectStatement_decorators = [test];
85
+ _plainFilterIsImplicitSelect_decorators = [test];
86
+ _keywordsAreUppercaseOnly_decorators = [test];
87
+ _lowercaseFieldsAreNotReserved_decorators = [test];
88
+ _toStringRoundTrips_decorators = [test];
89
+ _prependConditionOnStatements_decorators = [test];
90
+ _allowedFields_decorators = [test];
91
+ _assertFilterQuery_decorators = [test];
92
+ _parametersInStatements_decorators = [test];
93
+ _limitZeroIsKept_decorators = [test];
94
+ _normalizeQueryRejectsForgedObjects_decorators = [test];
95
+ _normalizeQueryReadsEachPartOnce_decorators = [test];
96
+ __esDecorate(this, null, _deleteStatement_decorators, { kind: "method", name: "deleteStatement", static: false, private: false, access: { has: obj => "deleteStatement" in obj, get: obj => obj.deleteStatement }, metadata: _metadata }, null, _instanceExtraInitializers);
97
+ __esDecorate(this, null, _updateStatement_decorators, { kind: "method", name: "updateStatement", static: false, private: false, access: { has: obj => "updateStatement" in obj, get: obj => obj.updateStatement }, metadata: _metadata }, null, _instanceExtraInitializers);
98
+ __esDecorate(this, null, _selectStatement_decorators, { kind: "method", name: "selectStatement", static: false, private: false, access: { has: obj => "selectStatement" in obj, get: obj => obj.selectStatement }, metadata: _metadata }, null, _instanceExtraInitializers);
99
+ __esDecorate(this, null, _plainFilterIsImplicitSelect_decorators, { kind: "method", name: "plainFilterIsImplicitSelect", static: false, private: false, access: { has: obj => "plainFilterIsImplicitSelect" in obj, get: obj => obj.plainFilterIsImplicitSelect }, metadata: _metadata }, null, _instanceExtraInitializers);
100
+ __esDecorate(this, null, _keywordsAreUppercaseOnly_decorators, { kind: "method", name: "keywordsAreUppercaseOnly", static: false, private: false, access: { has: obj => "keywordsAreUppercaseOnly" in obj, get: obj => obj.keywordsAreUppercaseOnly }, metadata: _metadata }, null, _instanceExtraInitializers);
101
+ __esDecorate(this, null, _lowercaseFieldsAreNotReserved_decorators, { kind: "method", name: "lowercaseFieldsAreNotReserved", static: false, private: false, access: { has: obj => "lowercaseFieldsAreNotReserved" in obj, get: obj => obj.lowercaseFieldsAreNotReserved }, metadata: _metadata }, null, _instanceExtraInitializers);
102
+ __esDecorate(this, null, _toStringRoundTrips_decorators, { kind: "method", name: "toStringRoundTrips", static: false, private: false, access: { has: obj => "toStringRoundTrips" in obj, get: obj => obj.toStringRoundTrips }, metadata: _metadata }, null, _instanceExtraInitializers);
103
+ __esDecorate(this, null, _prependConditionOnStatements_decorators, { kind: "method", name: "prependConditionOnStatements", static: false, private: false, access: { has: obj => "prependConditionOnStatements" in obj, get: obj => obj.prependConditionOnStatements }, metadata: _metadata }, null, _instanceExtraInitializers);
104
+ __esDecorate(this, null, _allowedFields_decorators, { kind: "method", name: "allowedFields", static: false, private: false, access: { has: obj => "allowedFields" in obj, get: obj => obj.allowedFields }, metadata: _metadata }, null, _instanceExtraInitializers);
105
+ __esDecorate(this, null, _assertFilterQuery_decorators, { kind: "method", name: "assertFilterQuery", static: false, private: false, access: { has: obj => "assertFilterQuery" in obj, get: obj => obj.assertFilterQuery }, metadata: _metadata }, null, _instanceExtraInitializers);
106
+ __esDecorate(this, null, _parametersInStatements_decorators, { kind: "method", name: "parametersInStatements", static: false, private: false, access: { has: obj => "parametersInStatements" in obj, get: obj => obj.parametersInStatements }, metadata: _metadata }, null, _instanceExtraInitializers);
107
+ __esDecorate(this, null, _limitZeroIsKept_decorators, { kind: "method", name: "limitZeroIsKept", static: false, private: false, access: { has: obj => "limitZeroIsKept" in obj, get: obj => obj.limitZeroIsKept }, metadata: _metadata }, null, _instanceExtraInitializers);
108
+ __esDecorate(this, null, _normalizeQueryRejectsForgedObjects_decorators, { kind: "method", name: "normalizeQueryRejectsForgedObjects", static: false, private: false, access: { has: obj => "normalizeQueryRejectsForgedObjects" in obj, get: obj => obj.normalizeQueryRejectsForgedObjects }, metadata: _metadata }, null, _instanceExtraInitializers);
109
+ __esDecorate(this, null, _normalizeQueryReadsEachPartOnce_decorators, { kind: "method", name: "normalizeQueryReadsEachPartOnce", static: false, private: false, access: { has: obj => "normalizeQueryReadsEachPartOnce" in obj, get: obj => obj.normalizeQueryReadsEachPartOnce }, metadata: _metadata }, null, _instanceExtraInitializers);
110
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
111
+ StatementsTest = _classThis = _classDescriptor.value;
112
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
113
+ __runInitializers(_classThis, _classExtraInitializers);
114
+ }
115
+ deleteStatement() {
116
+ const q1 = WebdaQL.parse("DELETE WHERE status = 'inactive'");
117
+ assert.strictEqual(q1.type, "DELETE");
118
+ assert.ok(q1.filter.eval({ status: "inactive" }));
119
+ assert.ok(!q1.filter.eval({ status: "active" }));
120
+ assert.strictEqual(q1.fields, undefined);
121
+ assert.strictEqual(q1.assignments, undefined);
122
+ const q2 = WebdaQL.parse("DELETE WHERE age < 18 AND status = 'pending'");
123
+ assert.ok(q2.filter.eval({ age: 10, status: "pending" }));
124
+ assert.ok(!q2.filter.eval({ age: 20, status: "pending" }));
125
+ const q3 = WebdaQL.parse("DELETE WHERE status = 'old' LIMIT 100");
126
+ assert.strictEqual(q3.limit, 100);
127
+ // Without WHERE: every object
128
+ const q4 = WebdaQL.parse("DELETE");
129
+ assert.strictEqual(q4.type, "DELETE");
130
+ assert.ok(q4.filter.eval({}));
131
+ // DELETE takes no ORDER BY / OFFSET, and WHERE needs a condition
132
+ for (const invalid of ["DELETE ORDER BY a", "DELETE WHERE a = 1 OFFSET 'x'", "DELETE WHERE", "DELETE a = 1"]) {
133
+ assert.throws(() => WebdaQL.parse(invalid), SyntaxError, invalid);
134
+ }
135
+ }
136
+ updateStatement() {
137
+ const q1 = WebdaQL.parse("UPDATE SET status = 'active' WHERE name = 'John'");
138
+ assert.strictEqual(q1.type, "UPDATE");
139
+ assert.ok(q1.filter.eval({ name: "John" }));
140
+ assert.ok(!q1.filter.eval({ name: "Jane" }));
141
+ assert.deepStrictEqual(q1.assignments, [{ field: "status", value: "active" }]);
142
+ assert.strictEqual(q1.fields, undefined);
143
+ const q2 = WebdaQL.parse("UPDATE SET status = 'active', age = 30, ratio = -1.5 WHERE name = 'John'");
144
+ assert.deepStrictEqual(q2.assignments, [
145
+ { field: "status", value: "active" },
146
+ { field: "age", value: 30 },
147
+ { field: "ratio", value: -1.5 }
148
+ ]);
149
+ // Dotted paths, booleans
150
+ const q3 = WebdaQL.parse("UPDATE SET profile.verified = TRUE WHERE id = 1");
151
+ assert.deepStrictEqual(q3.assignments, [{ field: "profile.verified", value: true }]);
152
+ const q4 = WebdaQL.parse("UPDATE SET status = 'archived' WHERE active = FALSE LIMIT 50");
153
+ assert.strictEqual(q4.limit, 50);
154
+ // Without WHERE
155
+ const q5 = WebdaQL.parse("UPDATE SET a = 1");
156
+ assert.ok(q5.filter.eval({}));
157
+ for (const invalid of [
158
+ "UPDATE a = 1",
159
+ "UPDATE SET",
160
+ "UPDATE SET a > 1",
161
+ "UPDATE SET a = 1 ORDER BY a",
162
+ "UPDATE SET a = 1 OFFSET 'x'",
163
+ "UPDATE SET a = b"
164
+ ]) {
165
+ assert.throws(() => WebdaQL.parse(invalid), SyntaxError, invalid);
166
+ }
167
+ }
168
+ selectStatement() {
169
+ const q1 = WebdaQL.parse("SELECT name, age WHERE status = 'active'");
170
+ assert.strictEqual(q1.type, "SELECT");
171
+ assert.deepStrictEqual(q1.fields, ["name", "age"]);
172
+ assert.ok(q1.filter.eval({ status: "active" }));
173
+ const q2 = WebdaQL.parse("SELECT name, profile.email WHERE status = 'active'");
174
+ assert.deepStrictEqual(q2.fields, ["name", "profile.email"]);
175
+ const q3 = WebdaQL.parse("SELECT name, age WHERE status = 'active' ORDER BY name DESC LIMIT 10 OFFSET 'token'");
176
+ assert.deepStrictEqual(q3.fields, ["name", "age"]);
177
+ assert.strictEqual(q3.limit, 10);
178
+ assert.strictEqual(q3.continuationToken, "token");
179
+ assert.deepStrictEqual(q3.orderBy, [{ field: "name", direction: "DESC" }]);
180
+ const q4 = WebdaQL.parse("SELECT name, age");
181
+ assert.deepStrictEqual(q4.fields, ["name", "age"]);
182
+ assert.ok(q4.filter instanceof WebdaQL.AndExpression);
183
+ assert.strictEqual(q4.filter.children.length, 0);
184
+ const q5 = WebdaQL.parse("SELECT name ORDER BY name LIMIT 5");
185
+ assert.strictEqual(q5.limit, 5);
186
+ // SELECT needs a field list; no implicit SELECT of a bare field list
187
+ for (const invalid of ["SELECT", "SELECT WHERE a = 1", "name, age", "name, age WHERE a = 1", "SELECT a,"]) {
188
+ assert.throws(() => WebdaQL.parse(invalid), SyntaxError, invalid);
189
+ }
190
+ }
191
+ plainFilterIsImplicitSelect() {
192
+ for (const query of ["", "status = 'active'", "status = 'active' AND age > 18 ORDER BY name LIMIT 3"]) {
193
+ const q = WebdaQL.parse(query);
194
+ assert.strictEqual(q.type, "SELECT", query);
195
+ assert.strictEqual(q.fields, undefined, query);
196
+ assert.strictEqual(q.assignments, undefined, query);
197
+ }
198
+ }
199
+ keywordsAreUppercaseOnly() {
200
+ for (const invalid of [
201
+ "delete where status = 'x'",
202
+ "Delete WHERE status = 'x'",
203
+ "update set a = 1",
204
+ "UPDATE set a = 1",
205
+ "select a where b = 1",
206
+ "SELECT a where b = 1"
207
+ ]) {
208
+ assert.throws(() => WebdaQL.parse(invalid), SyntaxError, invalid);
209
+ }
210
+ }
211
+ lowercaseFieldsAreNotReserved() {
212
+ const object = { desc: 1, set: 2, update: 3, select: 4, where: 5, delete: 6 };
213
+ for (const field of Object.keys(object)) {
214
+ const q = WebdaQL.parse(`${field} = ${object[field]} ORDER BY ${field} DESC`);
215
+ assert.strictEqual(q.type, "SELECT", field);
216
+ assert.ok(q.filter.eval(object), field);
217
+ assert.ok(!q.filter.eval({ ...object, [field]: 0 }), field);
218
+ assert.deepStrictEqual(q.orderBy, [{ field, direction: "DESC" }]);
219
+ }
220
+ assert.ok(WebdaQL.parse("desc = 1 AND set = 2 AND update = 3 AND select = 4 AND where = 5 AND delete = 6").filter.eval(object));
221
+ // And in statements
222
+ const select = WebdaQL.parse("SELECT where, set WHERE delete = 6");
223
+ assert.deepStrictEqual(select.fields, ["where", "set"]);
224
+ assert.ok(select.filter.eval(object));
225
+ assert.deepStrictEqual(WebdaQL.parse("UPDATE SET select = 1, desc = 2 WHERE update = 3").assignments, [
226
+ { field: "select", value: 1 },
227
+ { field: "desc", value: 2 }
228
+ ]);
229
+ }
230
+ toStringRoundTrips() {
231
+ assert.strictEqual(roundTrip(""), "");
232
+ assert.strictEqual(roundTrip("a = 1 ORDER BY a LIMIT 10 OFFSET 'x'"), 'a = 1 ORDER BY a ASC LIMIT 10 OFFSET "x"');
233
+ assert.strictEqual(roundTrip("DELETE"), "DELETE");
234
+ assert.strictEqual(roundTrip("DELETE LIMIT 2"), "DELETE LIMIT 2");
235
+ assert.strictEqual(roundTrip("DELETE WHERE a = 1 OR (b = 'x' AND c IS NULL) LIMIT 5"), 'DELETE WHERE a = 1 OR ( b = "x" AND c IS NULL ) LIMIT 5');
236
+ assert.strictEqual(roundTrip("UPDATE SET a = 1"), "UPDATE SET a = 1");
237
+ assert.strictEqual(roundTrip("UPDATE SET a = 'it''s', b.c = TRUE, d = -2.5 WHERE e != 'x' LIMIT 3"), 'UPDATE SET a = "it\'s", b.c = TRUE, d = -2.5 WHERE e != "x" LIMIT 3');
238
+ assert.strictEqual(roundTrip("SELECT a"), "SELECT a");
239
+ assert.strictEqual(roundTrip("SELECT a, b.c WHERE d IN [1, 2] ORDER BY a DESC, b ASC LIMIT 4 OFFSET 'tok'"), 'SELECT a, b.c WHERE d IN [1, 2] ORDER BY a DESC, b ASC LIMIT 4 OFFSET "tok"');
240
+ assert.strictEqual(roundTrip("SELECT a ORDER BY a"), "SELECT a ORDER BY a ASC");
241
+ // A mutated parsed query prints its current state
242
+ const q = WebdaQL.parse("SELECT a WHERE b = 1");
243
+ q.limit = 7;
244
+ q.continuationToken = "next";
245
+ assert.strictEqual(q.toString(), 'SELECT a WHERE b = 1 LIMIT 7 OFFSET "next"');
246
+ }
247
+ prependConditionOnStatements() {
248
+ const check = (query, condition, expected) => {
249
+ const merged = WebdaQL.PrependCondition(query, condition);
250
+ assert.strictEqual(merged, expected);
251
+ // Parsable and stable
252
+ assert.strictEqual(WebdaQL.parse(merged).toString(), merged);
253
+ };
254
+ check("SELECT a, b WHERE x = 1 ORDER BY a LIMIT 10 OFFSET 't'", "y = 2", 'SELECT a, b WHERE x = 1 AND y = 2 ORDER BY a ASC LIMIT 10 OFFSET "t"');
255
+ check("SELECT a ORDER BY a", "y = 2", "SELECT a WHERE y = 2 ORDER BY a ASC");
256
+ check("DELETE LIMIT 5", "y = 2", "DELETE WHERE y = 2 LIMIT 5");
257
+ check("UPDATE SET a = 1 WHERE x = 1", "y = 2", "UPDATE SET a = 1 WHERE x = 1 AND y = 2");
258
+ // Precedence: both sides keep their grouping
259
+ check("x = 1 OR y = 2", "z = 3 OR w = 4", "( x = 1 OR y = 2 ) AND ( z = 3 OR w = 4 )");
260
+ check("DELETE WHERE x = 1 OR y = 2", "owner = 'me'", 'DELETE WHERE ( x = 1 OR y = 2 ) AND owner = "me"');
261
+ check("SELECT a WHERE x = 1 OR y = 2 LIMIT 3", "owner = 'me' OR public = TRUE", 'SELECT a WHERE ( x = 1 OR y = 2 ) AND ( owner = "me" OR public = TRUE ) LIMIT 3');
262
+ // The merged condition must be a filter: a statement there is refused
263
+ for (const condition of ["DELETE WHERE a = 1", "SELECT a WHERE b = 1", "UPDATE SET a = 1"]) {
264
+ assert.throws(() => WebdaQL.PrependCondition("x = 1", condition), SyntaxError, condition);
265
+ }
266
+ }
267
+ allowedFields() {
268
+ const allowed = ["name", "age", "status", "profile.email", "address"];
269
+ assert.deepStrictEqual(WebdaQL.parse("SELECT name, age WHERE status = 'active'", allowed).fields, ["name", "age"]);
270
+ assert.throws(() => WebdaQL.parse("SELECT name, unknown WHERE status = 'active'", allowed), /Unknown field "unknown"/);
271
+ assert.strictEqual(WebdaQL.parse("UPDATE SET status = 'active' WHERE name = 'John'", allowed).type, "UPDATE");
272
+ assert.throws(() => WebdaQL.parse("UPDATE SET invalid = 'active' WHERE name = 'John'", allowed), /Unknown assignment field "invalid"/);
273
+ // Dotted paths: listed as such, or nested in a listed field
274
+ assert.deepStrictEqual(WebdaQL.parse("SELECT profile.email, address.city", allowed).fields, [
275
+ "profile.email",
276
+ "address.city"
277
+ ]);
278
+ assert.throws(() => WebdaQL.parse("SELECT profile.ssn", allowed), /Unknown field "profile.ssn"/);
279
+ assert.throws(() => WebdaQL.parse("UPDATE SET profile.secret = 'x'", allowed), /profile.secret/);
280
+ // A prefix is not a parent
281
+ assert.throws(() => WebdaQL.parse("SELECT nam", allowed), /Unknown field "nam"/);
282
+ // DELETE and plain filters have no field list
283
+ assert.strictEqual(WebdaQL.parse("DELETE WHERE status = 'old'", allowed).type, "DELETE");
284
+ assert.strictEqual(WebdaQL.parse("status = 'active'", allowed).type, "SELECT");
285
+ // Standalone
286
+ const parsed = WebdaQL.parse("SELECT name, age WHERE status = 'active'");
287
+ WebdaQL.validateQueryFields(parsed, allowed);
288
+ assert.throws(() => WebdaQL.validateQueryFields(parsed, ["status"]), /Unknown field "name"/);
289
+ assert.throws(() => WebdaQL.parse("SELECT name", []), /Unknown field "name"/);
290
+ // Errors are syntax errors (a 400 at the API)
291
+ assert.throws(() => WebdaQL.parse("SELECT nope", allowed), SyntaxError);
292
+ }
293
+ assertFilterQuery() {
294
+ for (const query of ["", "a = 1", "a = 1 ORDER BY a LIMIT 2 OFFSET 'x'"]) {
295
+ WebdaQL.assertFilterQuery(WebdaQL.parse(query));
296
+ }
297
+ // Hand-built queries without a type are filters
298
+ WebdaQL.assertFilterQuery({ filter: new WebdaQL.AndExpression([]) });
299
+ for (const query of ["DELETE", "DELETE WHERE a = 1", "UPDATE SET a = 1", "SELECT a", "SELECT a WHERE b = 1"]) {
300
+ assert.throws(() => WebdaQL.assertFilterQuery(WebdaQL.parse(query)), WebdaQLError, query);
301
+ }
302
+ assert.throws(() => WebdaQL.assertFilterQuery({ type: "DELETE" }), /DELETE/);
303
+ }
304
+ parametersInStatements() {
305
+ assert.strictEqual(bind("DELETE WHERE a = ? LIMIT ?", ["x", 5]), "DELETE WHERE a = 'x' LIMIT 5");
306
+ assert.strictEqual(bind("UPDATE SET a = :a, b.c = :b WHERE d IN :d LIMIT :l", { a: "it's", b: true, d: [1, 2], l: 3 }), "UPDATE SET a = 'it''s', b.c = TRUE WHERE d IN [1, 2] LIMIT 3");
307
+ assert.strictEqual(bind("SELECT a, b WHERE c = ? ORDER BY a LIMIT ? OFFSET ?", [1.5, 10, "tok"]), "SELECT a, b WHERE c = 1.5 ORDER BY a LIMIT 10 OFFSET 'tok'");
308
+ const update = WebdaQL.parse(bind("UPDATE SET a = ?, b = ? WHERE c = ?", ["x", -2, null]));
309
+ assert.deepStrictEqual(update.assignments, [
310
+ { field: "a", value: "x" },
311
+ { field: "b", value: -2 }
312
+ ]);
313
+ assert.ok(update.filter.eval({}));
314
+ // A null cannot be assigned: SET has no NULL literal
315
+ assert.throws(() => bind("UPDATE SET a = ? WHERE b = ?", [null, 1]), /cannot be assigned/);
316
+ assert.throws(() => bind("UPDATE SET a = :a", { a: undefined }), /cannot be assigned/);
317
+ // Placeholders never become a field or a keyword
318
+ for (const query of ["SELECT ? WHERE a = 1", "UPDATE SET ? = 1", "DELETE WHERE ? = 1", "? WHERE a = 1"]) {
319
+ assert.throws(() => bind(query, ["x"]), SyntaxError, query);
320
+ }
321
+ // Unbound parameters are refused at parse time, in statements too
322
+ for (const query of ["UPDATE SET a = ?", "DELETE LIMIT ?", "SELECT a WHERE b = :b"]) {
323
+ assert.throws(() => WebdaQL.parse(query), WebdaQLError, query);
324
+ }
325
+ }
326
+ limitZeroIsKept() {
327
+ assert.strictEqual(roundTrip("DELETE LIMIT 0"), "DELETE LIMIT 0");
328
+ assert.strictEqual(roundTrip("UPDATE SET a = 1 WHERE b = 2 LIMIT 0"), "UPDATE SET a = 1 WHERE b = 2 LIMIT 0");
329
+ assert.strictEqual(roundTrip("SELECT a LIMIT 0 OFFSET 't'"), 'SELECT a LIMIT 0 OFFSET "t"');
330
+ assert.strictEqual(roundTrip("a = 1 LIMIT 0"), "a = 1 LIMIT 0");
331
+ assert.strictEqual(WebdaQL.PrependCondition("DELETE LIMIT 0", "name = 'x'"), 'DELETE WHERE name = "x" LIMIT 0');
332
+ assert.strictEqual(WebdaQL.parse(WebdaQL.PrependCondition("DELETE LIMIT 0", "name = 'x'")).limit, 0);
333
+ // A LIMIT 0 condition overrides the query LIMIT, like any other LIMIT
334
+ assert.strictEqual(WebdaQL.PrependCondition("DELETE LIMIT 5", "LIMIT 0"), "DELETE LIMIT 0");
335
+ }
336
+ normalizeQueryRejectsForgedObjects() {
337
+ // A well-formed object goes back through the grammar unchanged
338
+ const ok = WebdaQL.normalizeQuery(WebdaQL.parse("DELETE WHERE a.b = 'x' AND c IN [1, 2] LIMIT 3"));
339
+ assert.strictEqual(ok.toString(), 'DELETE WHERE a.b = "x" AND c IN [1, 2] LIMIT 3');
340
+ assert.ok(ok.filter instanceof WebdaQL.AndExpression);
341
+ const forge = (query, change) => {
342
+ const q = WebdaQL.parse(query);
343
+ change(q);
344
+ return () => WebdaQL.normalizeQuery(q);
345
+ };
346
+ const invalid = [
347
+ // SQL break-out through a field path
348
+ ["DELETE WHERE uuid = 'nope'", q => (q.filter.attribute = ["x}' IS NULL OR TRUE OR data#>>'{y"])],
349
+ // Mongo operators
350
+ ["DELETE WHERE uuid = 'nope'", q => (q.filter.attribute = ["$where"])],
351
+ ["DELETE WHERE uuid = 'nope'", q => (q.filter.value = { $ne: "nope" })],
352
+ ["DELETE WHERE uuid = 'nope'", q => (q.filter.attribute = ["a", "$"])],
353
+ ["DELETE WHERE uuid IN ['a']", q => (q.filter.value = [{ $gt: "" }])],
354
+ ["DELETE WHERE uuid = 'nope'", q => (q.filter.attribute = ["a", ""])],
355
+ ["DELETE WHERE uuid = 'nope'", q => (q.filter.value = Number.NaN)],
356
+ ["DELETE WHERE uuid = 'nope'", q => (q.filter.operator = "= 1 OR")],
357
+ // A foreign expression whose toString is chosen by the caller
358
+ ["DELETE", q => (q.filter = { eval: () => true, toString: () => "1 = 1; DROP TABLE x" })],
359
+ ["UPDATE SET a = 1", q => (q.assignments = [{ field: "a'}", value: 1 }])],
360
+ ["UPDATE SET a = 1", q => (q.assignments = [{ field: "a", value: { $set: 1 } }])],
361
+ ["UPDATE SET a = 1", q => (q.assignments = [{ field: "a", value: null }])],
362
+ ["SELECT a", q => (q.fields = ["a; DROP"])],
363
+ ["a = 1 ORDER BY a", q => (q.orderBy = [{ field: "a'", direction: "ASC" }])],
364
+ ["a = 1 ORDER BY a", q => (q.orderBy = [{ field: "a", direction: "ASC; DROP" }])],
365
+ ["DELETE LIMIT 1", q => (q.limit = Number.NaN)],
366
+ ["DELETE LIMIT 1", q => (q.limit = -1)],
367
+ ["DELETE LIMIT 1", q => (q.limit = 1.5)],
368
+ ["DELETE LIMIT 1", q => (q.limit = "1; DROP")],
369
+ ["a = 1", q => (q.continuationToken = 12)],
370
+ ["a = 1", q => (q.type = "DROP")]
371
+ ];
372
+ for (const [query, change] of invalid) {
373
+ assert.throws(forge(query, change), WebdaQLError, `${query} ${change}`);
374
+ }
375
+ }
376
+ normalizeQueryReadsEachPartOnce() {
377
+ // A Proxy answering one thing to the check and another to the print
378
+ const twoFaced = (safe, hostile) => {
379
+ let reads = 0;
380
+ return new Proxy(safe, {
381
+ get: (target, prop, receiver) => {
382
+ if (prop === "join" || prop === "map") {
383
+ reads++;
384
+ }
385
+ return Reflect.get(reads > 0 ? hostile : target, prop, receiver);
386
+ }
387
+ });
388
+ };
389
+ const q = WebdaQL.parse("DELETE WHERE name = 'nope'");
390
+ q.filter.attribute = twoFaced(["name"], ["uuid IS NOT NULL OR name"]);
391
+ const normalized = (() => {
392
+ try {
393
+ return WebdaQL.normalizeQuery(q);
394
+ }
395
+ catch (err) {
396
+ return err;
397
+ }
398
+ })();
399
+ if (!(normalized instanceof WebdaQLError)) {
400
+ assert.strictEqual(normalized.toString(), 'DELETE WHERE name = "nope"');
401
+ }
402
+ // Arrays of a query object are copied before they are checked
403
+ const fields = WebdaQL.parse("SELECT a");
404
+ fields.fields = twoFaced(["a"], ["a, b WHERE TRUE"]);
405
+ assert.strictEqual(WebdaQL.normalizeQuery(fields).toString(), "SELECT a");
406
+ const set = WebdaQL.parse("UPDATE SET a = 1");
407
+ set.assignments = twoFaced([{ field: "a", value: 1 }], [
408
+ { field: "a", value: 1 },
409
+ { field: "uuid", value: "x" }
410
+ ]);
411
+ assert.strictEqual(WebdaQL.normalizeQuery(set).toString(), "UPDATE SET a = 1");
412
+ const values = WebdaQL.parse("DELETE WHERE a IN [1]");
413
+ values.filter.value = twoFaced([1], [1, 2]);
414
+ assert.strictEqual(WebdaQL.normalizeQuery(values).toString(), "DELETE WHERE a IN [1]");
415
+ }
416
+ constructor() {
417
+ __runInitializers(this, _instanceExtraInitializers);
418
+ }
419
+ };
420
+ return StatementsTest = _classThis;
421
+ })();
422
+ //# sourceMappingURL=statements.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statements.spec.js","sourceRoot":"","sources":["../src/statements.spec.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,15 @@
13
13
  export type WebdaQLString<T = unknown> = string & {
14
14
  readonly __webdaQL?: T;
15
15
  };
16
+ /**
17
+ * Marker brand for WebdaQL statement strings (`DELETE ...`, `UPDATE SET ...`), as taken by
18
+ * `Repository.deleteMany` / `updateMany`. `@webda/content-mapper` checks their fields against `T` and,
19
+ * unlike {@link WebdaQLString}, does not flag them as statements where a filter query is expected.
20
+ */
21
+ export type WebdaQLStatement<T = unknown> = string & {
22
+ readonly __webdaQL?: T;
23
+ readonly __webdaQLStatement?: true;
24
+ };
16
25
  /**
17
26
  * Thrown by `escape` when an interpolated value is not representable as a
18
27
  * WebdaQL literal (object, function, symbol, NaN, Infinity, a number needing an
@@ -1 +1 @@
1
- {"version":3,"file":"webdaql-string.d.ts","sourceRoot":"","sources":["../src/webdaql-string.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,GAAG,OAAO,IAAI,MAAM,GAAG;IAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;CAAE,CAAC;AAE7E;;;;;GAKG;AACH,qBAAa,YAAa,SAAQ,KAAK;IACrC;;;;OAIG;IACH,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,MAAM,CAAC,CAAC,GAAG,OAAO,EAChC,KAAK,EAAE,oBAAoB,GAAG,SAAS,MAAM,EAAE,EAC/C,MAAM,EAAE,SAAS,OAAO,EAAE,GACzB,aAAa,CAAC,CAAC,CAAC,CAOlB;AA+BD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CA6BlD"}
1
+ {"version":3,"file":"webdaql-string.d.ts","sourceRoot":"","sources":["../src/webdaql-string.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,GAAG,OAAO,IAAI,MAAM,GAAG;IAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;CAAE,CAAC;AAE7E;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,GAAG,OAAO,IAAI,MAAM,GAAG;IAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAEpH;;;;;GAKG;AACH,qBAAa,YAAa,SAAQ,KAAK;IACrC;;;;OAIG;IACH,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,MAAM,CAAC,CAAC,GAAG,OAAO,EAChC,KAAK,EAAE,oBAAoB,GAAG,SAAS,MAAM,EAAE,EAC/C,MAAM,EAAE,SAAS,OAAO,EAAE,GACzB,aAAa,CAAC,CAAC,CAAC,CAOlB;AA+BD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CA6BlD"}
@@ -43,11 +43,6 @@ export function escape(parts, values) {
43
43
  }
44
44
  return out;
45
45
  }
46
- /**
47
- * `=` or `!=` right before an interpolated value, with its surrounding spaces
48
- * (`>=` and `<=` are not equalities)
49
- */
50
- const TRAILING_EQUALITY = /\s*(!=|(?<![<>!])=)\s*$/;
51
46
  /**
52
47
  * Append a `null`/`undefined` value to the query built so far
53
48
  *
@@ -59,11 +54,17 @@ const TRAILING_EQUALITY = /\s*(!=|(?<![<>!])=)\s*$/;
59
54
  * @returns the query with the null comparison
60
55
  */
61
56
  function appendNull(out) {
62
- const match = TRAILING_EQUALITY.exec(out);
63
- if (!match) {
57
+ // `=` or `!=` right before the value (`>=` and `<=` are not equalities); trimEnd keeps this linear
58
+ const head = out.trimEnd();
59
+ const operator = head.endsWith("!=")
60
+ ? "!="
61
+ : head.endsWith("=") && !/[<>!]/.test(head.charAt(head.length - 2))
62
+ ? "="
63
+ : "";
64
+ if (!operator) {
64
65
  throw new WebdaQLError("A null value can only be compared with = or != in a WebdaQL query");
65
66
  }
66
- return `${out.substring(0, match.index)} ${match[1] === "=" ? "IS NULL" : "IS NOT NULL"}`;
67
+ return `${head.slice(0, -operator.length).trimEnd()} ${operator === "=" ? "IS NULL" : "IS NOT NULL"}`;
67
68
  }
68
69
  /**
69
70
  * Numbers WebdaQL can write: an optional minus sign, digits and an optional decimal part
@@ -1 +1 @@
1
- {"version":3,"file":"webdaql-string.js","sourceRoot":"","sources":["../src/webdaql-string.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"webdaql-string.js","sourceRoot":"","sources":["../src/webdaql-string.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webda/ql",
3
- "version": "4.0.0-beta.5",
3
+ "version": "4.0.0-beta.6",
4
4
  "description": "WebdaQL module",
5
5
  "keywords": [
6
6
  "webda"
@@ -28,7 +28,7 @@
28
28
  "typescript": "7.1.0-dev.20260929.1",
29
29
  "vite": "^6.0.0",
30
30
  "vitest": "^4.1.2",
31
- "@webda/test": "^4.0.0-beta.5"
31
+ "@webda/test": "^4.0.0-beta.6"
32
32
  },
33
33
  "files": [
34
34
  "lib"