jtlt 0.23.0 → 0.24.1
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/.gitignore +3 -0
- package/.npmignore +3 -0
- package/CHANGES.md +32 -0
- package/demo/codemirror.esm.js +3 -1
- package/dist/AbstractJoiningTransformer.d.ts.map +1 -1
- package/dist/DOMJoiningTransformer.d.ts.map +1 -1
- package/dist/JSONJoiningTransformer.d.ts.map +1 -1
- package/dist/JSONPathTransformer.d.ts.map +1 -1
- package/dist/JSONPathTransformerContext.d.ts +14 -1
- package/dist/JSONPathTransformerContext.d.ts.map +1 -1
- package/dist/StringJoiningTransformer.d.ts.map +1 -1
- package/dist/XPathTransformer.d.ts.map +1 -1
- package/dist/XPathTransformerContext.d.ts.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/indexedDB.d.ts.map +1 -1
- package/dist/jsonTemplate.d.ts.map +1 -1
- package/docs/API.expanded.md +18 -3
- package/package.json +28 -29
- package/pnpm-workspace.yaml +3 -1
- package/src/AbstractJoiningTransformer.js +15 -15
- package/src/DOMJoiningTransformer.js +13 -11
- package/src/JSONJoiningTransformer.js +21 -21
- package/src/JSONPathTransformer.js +3 -4
- package/src/JSONPathTransformerContext.js +65 -70
- package/src/StringJoiningTransformer.js +9 -7
- package/src/XPathTransformer.js +3 -4
- package/src/XPathTransformerContext.js +79 -91
- package/src/index.js +3 -1
- package/src/indexedDB.js +5 -6
- package/src/jsonTemplate.js +70 -55
- package/tsconfig-prod.json +1 -7
|
@@ -230,7 +230,7 @@ class AbstractJoiningTransformer {
|
|
|
230
230
|
`Function "${name}" must have either 'body' or 'sequence' attribute`
|
|
231
231
|
);
|
|
232
232
|
}
|
|
233
|
-
/* c8 ignore stop */
|
|
233
|
+
/* c8 ignore stop -- See above */
|
|
234
234
|
|
|
235
235
|
// Create function key with arity
|
|
236
236
|
const arity = params.length;
|
|
@@ -280,7 +280,7 @@ class AbstractJoiningTransformer {
|
|
|
280
280
|
`supported in this context)`
|
|
281
281
|
);
|
|
282
282
|
}
|
|
283
|
-
/* c8 ignore stop */
|
|
283
|
+
/* c8 ignore stop -- See above */
|
|
284
284
|
return functionDef.body(...args);
|
|
285
285
|
}
|
|
286
286
|
|
|
@@ -361,10 +361,7 @@ class AbstractJoiningTransformer {
|
|
|
361
361
|
this._flushPendingNamespace(alias);
|
|
362
362
|
|
|
363
363
|
if (colonIdx === -1) {
|
|
364
|
-
|
|
365
|
-
return elemName;
|
|
366
|
-
}
|
|
367
|
-
return alias + ':' + elemName;
|
|
364
|
+
return alias === '#default' ? elemName : alias + ':' + elemName;
|
|
368
365
|
}
|
|
369
366
|
|
|
370
367
|
return (alias === '#default'
|
|
@@ -392,13 +389,14 @@ class AbstractJoiningTransformer {
|
|
|
392
389
|
*/
|
|
393
390
|
_trackAttributePrefix (attrName) {
|
|
394
391
|
const colonIdx = attrName.indexOf(':');
|
|
395
|
-
if (colonIdx
|
|
396
|
-
|
|
397
|
-
this._usedNamespacePrefixes.add(prefix);
|
|
398
|
-
|
|
399
|
-
// If this prefix was buffered, output it now
|
|
400
|
-
this._flushPendingNamespace(prefix);
|
|
392
|
+
if (colonIdx === -1 || attrName.startsWith('xmlns')) {
|
|
393
|
+
return;
|
|
401
394
|
}
|
|
395
|
+
const prefix = attrName.slice(0, colonIdx);
|
|
396
|
+
this._usedNamespacePrefixes.add(prefix);
|
|
397
|
+
|
|
398
|
+
// If this prefix was buffered, output it now
|
|
399
|
+
this._flushPendingNamespace(prefix);
|
|
402
400
|
}
|
|
403
401
|
|
|
404
402
|
/**
|
|
@@ -445,10 +443,12 @@ class AbstractJoiningTransformer {
|
|
|
445
443
|
const cfg = /** @type {Record<string, unknown>} */ (this._cfg);
|
|
446
444
|
const oldCfgProp = cfg[prop];
|
|
447
445
|
cfg[prop] = val;
|
|
448
|
-
if (cb) {
|
|
449
|
-
|
|
450
|
-
cfg[prop] = oldCfgProp;
|
|
446
|
+
if (!cb) {
|
|
447
|
+
return;
|
|
451
448
|
}
|
|
449
|
+
|
|
450
|
+
cb.call(this);
|
|
451
|
+
cfg[prop] = oldCfgProp;
|
|
452
452
|
}
|
|
453
453
|
}
|
|
454
454
|
|
|
@@ -357,7 +357,7 @@ class DOMJoiningTransformer extends AbstractJoiningTransformer {
|
|
|
357
357
|
omitXmlDeclaration, doctypePublic, doctypeSystem, method
|
|
358
358
|
/* c8 ignore start -- outputConfig ?? attribution issue */
|
|
359
359
|
} = this._outputConfig ?? {};
|
|
360
|
-
/* c8 ignore stop */
|
|
360
|
+
/* c8 ignore stop -- See above */
|
|
361
361
|
|
|
362
362
|
/* c8 ignore start -- namespace/prefix detection branches */
|
|
363
363
|
const dtd = this._cfg.document.implementation.createDocumentType(
|
|
@@ -379,7 +379,7 @@ class DOMJoiningTransformer extends AbstractJoiningTransformer {
|
|
|
379
379
|
elementName,
|
|
380
380
|
dtd
|
|
381
381
|
);
|
|
382
|
-
/* c8 ignore stop */
|
|
382
|
+
/* c8 ignore stop -- See above */
|
|
383
383
|
|
|
384
384
|
/* c8 ignore start -- third OR condition short-circuits */
|
|
385
385
|
if (!omitXmlDeclaration && (
|
|
@@ -403,7 +403,7 @@ class DOMJoiningTransformer extends AbstractJoiningTransformer {
|
|
|
403
403
|
doc.firstChild
|
|
404
404
|
);
|
|
405
405
|
}
|
|
406
|
-
/* c8 ignore stop */
|
|
406
|
+
/* c8 ignore stop -- See above */
|
|
407
407
|
|
|
408
408
|
// Push the document to _docs
|
|
409
409
|
this._docs.push(doc);
|
|
@@ -587,15 +587,17 @@ class DOMJoiningTransformer extends AbstractJoiningTransformer {
|
|
|
587
587
|
*/
|
|
588
588
|
_flushPendingNamespace (prefix) {
|
|
589
589
|
const pending = this._pendingNamespaceMap.get(prefix);
|
|
590
|
-
if (pending) {
|
|
591
|
-
|
|
592
|
-
(this._dom).setAttributeNS(
|
|
593
|
-
'http://www.w3.org/2000/xmlns/',
|
|
594
|
-
pending.prefix === '#default' ? 'xmlns' : 'xmlns:' + pending.prefix,
|
|
595
|
-
this._replaceCharacterMaps(pending.namespaceURI)
|
|
596
|
-
);
|
|
597
|
-
this._pendingNamespaceMap.delete(prefix);
|
|
590
|
+
if (!pending) {
|
|
591
|
+
return;
|
|
598
592
|
}
|
|
593
|
+
|
|
594
|
+
/** @type {Element} */
|
|
595
|
+
(this._dom).setAttributeNS(
|
|
596
|
+
'http://www.w3.org/2000/xmlns/',
|
|
597
|
+
pending.prefix === '#default' ? 'xmlns' : 'xmlns:' + pending.prefix,
|
|
598
|
+
this._replaceCharacterMaps(pending.namespaceURI)
|
|
599
|
+
);
|
|
600
|
+
this._pendingNamespaceMap.delete(prefix);
|
|
599
601
|
}
|
|
600
602
|
/**
|
|
601
603
|
* @param {string} name
|
|
@@ -488,10 +488,9 @@ class JSONJoiningTransformer extends AbstractJoiningTransformer {
|
|
|
488
488
|
// If children provided as array, copy (may be primitives or nested JML)
|
|
489
489
|
if (Array.isArray(childNodes) && childNodes.length) {
|
|
490
490
|
jmlChildren.push(...childNodes.map((childNode) => {
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
return childNode;
|
|
491
|
+
return typeof childNode === 'string'
|
|
492
|
+
? this._replaceCharacterMaps(childNode)
|
|
493
|
+
: childNode;
|
|
495
494
|
}));
|
|
496
495
|
}
|
|
497
496
|
|
|
@@ -537,7 +536,7 @@ class JSONJoiningTransformer extends AbstractJoiningTransformer {
|
|
|
537
536
|
standalone
|
|
538
537
|
};
|
|
539
538
|
}
|
|
540
|
-
/* c8 ignore stop */
|
|
539
|
+
/* c8 ignore stop -- See above */
|
|
541
540
|
|
|
542
541
|
const doc = {$document: {
|
|
543
542
|
...(xmlDeclaration ? {xmlDeclaration} : {}),
|
|
@@ -641,20 +640,22 @@ class JSONJoiningTransformer extends AbstractJoiningTransformer {
|
|
|
641
640
|
}
|
|
642
641
|
|
|
643
642
|
const pending = this._pendingNamespaceMap.get(prefix);
|
|
644
|
-
if (pending) {
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
if (!attsObj.xmlns) {
|
|
649
|
-
attsObj.xmlns = {};
|
|
650
|
-
}
|
|
643
|
+
if (!pending) {
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
651
646
|
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
this._replaceCharacterMaps(pending.namespaceURI);
|
|
647
|
+
const top = /** @type {ElementInfo} */ (this._elementStack.at(-1));
|
|
648
|
+
const {attsObj} = top;
|
|
655
649
|
|
|
656
|
-
|
|
650
|
+
if (!attsObj.xmlns) {
|
|
651
|
+
attsObj.xmlns = {};
|
|
657
652
|
}
|
|
653
|
+
|
|
654
|
+
/** @type {Record<string, string>} */
|
|
655
|
+
(attsObj.xmlns)[pending.prefix === '#default' ? '' : pending.prefix] =
|
|
656
|
+
this._replaceCharacterMaps(pending.namespaceURI);
|
|
657
|
+
|
|
658
|
+
this._pendingNamespaceMap.delete(prefix);
|
|
658
659
|
}
|
|
659
660
|
/**
|
|
660
661
|
* Adds/updates an attribute for the most recently open element built via
|
|
@@ -882,7 +883,7 @@ class JSONJoiningTransformer extends AbstractJoiningTransformer {
|
|
|
882
883
|
standalone
|
|
883
884
|
};
|
|
884
885
|
}
|
|
885
|
-
/* c8 ignore stop */
|
|
886
|
+
/* c8 ignore stop -- See above */
|
|
886
887
|
|
|
887
888
|
resultDoc = {$document: {
|
|
888
889
|
...(xmlDeclaration ? {xmlDeclaration} : {}),
|
|
@@ -921,10 +922,9 @@ class JSONJoiningTransformer extends AbstractJoiningTransformer {
|
|
|
921
922
|
*/
|
|
922
923
|
_usePropertySets (obj, psName) {
|
|
923
924
|
// Merge the named property set (if present) into the provided object
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
return obj;
|
|
925
|
+
return Object.hasOwn(this.propertySets, psName)
|
|
926
|
+
? Object.assign(obj, this.propertySets[psName])
|
|
927
|
+
: obj;
|
|
928
928
|
}
|
|
929
929
|
}
|
|
930
930
|
|
|
@@ -34,10 +34,9 @@ class JSONPathTransformer {
|
|
|
34
34
|
*/
|
|
35
35
|
template (value) {
|
|
36
36
|
// Emit property names for the current object context
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return '';
|
|
37
|
+
return value && typeof value === 'object' && !Array.isArray(value)
|
|
38
|
+
? Object.keys(value).join('')
|
|
39
|
+
: '';
|
|
41
40
|
}
|
|
42
41
|
},
|
|
43
42
|
transformObjects: {
|
|
@@ -319,10 +319,8 @@ class JSONPathTransformerContext {
|
|
|
319
319
|
/* const results = */ this._getJoiningTransformer();
|
|
320
320
|
const modeMatchedTemplates = this._templates.filter((templateObj) => {
|
|
321
321
|
// Exclude named-only templates (those with name but no path)
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
}
|
|
325
|
-
return ((mode && mode === templateObj.mode) ||
|
|
322
|
+
return (!templateObj.name || templateObj.path) &&
|
|
323
|
+
((mode && mode === templateObj.mode) ||
|
|
326
324
|
(!mode && !templateObj.mode));
|
|
327
325
|
});
|
|
328
326
|
|
|
@@ -382,10 +380,7 @@ class JSONPathTransformerContext {
|
|
|
382
380
|
if (Number.isNaN(an)) {
|
|
383
381
|
return Number(order);
|
|
384
382
|
}
|
|
385
|
-
|
|
386
|
-
return -order;
|
|
387
|
-
}
|
|
388
|
-
return (an - bn) * order;
|
|
383
|
+
return Number.isNaN(bn) ? -order : (an - bn) * order;
|
|
389
384
|
}
|
|
390
385
|
// text
|
|
391
386
|
/* c8 ignore next 2 -- all null/undefined tested; OR short-circuit */
|
|
@@ -460,7 +455,7 @@ class JSONPathTransformerContext {
|
|
|
460
455
|
if (!templateObj.path) {
|
|
461
456
|
return false;
|
|
462
457
|
}
|
|
463
|
-
/* c8 ignore stop */
|
|
458
|
+
/* c8 ignore stop -- See above */
|
|
464
459
|
const queryResult = /** @type {any[]} */ (
|
|
465
460
|
(/** @type {any} */ (jsonpath))({
|
|
466
461
|
path: JSONPathTransformer.makeJSONPathAbsolute(
|
|
@@ -554,7 +549,7 @@ class JSONPathTransformerContext {
|
|
|
554
549
|
: (that._config.specificityPriorityResolver && b.path
|
|
555
550
|
? that._config.specificityPriorityResolver(b.path)
|
|
556
551
|
: 0);
|
|
557
|
-
/* c8 ignore stop */
|
|
552
|
+
/* c8 ignore stop -- See above */
|
|
558
553
|
|
|
559
554
|
if (aPriority === bPriority) {
|
|
560
555
|
that._triggerEqualPriorityError();
|
|
@@ -676,13 +671,13 @@ class JSONPathTransformerContext {
|
|
|
676
671
|
// @ts-expect-error -- _openTagState: StringJoiningTransformer
|
|
677
672
|
joiner._openTagState = false;
|
|
678
673
|
}
|
|
679
|
-
/* c8 ignore stop */
|
|
674
|
+
/* c8 ignore stop -- See above */
|
|
680
675
|
joiner.append(resolvedRet);
|
|
681
676
|
}
|
|
682
677
|
that._parent = parent;
|
|
683
678
|
// Matches reached here always carry a parentProperty; the sync
|
|
684
679
|
// path covers the root-node fallback.
|
|
685
|
-
/* c8 ignore next */
|
|
680
|
+
/* c8 ignore next -- See comment just above */
|
|
686
681
|
that._parentProperty = (parentProperty ?? that._parentProperty);
|
|
687
682
|
that._currPath = _oldPath;
|
|
688
683
|
return undefined;
|
|
@@ -700,7 +695,7 @@ class JSONPathTransformerContext {
|
|
|
700
695
|
// @ts-expect-error -- _openTagState only on StringJoiningTransformer
|
|
701
696
|
joiner._openTagState = false;
|
|
702
697
|
}
|
|
703
|
-
/* c8 ignore stop */
|
|
698
|
+
/* c8 ignore stop -- See above */
|
|
704
699
|
joiner.append(
|
|
705
700
|
/** @type {string|Node|*} */ (ret)
|
|
706
701
|
);
|
|
@@ -825,9 +820,22 @@ class JSONPathTransformerContext {
|
|
|
825
820
|
* `void`, not `void|Promise<void>` — see the note on `SimpleCallback`
|
|
826
821
|
* in JSONJoiningTransformer.js.)
|
|
827
822
|
* @param {SortSpec<V>} [sort] - Sort spec
|
|
823
|
+
* @param {string} [keyVar] - When given, binds each iteration's key —
|
|
824
|
+
* the array index, or the object property name when `select` is an
|
|
825
|
+
* object-wildcard path like `$.*` (jsonpath-plus's own `parentProperty`
|
|
826
|
+
* on a `resultType: 'all'` match) — to this name for the duration of
|
|
827
|
+
* that iteration, readable back via a bare `$name` reference (same
|
|
828
|
+
* convention as `variable()`), same as `_params[0]`/`this.vars` are
|
|
829
|
+
* already scoped fresh per iteration. Lets a template render
|
|
830
|
+
* "property: value" pairs, or skip one property by name via `$if`,
|
|
831
|
+
* while iterating an object's own properties — jsonpath-plus's match
|
|
832
|
+
* data already carries this; `select`s naming a bound variable (the
|
|
833
|
+
* bare-`$name` convention, below) carry the array index too, but never
|
|
834
|
+
* a meaningful key for a non-array bound value (treated as a single,
|
|
835
|
+
* length-1-sequence item — there's no "property name" for that case).
|
|
828
836
|
* @returns {this|Promise<this>}
|
|
829
837
|
*/
|
|
830
|
-
forEach (select, cb, sort) {
|
|
838
|
+
forEach (select, cb, sort, keyVar) {
|
|
831
839
|
// eslint-disable-next-line unicorn/no-this-assignment -- Temporary
|
|
832
840
|
const that = this;
|
|
833
841
|
// A bare `$name` (matching `if()`/`valueOf()`/comparisons' own
|
|
@@ -840,10 +848,13 @@ class JSONPathTransformerContext {
|
|
|
840
848
|
const param = paramRef && paramRef.groups
|
|
841
849
|
? this._lookupParam(paramRef.groups.name)
|
|
842
850
|
: {has: false, value: undefined};
|
|
843
|
-
/** @type {{value: any}[]} */
|
|
851
|
+
/** @type {{value: any, parentProperty?: string|number}[]} */
|
|
844
852
|
const matches = param.has
|
|
845
|
-
? (Array.isArray(param.value)
|
|
846
|
-
|
|
853
|
+
? (Array.isArray(param.value)
|
|
854
|
+
// An array's own index is a meaningful key (see `keyVar`, above);
|
|
855
|
+
// a non-array value wrapped as a length-1 sequence has none.
|
|
856
|
+
? param.value.map((value, index) => ({value, parentProperty: index}))
|
|
857
|
+
: [{value: param.value}])
|
|
847
858
|
: /** @type {any} */ (jsonpath)({
|
|
848
859
|
path: select,
|
|
849
860
|
json: this._contextObj,
|
|
@@ -894,10 +905,7 @@ class JSONPathTransformerContext {
|
|
|
894
905
|
if (Number.isNaN(an)) {
|
|
895
906
|
return Number(order);
|
|
896
907
|
}
|
|
897
|
-
|
|
898
|
-
return -order;
|
|
899
|
-
}
|
|
900
|
-
return (an - bn) * order;
|
|
908
|
+
return Number.isNaN(bn) ? -order : (an - bn) * order;
|
|
901
909
|
}
|
|
902
910
|
/* c8 ignore next 2 -- all null/undefined tested; OR short-circuit */
|
|
903
911
|
const aStr = aVal === null || aVal === undefined ? '' : String(aVal);
|
|
@@ -960,7 +968,7 @@ class JSONPathTransformerContext {
|
|
|
960
968
|
const prevVars = that.vars;
|
|
961
969
|
that._params = {0: m.value};
|
|
962
970
|
that._contextObj = m.value;
|
|
963
|
-
that.vars = {};
|
|
971
|
+
that.vars = keyVar ? {[keyVar]: m.parentProperty} : {};
|
|
964
972
|
// `cb`'s declared return type is plain `void` (see the parameter's
|
|
965
973
|
// JSDoc) — cast here to duck-type the real value; see the note on
|
|
966
974
|
// `SimpleCallback` in JSONJoiningTransformer.js.
|
|
@@ -991,7 +999,7 @@ class JSONPathTransformerContext {
|
|
|
991
999
|
const pv = that.vars;
|
|
992
1000
|
that._params = {0: next.value};
|
|
993
1001
|
that._contextObj = next.value;
|
|
994
|
-
that.vars = {};
|
|
1002
|
+
that.vars = keyVar ? {[keyVar]: next.parentProperty} : {};
|
|
995
1003
|
try {
|
|
996
1004
|
// eslint-disable-next-line no-await-in-loop -- Sequential order
|
|
997
1005
|
await cb.call(that, next.value);
|
|
@@ -1241,23 +1249,25 @@ class JSONPathTransformerContext {
|
|
|
1241
1249
|
currentGroup.push(m.value);
|
|
1242
1250
|
const endMatch = evalInContext(groupEndingWith, m.value);
|
|
1243
1251
|
|
|
1244
|
-
if (endMatch) {
|
|
1245
|
-
|
|
1246
|
-
const prevParams = this._params;
|
|
1247
|
-
const prevVars = this.vars;
|
|
1248
|
-
this.vars = {};
|
|
1249
|
-
try {
|
|
1250
|
-
this._contextObj = currentGroup;
|
|
1251
|
-
/** @type {any} */ (this)._currentGroup = currentGroup;
|
|
1252
|
-
cb.call(this, null, currentGroup, this);
|
|
1253
|
-
} finally {
|
|
1254
|
-
this._contextObj = prevContext;
|
|
1255
|
-
this._params = prevParams;
|
|
1256
|
-
this.vars = prevVars;
|
|
1257
|
-
delete /** @type {any} */ (this)._currentGroup;
|
|
1258
|
-
}
|
|
1259
|
-
currentGroup = [];
|
|
1252
|
+
if (!endMatch) {
|
|
1253
|
+
continue;
|
|
1260
1254
|
}
|
|
1255
|
+
|
|
1256
|
+
const prevContext = this._contextObj;
|
|
1257
|
+
const prevParams = this._params;
|
|
1258
|
+
const prevVars = this.vars;
|
|
1259
|
+
this.vars = {};
|
|
1260
|
+
try {
|
|
1261
|
+
this._contextObj = currentGroup;
|
|
1262
|
+
/** @type {any} */ (this)._currentGroup = currentGroup;
|
|
1263
|
+
cb.call(this, null, currentGroup, this);
|
|
1264
|
+
} finally {
|
|
1265
|
+
this._contextObj = prevContext;
|
|
1266
|
+
this._params = prevParams;
|
|
1267
|
+
this.vars = prevVars;
|
|
1268
|
+
delete /** @type {any} */ (this)._currentGroup;
|
|
1269
|
+
}
|
|
1270
|
+
currentGroup = [];
|
|
1261
1271
|
}
|
|
1262
1272
|
|
|
1263
1273
|
// Process last group if not ended
|
|
@@ -1325,10 +1335,7 @@ class JSONPathTransformerContext {
|
|
|
1325
1335
|
if (Number.isNaN(an)) {
|
|
1326
1336
|
return order;
|
|
1327
1337
|
}
|
|
1328
|
-
|
|
1329
|
-
return -order;
|
|
1330
|
-
}
|
|
1331
|
-
return (an - bn) * order;
|
|
1338
|
+
return Number.isNaN(bn) ? -order : (an - bn) * order;
|
|
1332
1339
|
}
|
|
1333
1340
|
/* c8 ignore next 2 -- all null/undefined tested; OR short-circuit */
|
|
1334
1341
|
const aStr = aVal === null || aVal === undefined ? '' : String(aVal);
|
|
@@ -1626,12 +1633,11 @@ class JSONPathTransformerContext {
|
|
|
1626
1633
|
* @returns {string} - Captured group or empty string
|
|
1627
1634
|
*/
|
|
1628
1635
|
const getRegexGroup = (groupNumber) => {
|
|
1629
|
-
|
|
1636
|
+
return !currentCapturedGroups ||
|
|
1630
1637
|
groupNumber < 0 ||
|
|
1631
|
-
groupNumber >= currentCapturedGroups.length
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
return currentCapturedGroups[groupNumber] || '';
|
|
1638
|
+
groupNumber >= currentCapturedGroups.length
|
|
1639
|
+
? ''
|
|
1640
|
+
: currentCapturedGroups[groupNumber] || '';
|
|
1635
1641
|
};
|
|
1636
1642
|
|
|
1637
1643
|
// Save previous context to restore later
|
|
@@ -1734,7 +1740,7 @@ class JSONPathTransformerContext {
|
|
|
1734
1740
|
// For non-functions, attempting structuredClone again would rethrow;
|
|
1735
1741
|
// use shallow clone to retain non-serializable props like Symbols.
|
|
1736
1742
|
clone = Array.isArray(val) ? [...val] : {...val};
|
|
1737
|
-
/* c8 ignore stop */
|
|
1743
|
+
/* c8 ignore stop -- See above */
|
|
1738
1744
|
}
|
|
1739
1745
|
} else {
|
|
1740
1746
|
// Primitives/functions copied by value/reference semantics naturally.
|
|
@@ -1766,7 +1772,7 @@ class JSONPathTransformerContext {
|
|
|
1766
1772
|
}
|
|
1767
1773
|
} else { /* c8 ignore start -- primitive branch attribution variance */
|
|
1768
1774
|
clone = src; // Primitive/function - nothing to shallow clone
|
|
1769
|
-
} /* c8 ignore stop */
|
|
1775
|
+
} /* c8 ignore stop -- See above */
|
|
1770
1776
|
this._getJoiningTransformer().append(clone);
|
|
1771
1777
|
return this;
|
|
1772
1778
|
}
|
|
@@ -1825,10 +1831,9 @@ class JSONPathTransformerContext {
|
|
|
1825
1831
|
if (Object.hasOwn(this.vars, name)) {
|
|
1826
1832
|
return {has: true, value: this.vars[name]};
|
|
1827
1833
|
}
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
return {has: false, value: undefined};
|
|
1834
|
+
return Object.hasOwn(this._runtimeParams, name)
|
|
1835
|
+
? {has: true, value: this._runtimeParams[name]}
|
|
1836
|
+
: {has: false, value: undefined};
|
|
1832
1837
|
}
|
|
1833
1838
|
|
|
1834
1839
|
/**
|
|
@@ -2762,15 +2767,9 @@ class JSONPathTransformerContext {
|
|
|
2762
2767
|
}
|
|
2763
2768
|
// Single item; apply scalar truthiness
|
|
2764
2769
|
const single = val[0];
|
|
2765
|
-
|
|
2766
|
-
return true;
|
|
2767
|
-
}
|
|
2768
|
-
return Boolean(single);
|
|
2770
|
+
return single && typeof single === 'object' ? true : Boolean(single);
|
|
2769
2771
|
}
|
|
2770
|
-
|
|
2771
|
-
return true;
|
|
2772
|
-
}
|
|
2773
|
-
return Boolean(val);
|
|
2772
|
+
return val && typeof val === 'object' ? true : Boolean(val);
|
|
2774
2773
|
}
|
|
2775
2774
|
|
|
2776
2775
|
/**
|
|
@@ -2821,10 +2820,9 @@ class JSONPathTransformerContext {
|
|
|
2821
2820
|
return null;
|
|
2822
2821
|
}
|
|
2823
2822
|
const right = this._parseLiteral(m.groups.right.trim());
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
return {left: m.groups.left, op: m.groups.op, right: right.value};
|
|
2823
|
+
return !right
|
|
2824
|
+
? null
|
|
2825
|
+
: {left: m.groups.left, op: m.groups.op, right: right.value};
|
|
2828
2826
|
}
|
|
2829
2827
|
|
|
2830
2828
|
/**
|
|
@@ -2855,10 +2853,7 @@ class JSONPathTransformerContext {
|
|
|
2855
2853
|
if (str === 'null') {
|
|
2856
2854
|
return {value: null};
|
|
2857
2855
|
}
|
|
2858
|
-
|
|
2859
|
-
return {value: undefined};
|
|
2860
|
-
}
|
|
2861
|
-
return null;
|
|
2856
|
+
return str === 'undefined' ? {value: undefined} : null;
|
|
2862
2857
|
}
|
|
2863
2858
|
|
|
2864
2859
|
/**
|
|
@@ -562,7 +562,7 @@ class StringJoiningTransformer extends AbstractJoiningTransformer {
|
|
|
562
562
|
standalone ? ` standalone="yes"` : ''
|
|
563
563
|
}?>\n`;
|
|
564
564
|
}
|
|
565
|
-
/* c8 ignore stop */
|
|
565
|
+
/* c8 ignore stop -- See above */
|
|
566
566
|
|
|
567
567
|
const doctype = bareDoctype ||
|
|
568
568
|
doctypePublic !== undefined || doctypeSystem !== undefined
|
|
@@ -733,13 +733,15 @@ class StringJoiningTransformer extends AbstractJoiningTransformer {
|
|
|
733
733
|
*/
|
|
734
734
|
_flushPendingNamespace (prefix) {
|
|
735
735
|
const pending = this._pendingNamespaceMap.get(prefix);
|
|
736
|
-
if (pending) {
|
|
737
|
-
|
|
738
|
-
pending.prefix === '#default' ? 'xmlns' : 'xmlns:' + pending.prefix
|
|
739
|
-
) + '="' +
|
|
740
|
-
this._replaceCharacterMaps(pending.namespaceURI) + '"');
|
|
741
|
-
this._pendingNamespaceMap.delete(prefix);
|
|
736
|
+
if (!pending) {
|
|
737
|
+
return;
|
|
742
738
|
}
|
|
739
|
+
|
|
740
|
+
this.append(' ' + (
|
|
741
|
+
pending.prefix === '#default' ? 'xmlns' : 'xmlns:' + pending.prefix
|
|
742
|
+
) + '="' +
|
|
743
|
+
this._replaceCharacterMaps(pending.namespaceURI) + '"');
|
|
744
|
+
this._pendingNamespaceMap.delete(prefix);
|
|
743
745
|
}
|
|
744
746
|
|
|
745
747
|
/**
|
package/src/XPathTransformer.js
CHANGED
|
@@ -50,10 +50,9 @@ class XPathTransformer {
|
|
|
50
50
|
return {path: template[0], template: template[1]};
|
|
51
51
|
}
|
|
52
52
|
// Normalize 'match' to 'path' for XSLT compatibility
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return template;
|
|
53
|
+
return template.match && !template.path
|
|
54
|
+
? {...template, path: template.match}
|
|
55
|
+
: template;
|
|
57
56
|
});
|
|
58
57
|
this.templates.forEach((template) => {
|
|
59
58
|
if ('name' in template && template.name &&
|