@jarenjs/json 0.9.2 → 0.34.2
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/ARCHITECTURE.md +86 -13
- package/README.md +248 -23
- package/dist/types/canonical.d.ts +37 -0
- package/dist/types/cow.d.ts +28 -0
- package/dist/types/errors.d.ts +45 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/jslt/errors.d.ts +15 -8
- package/dist/types/jslt/index.d.ts +22 -0
- package/dist/types/jslt/packs/finance.d.ts +119 -0
- package/dist/types/jslt/packs/index.d.ts +310 -0
- package/dist/types/jslt/packs/math.d.ts +159 -0
- package/dist/types/jslt/packs/stats.d.ts +48 -0
- package/dist/types/jslt/registry.d.ts +65 -0
- package/dist/types/jtlt/errors.d.ts +3 -6
- package/dist/types/option-variants.d.ts +29 -0
- package/dist/types/patch.d.ts +214 -0
- package/dist/types/path.d.ts +139 -9
- package/dist/types/pointer.d.ts +100 -9
- package/dist/types/query/compile.d.ts +12 -0
- package/dist/types/query/errors.d.ts +72 -8
- package/dist/types/query/index.d.ts +317 -25
- package/dist/types/query/normalize.d.ts +24 -0
- package/dist/types/query/operators.d.ts +241 -1
- package/dist/types/query/runtime.d.ts +5 -8
- package/dist/types/query/types.d.ts +34 -0
- package/dist/types/segments.d.ts +31 -0
- package/dist/types/write.d.ts +204 -0
- package/dist/types/xquery/parse.d.ts +2 -3
- package/docs/JSLT-FORMAT.md +74 -3
- package/docs/JSLT-PRELUDE.md +1 -1
- package/docs/QUERY-FORMAT.md +695 -33
- package/package.json +18 -4
- package/schemas/geojson.draft-07.schema.json +323 -0
- package/schemas/geojson.jaren.schema.json +863 -0
- package/schemas/geojson.schema.json +172 -0
- package/schemas/jaren-jslt.authoring.schema.json +142 -0
- package/schemas/jaren-jslt.draft-07.schema.json +152 -11
- package/schemas/jaren-jslt.llm-profile.schema.json +782 -0
- package/schemas/jaren-jslt.schema.json +152 -11
- package/schemas/jaren-query.draft-07.schema.json +152 -11
- package/schemas/jaren-query.llm-profile.schema.json +619 -0
- package/schemas/jaren-query.schema.json +82 -15
- package/src/basic.js +1 -1
- package/src/canonical.js +170 -0
- package/src/cow.js +106 -0
- package/src/errors.js +68 -0
- package/src/index.js +3 -0
- package/src/jslt/dispatch.js +178 -28
- package/src/jslt/errors.js +19 -14
- package/src/jslt/index.js +37 -29
- package/src/jslt/packs/finance.js +49 -0
- package/src/jslt/packs/index.js +18 -0
- package/src/jslt/packs/math.js +46 -0
- package/src/jslt/packs/stats.js +65 -0
- package/src/jslt/registry.js +200 -0
- package/src/jslt/stylesheet.js +14 -23
- package/src/jtlt/desugar.js +2 -3
- package/src/jtlt/errors.js +6 -12
- package/src/jtlt/index.js +12 -29
- package/src/jtlt/template.js +9 -18
- package/src/option-variants.js +54 -0
- package/src/patch.js +1052 -0
- package/src/path.js +319 -52
- package/src/pointer.js +225 -44
- package/src/query/compile.js +790 -75
- package/src/query/errors.js +72 -12
- package/src/query/index.js +274 -42
- package/src/query/normalize.js +489 -78
- package/src/query/operators.js +620 -23
- package/src/query/runtime.js +5 -19
- package/src/query/types.js +213 -0
- package/src/segments.js +409 -64
- package/src/write.js +660 -0
- package/src/xquery/parse.js +37 -53
package/src/xquery/parse.js
CHANGED
|
@@ -52,11 +52,15 @@ import {
|
|
|
52
52
|
CC_AT,
|
|
53
53
|
CC_LBRACKET,
|
|
54
54
|
CC_RBRACKET,
|
|
55
|
-
CC_UNDERSCORE,
|
|
56
55
|
CC_PIPE,
|
|
57
56
|
isDigitCode,
|
|
57
|
+
isNameStartCode,
|
|
58
|
+
isNameCharCode,
|
|
58
59
|
} from '@jarenjs/core/scan';
|
|
59
60
|
|
|
61
|
+
import { setObjectMember } from '@jarenjs/core/object';
|
|
62
|
+
import { LabeledSyntaxError } from '../errors.js';
|
|
63
|
+
|
|
60
64
|
const CC_HASH = 0x23;
|
|
61
65
|
const CC_PERCENT = 0x25;
|
|
62
66
|
const CC_PLUS = 0x2B;
|
|
@@ -73,12 +77,9 @@ const hasOwn = Object.hasOwn;
|
|
|
73
77
|
* subset (mirrors JSONPathSyntaxError: `source` and `position` locate the
|
|
74
78
|
* offending token).
|
|
75
79
|
*/
|
|
76
|
-
export class XQuerySyntaxError extends
|
|
80
|
+
export class XQuerySyntaxError extends LabeledSyntaxError {
|
|
77
81
|
constructor(message, source, position) {
|
|
78
|
-
super(
|
|
79
|
-
this.name = 'XQuerySyntaxError';
|
|
80
|
-
this.source = source;
|
|
81
|
-
this.position = position;
|
|
82
|
+
super('XQuerySyntaxError', 'XQuery', message, source, position);
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
|
|
@@ -215,16 +216,6 @@ function emitString(s) {
|
|
|
215
216
|
return s.charCodeAt(0) === CC_DOLLAR ? '$' + s : s;
|
|
216
217
|
}
|
|
217
218
|
|
|
218
|
-
// own-property assignment for emitted objects keyed by user-controlled
|
|
219
|
-
// names: a plain `obj[name] =` would follow the prototype chain for
|
|
220
|
-
// '__proto__' and silently drop the member
|
|
221
|
-
function setMember(obj, name, value) {
|
|
222
|
-
if (name === '__proto__')
|
|
223
|
-
Object.defineProperty(obj, name, { value, enumerable: true, writable: true, configurable: true });
|
|
224
|
-
else
|
|
225
|
-
obj[name] = value;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
219
|
// member names foldable into RFC 9535 dot shorthand; everything else
|
|
229
220
|
// (NCNames with '-', '.', or non-ASCII) uses the bracketed name selector.
|
|
230
221
|
// NCNames can never contain a quote or backslash, so no escaping needed.
|
|
@@ -245,16 +236,9 @@ function isEmptySeqExpr(e) {
|
|
|
245
236
|
|
|
246
237
|
//#region parser
|
|
247
238
|
|
|
248
|
-
function isNameFirstCode(c) {
|
|
249
|
-
return (c >= 0x41 && c <= 0x5A) // A-Z
|
|
250
|
-
|| (c >= 0x61 && c <= 0x7A) // a-z
|
|
251
|
-
|| c === CC_UNDERSCORE
|
|
252
|
-
|| c >= 0x80; // any non-ASCII code unit
|
|
253
|
-
}
|
|
254
|
-
|
|
255
239
|
// XML NameChar, pragmatically: name start, digits, '-' and '.'
|
|
256
|
-
function
|
|
257
|
-
return
|
|
240
|
+
function isXmlNameCharCode(c) {
|
|
241
|
+
return isNameCharCode(c) || c === CC_MINUS || c === CC_DOT;
|
|
258
242
|
}
|
|
259
243
|
|
|
260
244
|
/**
|
|
@@ -320,7 +304,7 @@ export function parseXQuery(source) {
|
|
|
320
304
|
|
|
321
305
|
function parseNCName() {
|
|
322
306
|
const start = pos;
|
|
323
|
-
if (!
|
|
307
|
+
if (!isNameStartCode(cc(pos)))
|
|
324
308
|
fail('expected a name');
|
|
325
309
|
while (pos < len) {
|
|
326
310
|
const c = source.charCodeAt(pos);
|
|
@@ -332,7 +316,7 @@ export function parseXQuery(source) {
|
|
|
332
316
|
pos += 2;
|
|
333
317
|
continue;
|
|
334
318
|
}
|
|
335
|
-
if (!
|
|
319
|
+
if (!isXmlNameCharCode(c))
|
|
336
320
|
break;
|
|
337
321
|
pos++;
|
|
338
322
|
}
|
|
@@ -344,7 +328,7 @@ export function parseXQuery(source) {
|
|
|
344
328
|
function tryKeyword(word) {
|
|
345
329
|
const save = pos;
|
|
346
330
|
skipWS();
|
|
347
|
-
if (
|
|
331
|
+
if (isNameStartCode(cc(pos))) {
|
|
348
332
|
const at = pos;
|
|
349
333
|
if (parseNCName() === word)
|
|
350
334
|
return at;
|
|
@@ -356,7 +340,7 @@ export function parseXQuery(source) {
|
|
|
356
340
|
function expectKeyword(word) {
|
|
357
341
|
skipWS();
|
|
358
342
|
const at = pos;
|
|
359
|
-
if (!
|
|
343
|
+
if (!isNameStartCode(cc(pos)) || parseNCName() !== word)
|
|
360
344
|
fail(`expected '${word}'`, at);
|
|
361
345
|
}
|
|
362
346
|
|
|
@@ -371,7 +355,7 @@ export function parseXQuery(source) {
|
|
|
371
355
|
const name = parseNCName();
|
|
372
356
|
if (name === 'Q' && cc(pos) === CC_LBRACE)
|
|
373
357
|
fail("unsupported construct 'URI-qualified name'", at);
|
|
374
|
-
if (cc(pos) === CC_COLON &&
|
|
358
|
+
if (cc(pos) === CC_COLON && isNameStartCode(cc(pos + 1)))
|
|
375
359
|
fail("unsupported construct 'namespaced variable'", at);
|
|
376
360
|
if (!VAR_NAME_RE.test(name))
|
|
377
361
|
fail(`unsupported variable name '${name}'`, at);
|
|
@@ -446,7 +430,7 @@ export function parseXQuery(source) {
|
|
|
446
430
|
// XQuery A.2.2: a numeric literal must not be followed directly by
|
|
447
431
|
// '.' or a name start character (e.g. `10div 3` is not `10 div 3`)
|
|
448
432
|
const n = cc(pos);
|
|
449
|
-
if (n === CC_DOT ||
|
|
433
|
+
if (n === CC_DOT || isNameStartCode(n))
|
|
450
434
|
fail('a numeric literal must be followed by a delimiter');
|
|
451
435
|
const value = Number(source.slice(start, pos));
|
|
452
436
|
// an overflowing DoubleLiteral is a valid XQuery double (INF) but has
|
|
@@ -481,7 +465,7 @@ export function parseXQuery(source) {
|
|
|
481
465
|
function parseExprSingle() {
|
|
482
466
|
skipWS();
|
|
483
467
|
const at = pos;
|
|
484
|
-
if (
|
|
468
|
+
if (isNameStartCode(cc(pos))) {
|
|
485
469
|
const save = pos;
|
|
486
470
|
const ident = parseNCName();
|
|
487
471
|
skipWS();
|
|
@@ -489,7 +473,7 @@ export function parseXQuery(source) {
|
|
|
489
473
|
if (ident === 'for' || ident === 'let') {
|
|
490
474
|
if (next === CC_DOLLAR)
|
|
491
475
|
return parseFlwor(ident);
|
|
492
|
-
if (ident === 'for' &&
|
|
476
|
+
if (ident === 'for' && isNameStartCode(next)) {
|
|
493
477
|
const save2 = pos;
|
|
494
478
|
const w = parseNCName();
|
|
495
479
|
pos = save2;
|
|
@@ -520,7 +504,7 @@ export function parseXQuery(source) {
|
|
|
520
504
|
for (;;) {
|
|
521
505
|
const save = pos;
|
|
522
506
|
skipWS();
|
|
523
|
-
if (
|
|
507
|
+
if (isNameStartCode(cc(pos)) && parseNCName() === 'or') {
|
|
524
508
|
if (items === null)
|
|
525
509
|
items = [first];
|
|
526
510
|
items.push(parseAnd());
|
|
@@ -537,7 +521,7 @@ export function parseXQuery(source) {
|
|
|
537
521
|
for (;;) {
|
|
538
522
|
const save = pos;
|
|
539
523
|
skipWS();
|
|
540
|
-
if (
|
|
524
|
+
if (isNameStartCode(cc(pos)) && parseNCName() === 'and') {
|
|
541
525
|
if (items === null)
|
|
542
526
|
items = [first];
|
|
543
527
|
items.push(parseComparison());
|
|
@@ -594,7 +578,7 @@ export function parseXQuery(source) {
|
|
|
594
578
|
op = '$gt';
|
|
595
579
|
}
|
|
596
580
|
}
|
|
597
|
-
else if (
|
|
581
|
+
else if (isNameStartCode(c)) {
|
|
598
582
|
const ident = parseNCName();
|
|
599
583
|
if (hasOwn(VALUE_COMPS, ident))
|
|
600
584
|
op = VALUE_COMPS[ident];
|
|
@@ -641,7 +625,7 @@ export function parseXQuery(source) {
|
|
|
641
625
|
const first = parseAdditive();
|
|
642
626
|
const save = pos;
|
|
643
627
|
skipWS();
|
|
644
|
-
if (
|
|
628
|
+
if (isNameStartCode(cc(pos)) && parseNCName() === 'to')
|
|
645
629
|
return { '$range': [first, parseAdditive()] };
|
|
646
630
|
pos = save;
|
|
647
631
|
return first;
|
|
@@ -684,7 +668,7 @@ export function parseXQuery(source) {
|
|
|
684
668
|
expr = { '$mul': [expr, parseUnary()] };
|
|
685
669
|
continue;
|
|
686
670
|
}
|
|
687
|
-
if (
|
|
671
|
+
if (isNameStartCode(c)) {
|
|
688
672
|
const ident = parseNCName();
|
|
689
673
|
if (ident === 'div') {
|
|
690
674
|
expr = { '$div': [expr, parseUnary()] };
|
|
@@ -763,7 +747,7 @@ export function parseXQuery(source) {
|
|
|
763
747
|
}
|
|
764
748
|
if (isDigitCode(c))
|
|
765
749
|
return { index: parseLookupIndex() };
|
|
766
|
-
if (
|
|
750
|
+
if (isNameStartCode(c))
|
|
767
751
|
return { name: parseNCName() };
|
|
768
752
|
if (c === CC_LPAREN)
|
|
769
753
|
fail("unsupported construct 'parenthesized lookup key'");
|
|
@@ -774,7 +758,7 @@ export function parseXQuery(source) {
|
|
|
774
758
|
const at = pos;
|
|
775
759
|
while (isDigitCode(cc(pos)))
|
|
776
760
|
pos++;
|
|
777
|
-
if (cc(pos) === CC_DOT ||
|
|
761
|
+
if (cc(pos) === CC_DOT || isNameStartCode(cc(pos)))
|
|
778
762
|
fail('expected an integer lookup key', at);
|
|
779
763
|
const n = Number(source.slice(at, pos));
|
|
780
764
|
if (!Number.isSafeInteger(n))
|
|
@@ -867,7 +851,7 @@ export function parseXQuery(source) {
|
|
|
867
851
|
fail("unsupported construct 'node constructor'", at);
|
|
868
852
|
if (c === CC_BACKTICK)
|
|
869
853
|
fail("unsupported construct 'string constructor'", at);
|
|
870
|
-
if (
|
|
854
|
+
if (isNameStartCode(c))
|
|
871
855
|
return parseNamedPrimary(at);
|
|
872
856
|
return fail('expected an expression');
|
|
873
857
|
}
|
|
@@ -1008,7 +992,7 @@ export function parseXQuery(source) {
|
|
|
1008
992
|
if (plain) {
|
|
1009
993
|
const out = {};
|
|
1010
994
|
for (let i = 0; i < keys.length; i++)
|
|
1011
|
-
|
|
995
|
+
setObjectMember(out, keys[i], values[i]);
|
|
1012
996
|
return out;
|
|
1013
997
|
}
|
|
1014
998
|
const pairs = new Array(keys.length);
|
|
@@ -1021,7 +1005,7 @@ export function parseXQuery(source) {
|
|
|
1021
1005
|
let name = parseNCName();
|
|
1022
1006
|
let written = name;
|
|
1023
1007
|
let prefix = null;
|
|
1024
|
-
if (cc(pos) === CC_COLON &&
|
|
1008
|
+
if (cc(pos) === CC_COLON && isNameStartCode(cc(pos + 1))) {
|
|
1025
1009
|
pos++;
|
|
1026
1010
|
prefix = name;
|
|
1027
1011
|
name = parseNCName();
|
|
@@ -1169,7 +1153,7 @@ export function parseXQuery(source) {
|
|
|
1169
1153
|
groups.push(group);
|
|
1170
1154
|
group = {};
|
|
1171
1155
|
}
|
|
1172
|
-
|
|
1156
|
+
setObjectMember(group, name, bindings[i][1]);
|
|
1173
1157
|
}
|
|
1174
1158
|
groups.push(group);
|
|
1175
1159
|
let out = cond;
|
|
@@ -1198,7 +1182,7 @@ export function parseXQuery(source) {
|
|
|
1198
1182
|
for (;;) {
|
|
1199
1183
|
skipWS();
|
|
1200
1184
|
const at = pos;
|
|
1201
|
-
if (!
|
|
1185
|
+
if (!isNameStartCode(cc(pos)))
|
|
1202
1186
|
fail('expected a FLWOR clause');
|
|
1203
1187
|
const kw = parseNCName();
|
|
1204
1188
|
if (kw === 'for' || kw === 'let') {
|
|
@@ -1244,7 +1228,7 @@ export function parseXQuery(source) {
|
|
|
1244
1228
|
skipWS();
|
|
1245
1229
|
if (cc(pos) === CC_DOLLAR)
|
|
1246
1230
|
return;
|
|
1247
|
-
if (kw === 'for' &&
|
|
1231
|
+
if (kw === 'for' && isNameStartCode(cc(pos))) {
|
|
1248
1232
|
const save = pos;
|
|
1249
1233
|
const w = parseNCName();
|
|
1250
1234
|
pos = save;
|
|
@@ -1444,7 +1428,7 @@ export function parseXQuery(source) {
|
|
|
1444
1428
|
if (c.kind === 'for') {
|
|
1445
1429
|
if (forObj === null)
|
|
1446
1430
|
forObj = {};
|
|
1447
|
-
|
|
1431
|
+
setObjectMember(forObj, c.name, c.atName === null ? c.expr : { '$in': c.expr, '$at': c.atName });
|
|
1448
1432
|
names.add(c.name);
|
|
1449
1433
|
if (c.atName !== null)
|
|
1450
1434
|
names.add(c.atName);
|
|
@@ -1453,7 +1437,7 @@ export function parseXQuery(source) {
|
|
|
1453
1437
|
else {
|
|
1454
1438
|
if (letObj === null)
|
|
1455
1439
|
letObj = {};
|
|
1456
|
-
|
|
1440
|
+
setObjectMember(letObj, c.name, c.expr);
|
|
1457
1441
|
names.add(c.name);
|
|
1458
1442
|
}
|
|
1459
1443
|
lastSlot = slot;
|
|
@@ -1477,7 +1461,7 @@ export function parseXQuery(source) {
|
|
|
1477
1461
|
fail(`duplicate variable '$${g.name}'`, g.at);
|
|
1478
1462
|
if (names.has(g.name))
|
|
1479
1463
|
fail(`unsupported construct 'group by' rebinding variable '$${g.name}'`, g.at);
|
|
1480
|
-
|
|
1464
|
+
setObjectMember(groupObj, g.name, g.expr);
|
|
1481
1465
|
}
|
|
1482
1466
|
for (let k = 0; k < c.keys.length; k++)
|
|
1483
1467
|
names.add(c.keys[k].name);
|
|
@@ -1533,7 +1517,7 @@ export function parseXQuery(source) {
|
|
|
1533
1517
|
if (tryKeyword('xquery') < 0)
|
|
1534
1518
|
return;
|
|
1535
1519
|
skipWS();
|
|
1536
|
-
if (!
|
|
1520
|
+
if (!isNameStartCode(cc(pos))) {
|
|
1537
1521
|
pos = save;
|
|
1538
1522
|
return;
|
|
1539
1523
|
}
|
|
@@ -1598,7 +1582,7 @@ export function parseXQuery(source) {
|
|
|
1598
1582
|
const save = pos;
|
|
1599
1583
|
skipWS();
|
|
1600
1584
|
const at = pos;
|
|
1601
|
-
if (!
|
|
1585
|
+
if (!isNameStartCode(cc(pos))) {
|
|
1602
1586
|
pos = save;
|
|
1603
1587
|
return;
|
|
1604
1588
|
}
|
|
@@ -1607,7 +1591,7 @@ export function parseXQuery(source) {
|
|
|
1607
1591
|
skipWS();
|
|
1608
1592
|
if (cc(pos) === CC_PERCENT)
|
|
1609
1593
|
fail("unsupported construct 'annotation'");
|
|
1610
|
-
if (!
|
|
1594
|
+
if (!isNameStartCode(cc(pos)))
|
|
1611
1595
|
fail('expected a declaration keyword');
|
|
1612
1596
|
const kind = parseNCName();
|
|
1613
1597
|
if (kind === 'variable') {
|
|
@@ -1618,7 +1602,7 @@ export function parseXQuery(source) {
|
|
|
1618
1602
|
}
|
|
1619
1603
|
if (w === 'import') {
|
|
1620
1604
|
skipWS();
|
|
1621
|
-
const kind =
|
|
1605
|
+
const kind = isNameStartCode(cc(pos)) ? parseNCName() : 'declaration';
|
|
1622
1606
|
fail(`unsupported construct 'import ${kind}'`, at);
|
|
1623
1607
|
}
|
|
1624
1608
|
if (w === 'module')
|