@thoughtspot/visual-embed-sdk 1.49.2 → 1.50.0
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/cjs/package.json +4 -10
- package/cjs/src/authToken.spec.js +5 -0
- package/cjs/src/authToken.spec.js.map +1 -1
- package/cjs/src/embed/app.d.ts +7 -1
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +6 -0
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/app.spec.js +11 -2
- package/cjs/src/embed/app.spec.js.map +1 -1
- package/cjs/src/embed/conversation.d.ts +12 -0
- package/cjs/src/embed/conversation.d.ts.map +1 -1
- package/cjs/src/embed/conversation.js.map +1 -1
- package/cjs/src/embed/conversation.spec.js +30 -0
- package/cjs/src/embed/conversation.spec.js.map +1 -1
- package/cjs/src/embed/embedConfig.spec.d.ts +2 -0
- package/cjs/src/embed/embedConfig.spec.d.ts.map +1 -0
- package/cjs/src/embed/embedConfig.spec.js +74 -0
- package/cjs/src/embed/embedConfig.spec.js.map +1 -0
- package/cjs/src/embed/host-events.spec.d.ts +2 -0
- package/cjs/src/embed/host-events.spec.d.ts.map +1 -0
- package/cjs/src/embed/host-events.spec.js +1219 -0
- package/cjs/src/embed/host-events.spec.js.map +1 -0
- package/cjs/src/embed/liveboard.d.ts +6 -0
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/spotter-viz-utils.d.ts +29 -0
- package/cjs/src/embed/spotter-viz-utils.d.ts.map +1 -1
- package/cjs/src/embed/spotter-viz-utils.js.map +1 -1
- package/cjs/src/index.d.ts +2 -2
- package/cjs/src/index.d.ts.map +1 -1
- package/cjs/src/index.js.map +1 -1
- package/cjs/src/mixpanel-service.spec.js +14 -0
- package/cjs/src/mixpanel-service.spec.js.map +1 -1
- package/cjs/src/types.d.ts +93 -6
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +88 -3
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/custom-actions.spec.js +26 -0
- package/cjs/src/utils/custom-actions.spec.js.map +1 -1
- package/cjs/src/utils/graphql/answerService/answerService.spec.js +15 -0
- package/cjs/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
- package/cjs/src/utils/processData.spec.js +30 -0
- package/cjs/src/utils/processData.spec.js.map +1 -1
- package/cjs/src/utils/reporting.spec.js +21 -0
- package/cjs/src/utils/reporting.spec.js.map +1 -1
- package/cjs/src/utils/sessionInfoService.spec.d.ts +2 -0
- package/cjs/src/utils/sessionInfoService.spec.d.ts.map +1 -0
- package/cjs/src/utils/sessionInfoService.spec.js +130 -0
- package/cjs/src/utils/sessionInfoService.spec.js.map +1 -0
- package/cjs/src/utils.js +2 -3
- package/cjs/src/utils.js.map +1 -1
- package/cjs/src/utils.spec.js +158 -0
- package/cjs/src/utils.spec.js.map +1 -1
- package/dist/{index-CS7yJ2Jj.js → index-B5xoN6Cp.js} +303 -187
- package/dist/src/embed/app.d.ts +7 -1
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/conversation.d.ts +12 -0
- package/dist/src/embed/conversation.d.ts.map +1 -1
- package/dist/src/embed/embedConfig.spec.d.ts +2 -0
- package/dist/src/embed/embedConfig.spec.d.ts.map +1 -0
- package/dist/src/embed/host-events.spec.d.ts +2 -0
- package/dist/src/embed/host-events.spec.d.ts.map +1 -0
- package/dist/src/embed/liveboard.d.ts +6 -0
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/spotter-viz-utils.d.ts +29 -0
- package/dist/src/embed/spotter-viz-utils.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/types.d.ts +93 -6
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/sessionInfoService.spec.d.ts +2 -0
- package/dist/src/utils/sessionInfoService.spec.d.ts.map +1 -0
- package/dist/tsembed-react.es.js +126 -18
- package/dist/tsembed-react.js +427 -203
- package/dist/tsembed.es.js +126 -18
- package/dist/tsembed.js +427 -203
- package/dist/visual-embed-sdk-react-full.d.ts +147 -7
- package/dist/visual-embed-sdk-react.d.ts +147 -7
- package/dist/visual-embed-sdk.d.ts +147 -7
- package/lib/package.json +4 -10
- package/lib/src/authToken.spec.js +5 -0
- package/lib/src/authToken.spec.js.map +1 -1
- package/lib/src/embed/app.d.ts +7 -1
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +6 -0
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +11 -2
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/conversation.d.ts +12 -0
- package/lib/src/embed/conversation.d.ts.map +1 -1
- package/lib/src/embed/conversation.js.map +1 -1
- package/lib/src/embed/conversation.spec.js +30 -0
- package/lib/src/embed/conversation.spec.js.map +1 -1
- package/lib/src/embed/embedConfig.spec.d.ts +2 -0
- package/lib/src/embed/embedConfig.spec.d.ts.map +1 -0
- package/lib/src/embed/embedConfig.spec.js +72 -0
- package/lib/src/embed/embedConfig.spec.js.map +1 -0
- package/lib/src/embed/host-events.spec.d.ts +2 -0
- package/lib/src/embed/host-events.spec.d.ts.map +1 -0
- package/lib/src/embed/host-events.spec.js +1216 -0
- package/lib/src/embed/host-events.spec.js.map +1 -0
- package/lib/src/embed/liveboard.d.ts +6 -0
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/spotter-viz-utils.d.ts +29 -0
- package/lib/src/embed/spotter-viz-utils.d.ts.map +1 -1
- package/lib/src/embed/spotter-viz-utils.js.map +1 -1
- package/lib/src/index.d.ts +2 -2
- package/lib/src/index.d.ts.map +1 -1
- package/lib/src/index.js.map +1 -1
- package/lib/src/mixpanel-service.spec.js +14 -0
- package/lib/src/mixpanel-service.spec.js.map +1 -1
- package/lib/src/types.d.ts +93 -6
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +88 -3
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/custom-actions.spec.js +26 -0
- package/lib/src/utils/custom-actions.spec.js.map +1 -1
- package/lib/src/utils/graphql/answerService/answerService.spec.js +15 -0
- package/lib/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
- package/lib/src/utils/processData.spec.js +30 -0
- package/lib/src/utils/processData.spec.js.map +1 -1
- package/lib/src/utils/reporting.spec.js +21 -0
- package/lib/src/utils/reporting.spec.js.map +1 -1
- package/lib/src/utils/sessionInfoService.spec.d.ts +2 -0
- package/lib/src/utils/sessionInfoService.spec.d.ts.map +1 -0
- package/lib/src/utils/sessionInfoService.spec.js +127 -0
- package/lib/src/utils/sessionInfoService.spec.js.map +1 -0
- package/lib/src/utils.js +1 -1
- package/lib/src/utils.js.map +1 -1
- package/lib/src/utils.spec.js +159 -1
- package/lib/src/utils.spec.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +147 -7
- package/package.json +4 -10
- package/src/authToken.spec.ts +6 -0
- package/src/embed/app.spec.ts +15 -2
- package/src/embed/app.ts +13 -1
- package/src/embed/conversation.spec.ts +32 -0
- package/src/embed/conversation.ts +12 -0
- package/src/embed/embedConfig.spec.ts +79 -0
- package/src/embed/host-events.spec.ts +1635 -0
- package/src/embed/liveboard.ts +6 -0
- package/src/embed/spotter-viz-utils.ts +30 -0
- package/src/index.ts +2 -1
- package/src/mixpanel-service.spec.ts +15 -0
- package/src/types.ts +96 -6
- package/src/utils/custom-actions.spec.ts +28 -0
- package/src/utils/graphql/answerService/answerService.spec.ts +18 -0
- package/src/utils/processData.spec.ts +32 -0
- package/src/utils/reporting.spec.ts +27 -0
- package/src/utils/sessionInfoService.spec.ts +151 -0
- package/src/utils.spec.ts +195 -0
- package/src/utils.ts +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* @thoughtspot/visual-embed-sdk version 1.
|
|
1
|
+
/* @thoughtspot/visual-embed-sdk version 1.50.0 */
|
|
2
2
|
'use client';
|
|
3
3
|
const ALIAS = Symbol.for('yaml.alias');
|
|
4
4
|
const DOC = Symbol.for('yaml.document');
|
|
@@ -475,8 +475,7 @@ function createNodeAnchors(doc, prefix) {
|
|
|
475
475
|
return {
|
|
476
476
|
onAnchor: (source) => {
|
|
477
477
|
aliasObjects.push(source);
|
|
478
|
-
|
|
479
|
-
prevAnchors = anchorNames(doc);
|
|
478
|
+
prevAnchors ?? (prevAnchors = anchorNames(doc));
|
|
480
479
|
const anchor = findNewAnchor(prefix, prevAnchors);
|
|
481
480
|
prevAnchors.add(anchor);
|
|
482
481
|
return anchor;
|
|
@@ -640,23 +639,38 @@ class Alias extends NodeBase {
|
|
|
640
639
|
* Resolve the value of this alias within `doc`, finding the last
|
|
641
640
|
* instance of the `source` anchor before this node.
|
|
642
641
|
*/
|
|
643
|
-
resolve(doc) {
|
|
642
|
+
resolve(doc, ctx) {
|
|
643
|
+
if (ctx?.maxAliasCount === 0)
|
|
644
|
+
throw new ReferenceError('Alias resolution is disabled');
|
|
645
|
+
let nodes;
|
|
646
|
+
if (ctx?.aliasResolveCache) {
|
|
647
|
+
nodes = ctx.aliasResolveCache;
|
|
648
|
+
}
|
|
649
|
+
else {
|
|
650
|
+
nodes = [];
|
|
651
|
+
visit$1(doc, {
|
|
652
|
+
Node: (_key, node) => {
|
|
653
|
+
if (isAlias(node) || hasAnchor(node))
|
|
654
|
+
nodes.push(node);
|
|
655
|
+
}
|
|
656
|
+
});
|
|
657
|
+
if (ctx)
|
|
658
|
+
ctx.aliasResolveCache = nodes;
|
|
659
|
+
}
|
|
644
660
|
let found = undefined;
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
}
|
|
652
|
-
});
|
|
661
|
+
for (const node of nodes) {
|
|
662
|
+
if (node === this)
|
|
663
|
+
break;
|
|
664
|
+
if (node.anchor === this.source)
|
|
665
|
+
found = node;
|
|
666
|
+
}
|
|
653
667
|
return found;
|
|
654
668
|
}
|
|
655
669
|
toJSON(_arg, ctx) {
|
|
656
670
|
if (!ctx)
|
|
657
671
|
return { source: this.source };
|
|
658
672
|
const { anchors, doc, maxAliasCount } = ctx;
|
|
659
|
-
const source = this.resolve(doc);
|
|
673
|
+
const source = this.resolve(doc, ctx);
|
|
660
674
|
if (!source) {
|
|
661
675
|
const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;
|
|
662
676
|
throw new ReferenceError(msg);
|
|
@@ -668,7 +682,7 @@ class Alias extends NodeBase {
|
|
|
668
682
|
data = anchors.get(source);
|
|
669
683
|
}
|
|
670
684
|
/* istanbul ignore if */
|
|
671
|
-
if (
|
|
685
|
+
if (data?.res === undefined) {
|
|
672
686
|
const msg = 'This should not happen: Alias anchor was not resolved?';
|
|
673
687
|
throw new ReferenceError(msg);
|
|
674
688
|
}
|
|
@@ -775,8 +789,7 @@ function createNode(value, tagName, ctx) {
|
|
|
775
789
|
if (aliasDuplicateObjects && value && typeof value === 'object') {
|
|
776
790
|
ref = sourceObjects.get(value);
|
|
777
791
|
if (ref) {
|
|
778
|
-
|
|
779
|
-
ref.anchor = onAnchor(value);
|
|
792
|
+
ref.anchor ?? (ref.anchor = onAnchor(value));
|
|
780
793
|
return new Alias(ref.anchor);
|
|
781
794
|
}
|
|
782
795
|
else {
|
|
@@ -1287,7 +1300,7 @@ function blockString({ comment, type, value }, ctx, onComment, onChompKeep) {
|
|
|
1287
1300
|
const { blockQuote, commentString, lineWidth } = ctx.options;
|
|
1288
1301
|
// 1. Block can't end in whitespace unless the last line is non-empty.
|
|
1289
1302
|
// 2. Strings consisting of only whitespace are best rendered explicitly.
|
|
1290
|
-
if (!blockQuote || /\n[\t ]+$/.test(value)
|
|
1303
|
+
if (!blockQuote || /\n[\t ]+$/.test(value)) {
|
|
1291
1304
|
return quotedString(value, ctx);
|
|
1292
1305
|
}
|
|
1293
1306
|
const indent = ctx.indent ||
|
|
@@ -1347,23 +1360,32 @@ function blockString({ comment, type, value }, ctx, onComment, onChompKeep) {
|
|
|
1347
1360
|
start = start.replace(/\n+/g, `$&${indent}`);
|
|
1348
1361
|
}
|
|
1349
1362
|
const indentSize = indent ? '2' : '1'; // root is at -1
|
|
1350
|
-
|
|
1363
|
+
// Leading | or > is added later
|
|
1364
|
+
let header = (startWithSpace ? indentSize : '') + chomp;
|
|
1351
1365
|
if (comment) {
|
|
1352
1366
|
header += ' ' + commentString(comment.replace(/ ?[\r\n]+/g, ' '));
|
|
1353
1367
|
if (onComment)
|
|
1354
1368
|
onComment();
|
|
1355
1369
|
}
|
|
1356
|
-
if (literal) {
|
|
1357
|
-
|
|
1358
|
-
|
|
1370
|
+
if (!literal) {
|
|
1371
|
+
const foldedValue = value
|
|
1372
|
+
.replace(/\n+/g, '\n$&')
|
|
1373
|
+
.replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, '$1$2') // more-indented lines aren't folded
|
|
1374
|
+
// ^ more-ind. ^ empty ^ capture next empty lines only at end of indent
|
|
1375
|
+
.replace(/\n+/g, `$&${indent}`);
|
|
1376
|
+
let literalFallback = false;
|
|
1377
|
+
const foldOptions = getFoldOptions(ctx, true);
|
|
1378
|
+
if (blockQuote !== 'folded' && type !== Scalar.BLOCK_FOLDED) {
|
|
1379
|
+
foldOptions.onOverflow = () => {
|
|
1380
|
+
literalFallback = true;
|
|
1381
|
+
};
|
|
1382
|
+
}
|
|
1383
|
+
const body = foldFlowLines(`${start}${foldedValue}${end}`, indent, FOLD_BLOCK, foldOptions);
|
|
1384
|
+
if (!literalFallback)
|
|
1385
|
+
return `>${header}\n${indent}${body}`;
|
|
1359
1386
|
}
|
|
1360
|
-
value = value
|
|
1361
|
-
|
|
1362
|
-
.replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, '$1$2') // more-indented lines aren't folded
|
|
1363
|
-
// ^ more-ind. ^ empty ^ capture next empty lines only at end of indent
|
|
1364
|
-
.replace(/\n+/g, `$&${indent}`);
|
|
1365
|
-
const body = foldFlowLines(`${start}${value}${end}`, indent, FOLD_BLOCK, getFoldOptions(ctx, true));
|
|
1366
|
-
return `${header}\n${indent}${body}`;
|
|
1387
|
+
value = value.replace(/\n+/g, `$&${indent}`);
|
|
1388
|
+
return `|${header}\n${indent}${start}${value}${end}`;
|
|
1367
1389
|
}
|
|
1368
1390
|
function plainString(item, ctx, onComment, onChompKeep) {
|
|
1369
1391
|
const { type, value } = item;
|
|
@@ -1372,10 +1394,9 @@ function plainString(item, ctx, onComment, onChompKeep) {
|
|
|
1372
1394
|
(inFlow && /[[\]{},]/.test(value))) {
|
|
1373
1395
|
return quotedString(value, ctx);
|
|
1374
1396
|
}
|
|
1375
|
-
if (
|
|
1376
|
-
/^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(value)) {
|
|
1397
|
+
if (/^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(value)) {
|
|
1377
1398
|
// not allowed:
|
|
1378
|
-
// -
|
|
1399
|
+
// - '-' or '?'
|
|
1379
1400
|
// - start with an indicator character (except [?:-]) or /[?-] /
|
|
1380
1401
|
// - '\n ', ': ' or ' \n' anywhere
|
|
1381
1402
|
// - '#' not preceded by a non-space char
|
|
@@ -1470,6 +1491,7 @@ function createStringifyContext(doc, options) {
|
|
|
1470
1491
|
nullStr: 'null',
|
|
1471
1492
|
simpleKeys: false,
|
|
1472
1493
|
singleQuote: null,
|
|
1494
|
+
trailingComma: false,
|
|
1473
1495
|
trueStr: 'true',
|
|
1474
1496
|
verifyAliasOrder: true
|
|
1475
1497
|
}, doc.schema.toStringOptions, options);
|
|
@@ -1504,7 +1526,12 @@ function getTagObject(tags, item) {
|
|
|
1504
1526
|
let obj;
|
|
1505
1527
|
if (isScalar$1(item)) {
|
|
1506
1528
|
obj = item.value;
|
|
1507
|
-
|
|
1529
|
+
let match = tags.filter(t => t.identify?.(obj));
|
|
1530
|
+
if (match.length > 1) {
|
|
1531
|
+
const testMatch = match.filter(t => t.test);
|
|
1532
|
+
if (testMatch.length > 0)
|
|
1533
|
+
match = testMatch;
|
|
1534
|
+
}
|
|
1508
1535
|
tagObj =
|
|
1509
1536
|
match.find(t => t.format === item.format) ?? match.find(t => !t.format);
|
|
1510
1537
|
}
|
|
@@ -1513,7 +1540,7 @@ function getTagObject(tags, item) {
|
|
|
1513
1540
|
tagObj = tags.find(t => t.nodeClass && obj instanceof t.nodeClass);
|
|
1514
1541
|
}
|
|
1515
1542
|
if (!tagObj) {
|
|
1516
|
-
const name = obj?.constructor?.name ?? typeof obj;
|
|
1543
|
+
const name = obj?.constructor?.name ?? (obj === null ? 'null' : typeof obj);
|
|
1517
1544
|
throw new Error(`Tag not resolved for ${name} value`);
|
|
1518
1545
|
}
|
|
1519
1546
|
return tagObj;
|
|
@@ -1528,7 +1555,7 @@ function stringifyProps(node, tagObj, { anchors, doc }) {
|
|
|
1528
1555
|
anchors.add(anchor);
|
|
1529
1556
|
props.push(`&${anchor}`);
|
|
1530
1557
|
}
|
|
1531
|
-
const tag = node.tag
|
|
1558
|
+
const tag = node.tag ?? (tagObj.default ? null : tagObj.tag);
|
|
1532
1559
|
if (tag)
|
|
1533
1560
|
props.push(doc.directives.tagString(tag));
|
|
1534
1561
|
return props.join(' ');
|
|
@@ -1554,8 +1581,7 @@ function stringify$2(item, ctx, onComment, onChompKeep) {
|
|
|
1554
1581
|
const node = isNode(item)
|
|
1555
1582
|
? item
|
|
1556
1583
|
: ctx.doc.createNode(item, { onTagObj: o => (tagObj = o) });
|
|
1557
|
-
|
|
1558
|
-
tagObj = getTagObject(ctx.doc.schema.tags, node);
|
|
1584
|
+
tagObj ?? (tagObj = getTagObject(ctx.doc.schema.tags, node));
|
|
1559
1585
|
const props = stringifyProps(node, tagObj, ctx);
|
|
1560
1586
|
if (props.length > 0)
|
|
1561
1587
|
ctx.indentAtStart = (ctx.indentAtStart ?? 0) + props.length + 1;
|
|
@@ -1669,7 +1695,7 @@ function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
|
|
|
1669
1695
|
ws += `\n${indentComment(cs, ctx.indent)}`;
|
|
1670
1696
|
}
|
|
1671
1697
|
if (valueStr === '' && !ctx.inFlow) {
|
|
1672
|
-
if (ws === '\n')
|
|
1698
|
+
if (ws === '\n' && valueComment)
|
|
1673
1699
|
ws = '\n\n';
|
|
1674
1700
|
}
|
|
1675
1701
|
else {
|
|
@@ -1717,54 +1743,10 @@ function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
|
|
|
1717
1743
|
|
|
1718
1744
|
function warn(logLevel, warning) {
|
|
1719
1745
|
if (logLevel === 'debug' || logLevel === 'warn') {
|
|
1720
|
-
|
|
1721
|
-
process.emitWarning(warning);
|
|
1722
|
-
else
|
|
1723
|
-
console.warn(warning);
|
|
1746
|
+
console.warn(warning);
|
|
1724
1747
|
}
|
|
1725
1748
|
}
|
|
1726
1749
|
|
|
1727
|
-
const MERGE_KEY = '<<';
|
|
1728
|
-
function addPairToJSMap(ctx, map, { key, value }) {
|
|
1729
|
-
if (ctx?.doc.schema.merge && isMergeKey(key)) {
|
|
1730
|
-
value = isAlias(value) ? value.resolve(ctx.doc) : value;
|
|
1731
|
-
if (isSeq(value))
|
|
1732
|
-
for (const it of value.items)
|
|
1733
|
-
mergeToJSMap(ctx, map, it);
|
|
1734
|
-
else if (Array.isArray(value))
|
|
1735
|
-
for (const it of value)
|
|
1736
|
-
mergeToJSMap(ctx, map, it);
|
|
1737
|
-
else
|
|
1738
|
-
mergeToJSMap(ctx, map, value);
|
|
1739
|
-
}
|
|
1740
|
-
else {
|
|
1741
|
-
const jsKey = toJS(key, '', ctx);
|
|
1742
|
-
if (map instanceof Map) {
|
|
1743
|
-
map.set(jsKey, toJS(value, jsKey, ctx));
|
|
1744
|
-
}
|
|
1745
|
-
else if (map instanceof Set) {
|
|
1746
|
-
map.add(jsKey);
|
|
1747
|
-
}
|
|
1748
|
-
else {
|
|
1749
|
-
const stringKey = stringifyKey(key, jsKey, ctx);
|
|
1750
|
-
const jsValue = toJS(value, stringKey, ctx);
|
|
1751
|
-
if (stringKey in map)
|
|
1752
|
-
Object.defineProperty(map, stringKey, {
|
|
1753
|
-
value: jsValue,
|
|
1754
|
-
writable: true,
|
|
1755
|
-
enumerable: true,
|
|
1756
|
-
configurable: true
|
|
1757
|
-
});
|
|
1758
|
-
else
|
|
1759
|
-
map[stringKey] = jsValue;
|
|
1760
|
-
}
|
|
1761
|
-
}
|
|
1762
|
-
return map;
|
|
1763
|
-
}
|
|
1764
|
-
const isMergeKey = (key) => key === MERGE_KEY ||
|
|
1765
|
-
(isScalar$1(key) &&
|
|
1766
|
-
key.value === MERGE_KEY &&
|
|
1767
|
-
(!key.type || key.type === Scalar.PLAIN));
|
|
1768
1750
|
// If the value associated with a merge key is a single mapping node, each of
|
|
1769
1751
|
// its key/value pairs is inserted into the current mapping, unless the key
|
|
1770
1752
|
// already exists in it. If the value associated with the merge key is a
|
|
@@ -1772,8 +1754,36 @@ const isMergeKey = (key) => key === MERGE_KEY ||
|
|
|
1772
1754
|
// of these nodes is merged in turn according to its order in the sequence.
|
|
1773
1755
|
// Keys in mapping nodes earlier in the sequence override keys specified in
|
|
1774
1756
|
// later mapping nodes. -- http://yaml.org/type/merge.html
|
|
1775
|
-
|
|
1776
|
-
|
|
1757
|
+
const MERGE_KEY = '<<';
|
|
1758
|
+
const merge = {
|
|
1759
|
+
identify: value => value === MERGE_KEY ||
|
|
1760
|
+
(typeof value === 'symbol' && value.description === MERGE_KEY),
|
|
1761
|
+
default: 'key',
|
|
1762
|
+
tag: 'tag:yaml.org,2002:merge',
|
|
1763
|
+
test: /^<<$/,
|
|
1764
|
+
resolve: () => Object.assign(new Scalar(Symbol(MERGE_KEY)), {
|
|
1765
|
+
addToJSMap: addMergeToJSMap
|
|
1766
|
+
}),
|
|
1767
|
+
stringify: () => MERGE_KEY
|
|
1768
|
+
};
|
|
1769
|
+
const isMergeKey = (ctx, key) => (merge.identify(key) ||
|
|
1770
|
+
(isScalar$1(key) &&
|
|
1771
|
+
(!key.type || key.type === Scalar.PLAIN) &&
|
|
1772
|
+
merge.identify(key.value))) &&
|
|
1773
|
+
ctx?.doc.schema.tags.some(tag => tag.tag === merge.tag && tag.default);
|
|
1774
|
+
function addMergeToJSMap(ctx, map, value) {
|
|
1775
|
+
const source = resolveAliasValue(ctx, value);
|
|
1776
|
+
if (isSeq(source))
|
|
1777
|
+
for (const it of source.items)
|
|
1778
|
+
mergeValue(ctx, map, it);
|
|
1779
|
+
else if (Array.isArray(source))
|
|
1780
|
+
for (const it of source)
|
|
1781
|
+
mergeValue(ctx, map, it);
|
|
1782
|
+
else
|
|
1783
|
+
mergeValue(ctx, map, source);
|
|
1784
|
+
}
|
|
1785
|
+
function mergeValue(ctx, map, value) {
|
|
1786
|
+
const source = resolveAliasValue(ctx, value);
|
|
1777
1787
|
if (!isMap(source))
|
|
1778
1788
|
throw new Error('Merge sources must be maps or map aliases');
|
|
1779
1789
|
const srcMap = source.toJSON(null, ctx, Map);
|
|
@@ -1796,9 +1806,44 @@ function mergeToJSMap(ctx, map, value) {
|
|
|
1796
1806
|
}
|
|
1797
1807
|
return map;
|
|
1798
1808
|
}
|
|
1809
|
+
function resolveAliasValue(ctx, value) {
|
|
1810
|
+
return ctx && isAlias(value) ? value.resolve(ctx.doc, ctx) : value;
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
function addPairToJSMap(ctx, map, { key, value }) {
|
|
1814
|
+
if (isNode(key) && key.addToJSMap)
|
|
1815
|
+
key.addToJSMap(ctx, map, value);
|
|
1816
|
+
// TODO: Should drop this special case for bare << handling
|
|
1817
|
+
else if (isMergeKey(ctx, key))
|
|
1818
|
+
addMergeToJSMap(ctx, map, value);
|
|
1819
|
+
else {
|
|
1820
|
+
const jsKey = toJS(key, '', ctx);
|
|
1821
|
+
if (map instanceof Map) {
|
|
1822
|
+
map.set(jsKey, toJS(value, jsKey, ctx));
|
|
1823
|
+
}
|
|
1824
|
+
else if (map instanceof Set) {
|
|
1825
|
+
map.add(jsKey);
|
|
1826
|
+
}
|
|
1827
|
+
else {
|
|
1828
|
+
const stringKey = stringifyKey(key, jsKey, ctx);
|
|
1829
|
+
const jsValue = toJS(value, stringKey, ctx);
|
|
1830
|
+
if (stringKey in map)
|
|
1831
|
+
Object.defineProperty(map, stringKey, {
|
|
1832
|
+
value: jsValue,
|
|
1833
|
+
writable: true,
|
|
1834
|
+
enumerable: true,
|
|
1835
|
+
configurable: true
|
|
1836
|
+
});
|
|
1837
|
+
else
|
|
1838
|
+
map[stringKey] = jsValue;
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
return map;
|
|
1842
|
+
}
|
|
1799
1843
|
function stringifyKey(key, jsKey, ctx) {
|
|
1800
1844
|
if (jsKey === null)
|
|
1801
1845
|
return '';
|
|
1846
|
+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
1802
1847
|
if (typeof jsKey !== 'object')
|
|
1803
1848
|
return String(jsKey);
|
|
1804
1849
|
if (isNode(key) && ctx?.doc) {
|
|
@@ -1951,12 +1996,22 @@ function stringifyFlowCollection({ items }, ctx, { flowChars, itemIndent }) {
|
|
|
1951
1996
|
if (comment)
|
|
1952
1997
|
reqNewline = true;
|
|
1953
1998
|
let str = stringify$2(item, itemCtx, () => (comment = null));
|
|
1954
|
-
|
|
1999
|
+
reqNewline || (reqNewline = lines.length > linesAtValue || str.includes('\n'));
|
|
2000
|
+
if (i < items.length - 1) {
|
|
1955
2001
|
str += ',';
|
|
2002
|
+
}
|
|
2003
|
+
else if (ctx.options.trailingComma) {
|
|
2004
|
+
if (ctx.options.lineWidth > 0) {
|
|
2005
|
+
reqNewline || (reqNewline = lines.reduce((sum, line) => sum + line.length + 2, 2) +
|
|
2006
|
+
(str.length + 2) >
|
|
2007
|
+
ctx.options.lineWidth);
|
|
2008
|
+
}
|
|
2009
|
+
if (reqNewline) {
|
|
2010
|
+
str += ',';
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
1956
2013
|
if (comment)
|
|
1957
2014
|
str += lineComment(str, itemIndent, commentString(comment));
|
|
1958
|
-
if (!reqNewline && (lines.length > linesAtValue || str.includes('\n')))
|
|
1959
|
-
reqNewline = true;
|
|
1960
2015
|
lines.push(str);
|
|
1961
2016
|
linesAtValue = lines.length;
|
|
1962
2017
|
}
|
|
@@ -2301,11 +2356,12 @@ function stringifyNumber({ format, minFractionDigits, tag, value }) {
|
|
|
2301
2356
|
const num = typeof value === 'number' ? value : Number(value);
|
|
2302
2357
|
if (!isFinite(num))
|
|
2303
2358
|
return isNaN(num) ? '.nan' : num < 0 ? '-.inf' : '.inf';
|
|
2304
|
-
let n = JSON.stringify(value);
|
|
2359
|
+
let n = Object.is(value, -0) ? '-0' : JSON.stringify(value);
|
|
2305
2360
|
if (!format &&
|
|
2306
2361
|
minFractionDigits &&
|
|
2307
2362
|
(!tag || tag === 'tag:yaml.org,2002:float') &&
|
|
2308
|
-
|
|
2363
|
+
/^-?\d/.test(n) &&
|
|
2364
|
+
!n.includes('e')) {
|
|
2309
2365
|
let i = n.indexOf('.');
|
|
2310
2366
|
if (i < 0) {
|
|
2311
2367
|
i = n.length;
|
|
@@ -2431,7 +2487,7 @@ const jsonScalars = [
|
|
|
2431
2487
|
identify: value => typeof value === 'boolean',
|
|
2432
2488
|
default: true,
|
|
2433
2489
|
tag: 'tag:yaml.org,2002:bool',
|
|
2434
|
-
test: /^true
|
|
2490
|
+
test: /^true$|^false$/,
|
|
2435
2491
|
resolve: str => str === 'true',
|
|
2436
2492
|
stringify: stringifyJSON
|
|
2437
2493
|
},
|
|
@@ -2476,10 +2532,7 @@ const binary = {
|
|
|
2476
2532
|
* document.querySelector('#photo').src = URL.createObjectURL(blob)
|
|
2477
2533
|
*/
|
|
2478
2534
|
resolve(src, onError) {
|
|
2479
|
-
if (typeof
|
|
2480
|
-
return Buffer.from(src, 'base64');
|
|
2481
|
-
}
|
|
2482
|
-
else if (typeof atob === 'function') {
|
|
2535
|
+
if (typeof atob === 'function') {
|
|
2483
2536
|
// On IE 11, atob() can't handle newlines
|
|
2484
2537
|
const str = atob(src.replace(/[\n\r]/g, ''));
|
|
2485
2538
|
const buffer = new Uint8Array(str.length);
|
|
@@ -2493,15 +2546,11 @@ const binary = {
|
|
|
2493
2546
|
}
|
|
2494
2547
|
},
|
|
2495
2548
|
stringify({ comment, type, value }, ctx, onComment, onChompKeep) {
|
|
2549
|
+
if (!value)
|
|
2550
|
+
return '';
|
|
2496
2551
|
const buf = value; // checked earlier by binary.identify()
|
|
2497
2552
|
let str;
|
|
2498
|
-
if (typeof
|
|
2499
|
-
str =
|
|
2500
|
-
buf instanceof Buffer
|
|
2501
|
-
? buf.toString('base64')
|
|
2502
|
-
: Buffer.from(buf.buffer).toString('base64');
|
|
2503
|
-
}
|
|
2504
|
-
else if (typeof btoa === 'function') {
|
|
2553
|
+
if (typeof btoa === 'function') {
|
|
2505
2554
|
let s = '';
|
|
2506
2555
|
for (let i = 0; i < buf.length; ++i)
|
|
2507
2556
|
s += String.fromCharCode(buf[i]);
|
|
@@ -2510,8 +2559,7 @@ const binary = {
|
|
|
2510
2559
|
else {
|
|
2511
2560
|
throw new Error('This environment does not support writing binary tags; either Buffer or btoa is required');
|
|
2512
2561
|
}
|
|
2513
|
-
|
|
2514
|
-
type = Scalar.BLOCK_LITERAL;
|
|
2562
|
+
type ?? (type = Scalar.BLOCK_LITERAL);
|
|
2515
2563
|
if (type !== Scalar.QUOTE_DOUBLE) {
|
|
2516
2564
|
const lineWidth = Math.max(ctx.options.lineWidth - ctx.indent.length, ctx.options.minContentWidth);
|
|
2517
2565
|
const n = Math.ceil(str.length / lineWidth);
|
|
@@ -2980,7 +3028,7 @@ const timestamp = {
|
|
|
2980
3028
|
}
|
|
2981
3029
|
return new Date(date);
|
|
2982
3030
|
},
|
|
2983
|
-
stringify: ({ value }) => value
|
|
3031
|
+
stringify: ({ value }) => value?.toISOString().replace(/(T00:00:00)?\.000Z$/, '') ?? ''
|
|
2984
3032
|
};
|
|
2985
3033
|
|
|
2986
3034
|
const schema = [
|
|
@@ -2998,6 +3046,7 @@ const schema = [
|
|
|
2998
3046
|
floatExp,
|
|
2999
3047
|
float,
|
|
3000
3048
|
binary,
|
|
3049
|
+
merge,
|
|
3001
3050
|
omap,
|
|
3002
3051
|
pairs,
|
|
3003
3052
|
set,
|
|
@@ -3025,6 +3074,7 @@ const tagsByName = {
|
|
|
3025
3074
|
intOct: intOct$1,
|
|
3026
3075
|
intTime,
|
|
3027
3076
|
map,
|
|
3077
|
+
merge,
|
|
3028
3078
|
null: nullTag,
|
|
3029
3079
|
omap,
|
|
3030
3080
|
pairs,
|
|
@@ -3034,13 +3084,20 @@ const tagsByName = {
|
|
|
3034
3084
|
};
|
|
3035
3085
|
const coreKnownTags = {
|
|
3036
3086
|
'tag:yaml.org,2002:binary': binary,
|
|
3087
|
+
'tag:yaml.org,2002:merge': merge,
|
|
3037
3088
|
'tag:yaml.org,2002:omap': omap,
|
|
3038
3089
|
'tag:yaml.org,2002:pairs': pairs,
|
|
3039
3090
|
'tag:yaml.org,2002:set': set,
|
|
3040
3091
|
'tag:yaml.org,2002:timestamp': timestamp
|
|
3041
3092
|
};
|
|
3042
|
-
function getTags(customTags, schemaName) {
|
|
3043
|
-
|
|
3093
|
+
function getTags(customTags, schemaName, addMergeTag) {
|
|
3094
|
+
const schemaTags = schemas.get(schemaName);
|
|
3095
|
+
if (schemaTags && !customTags) {
|
|
3096
|
+
return addMergeTag && !schemaTags.includes(merge)
|
|
3097
|
+
? schemaTags.concat(merge)
|
|
3098
|
+
: schemaTags.slice();
|
|
3099
|
+
}
|
|
3100
|
+
let tags = schemaTags;
|
|
3044
3101
|
if (!tags) {
|
|
3045
3102
|
if (Array.isArray(customTags))
|
|
3046
3103
|
tags = [];
|
|
@@ -3059,17 +3116,21 @@ function getTags(customTags, schemaName) {
|
|
|
3059
3116
|
else if (typeof customTags === 'function') {
|
|
3060
3117
|
tags = customTags(tags.slice());
|
|
3061
3118
|
}
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
const tagObj = tagsByName[tag];
|
|
3066
|
-
if (tagObj)
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3119
|
+
if (addMergeTag)
|
|
3120
|
+
tags = tags.concat(merge);
|
|
3121
|
+
return tags.reduce((tags, tag) => {
|
|
3122
|
+
const tagObj = typeof tag === 'string' ? tagsByName[tag] : tag;
|
|
3123
|
+
if (!tagObj) {
|
|
3124
|
+
const tagName = JSON.stringify(tag);
|
|
3125
|
+
const keys = Object.keys(tagsByName)
|
|
3126
|
+
.map(key => JSON.stringify(key))
|
|
3127
|
+
.join(', ');
|
|
3128
|
+
throw new Error(`Unknown custom tag ${tagName}; use one of ${keys}`);
|
|
3129
|
+
}
|
|
3130
|
+
if (!tags.includes(tagObj))
|
|
3131
|
+
tags.push(tagObj);
|
|
3132
|
+
return tags;
|
|
3133
|
+
}, []);
|
|
3073
3134
|
}
|
|
3074
3135
|
|
|
3075
3136
|
const sortMapEntriesByKey = (a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0;
|
|
@@ -3080,10 +3141,9 @@ class Schema {
|
|
|
3080
3141
|
: compat
|
|
3081
3142
|
? getTags(null, compat)
|
|
3082
3143
|
: null;
|
|
3083
|
-
this.merge = !!merge;
|
|
3084
3144
|
this.name = (typeof schema === 'string' && schema) || 'core';
|
|
3085
3145
|
this.knownTags = resolveKnownTags ? coreKnownTags : {};
|
|
3086
|
-
this.tags = getTags(customTags, this.name);
|
|
3146
|
+
this.tags = getTags(customTags, this.name, merge);
|
|
3087
3147
|
this.toStringOptions = toStringDefaults ?? null;
|
|
3088
3148
|
Object.defineProperty(this, MAP, { value: map });
|
|
3089
3149
|
Object.defineProperty(this, SCALAR$1, { value: string });
|
|
@@ -3208,6 +3268,7 @@ class Document {
|
|
|
3208
3268
|
logLevel: 'warn',
|
|
3209
3269
|
prettyErrors: true,
|
|
3210
3270
|
strict: true,
|
|
3271
|
+
stringKeys: false,
|
|
3211
3272
|
uniqueKeys: true,
|
|
3212
3273
|
version: '1.2'
|
|
3213
3274
|
}, options);
|
|
@@ -3431,7 +3492,7 @@ class Document {
|
|
|
3431
3492
|
this.directives.yaml.version = '1.1';
|
|
3432
3493
|
else
|
|
3433
3494
|
this.directives = new Directives({ version: '1.1' });
|
|
3434
|
-
opt = {
|
|
3495
|
+
opt = { resolveKnownTags: false, schema: 'yaml-1.1' };
|
|
3435
3496
|
break;
|
|
3436
3497
|
case '1.2':
|
|
3437
3498
|
case 'next':
|
|
@@ -3439,7 +3500,7 @@ class Document {
|
|
|
3439
3500
|
this.directives.yaml.version = version;
|
|
3440
3501
|
else
|
|
3441
3502
|
this.directives = new Directives({ version });
|
|
3442
|
-
opt = {
|
|
3503
|
+
opt = { resolveKnownTags: true, schema: 'core' };
|
|
3443
3504
|
break;
|
|
3444
3505
|
case null:
|
|
3445
3506
|
if (this.directives)
|
|
@@ -3552,7 +3613,7 @@ const prettifyError = (src, lc) => (error) => {
|
|
|
3552
3613
|
if (/[^ ]/.test(lineStr)) {
|
|
3553
3614
|
let count = 1;
|
|
3554
3615
|
const end = error.linePos[1];
|
|
3555
|
-
if (end
|
|
3616
|
+
if (end?.line === line && end.col > col) {
|
|
3556
3617
|
count = Math.max(1, Math.min(end.col - col, 80 - ci));
|
|
3557
3618
|
}
|
|
3558
3619
|
const pointer = ' '.repeat(ci) + '^'.repeat(count);
|
|
@@ -3617,7 +3678,7 @@ function resolveProps(tokens, { flow, indicator, next, offset, onError, parentIn
|
|
|
3617
3678
|
if (atNewline) {
|
|
3618
3679
|
if (comment)
|
|
3619
3680
|
comment += token.source;
|
|
3620
|
-
else
|
|
3681
|
+
else if (!found || indicator !== 'seq-item-ind')
|
|
3621
3682
|
spaceBefore = true;
|
|
3622
3683
|
}
|
|
3623
3684
|
else
|
|
@@ -3634,8 +3695,7 @@ function resolveProps(tokens, { flow, indicator, next, offset, onError, parentIn
|
|
|
3634
3695
|
if (token.source.endsWith(':'))
|
|
3635
3696
|
onError(token.offset + token.source.length - 1, 'BAD_ALIAS', 'Anchor ending in : is ambiguous', true);
|
|
3636
3697
|
anchor = token;
|
|
3637
|
-
|
|
3638
|
-
start = token.offset;
|
|
3698
|
+
start ?? (start = token.offset);
|
|
3639
3699
|
atNewline = false;
|
|
3640
3700
|
hasSpace = false;
|
|
3641
3701
|
reqSpace = true;
|
|
@@ -3644,8 +3704,7 @@ function resolveProps(tokens, { flow, indicator, next, offset, onError, parentIn
|
|
|
3644
3704
|
if (tag)
|
|
3645
3705
|
onError(token, 'MULTIPLE_TAGS', 'A node can have at most one tag');
|
|
3646
3706
|
tag = token;
|
|
3647
|
-
|
|
3648
|
-
start = token.offset;
|
|
3707
|
+
start ?? (start = token.offset);
|
|
3649
3708
|
atNewline = false;
|
|
3650
3709
|
hasSpace = false;
|
|
3651
3710
|
reqSpace = true;
|
|
@@ -3758,11 +3817,7 @@ function mapIncludes(ctx, items, search) {
|
|
|
3758
3817
|
return false;
|
|
3759
3818
|
const isEqual = typeof uniqueKeys === 'function'
|
|
3760
3819
|
? uniqueKeys
|
|
3761
|
-
: (a, b) => a === b ||
|
|
3762
|
-
(isScalar$1(a) &&
|
|
3763
|
-
isScalar$1(b) &&
|
|
3764
|
-
a.value === b.value &&
|
|
3765
|
-
!(a.value === '<<' && ctx.schema.merge));
|
|
3820
|
+
: (a, b) => a === b || (isScalar$1(a) && isScalar$1(b) && a.value === b.value);
|
|
3766
3821
|
return items.some(pair => isEqual(pair.key, search));
|
|
3767
3822
|
}
|
|
3768
3823
|
|
|
@@ -3811,12 +3866,14 @@ function resolveBlockMap({ composeNode, composeEmptyNode }, ctx, bm, onError, ta
|
|
|
3811
3866
|
onError(offset, 'BAD_INDENT', startColMsg);
|
|
3812
3867
|
}
|
|
3813
3868
|
// key value
|
|
3869
|
+
ctx.atKey = true;
|
|
3814
3870
|
const keyStart = keyProps.end;
|
|
3815
3871
|
const keyNode = key
|
|
3816
3872
|
? composeNode(ctx, key, keyProps, onError)
|
|
3817
3873
|
: composeEmptyNode(ctx, keyStart, start, null, keyProps, onError);
|
|
3818
3874
|
if (ctx.schema.compat)
|
|
3819
3875
|
flowIndentCheck(bm.indent, key, onError);
|
|
3876
|
+
ctx.atKey = false;
|
|
3820
3877
|
if (mapIncludes(ctx, map.items, keyNode))
|
|
3821
3878
|
onError(keyStart, 'DUPLICATE_KEY', 'Map keys must be unique');
|
|
3822
3879
|
// value properties
|
|
@@ -3876,6 +3933,8 @@ function resolveBlockSeq({ composeNode, composeEmptyNode }, ctx, bs, onError, ta
|
|
|
3876
3933
|
const seq = new NodeClass(ctx.schema);
|
|
3877
3934
|
if (ctx.atRoot)
|
|
3878
3935
|
ctx.atRoot = false;
|
|
3936
|
+
if (ctx.atKey)
|
|
3937
|
+
ctx.atKey = false;
|
|
3879
3938
|
let offset = bs.offset;
|
|
3880
3939
|
let commentEnd = null;
|
|
3881
3940
|
for (const { start, value } of bs.items) {
|
|
@@ -3889,7 +3948,7 @@ function resolveBlockSeq({ composeNode, composeEmptyNode }, ctx, bs, onError, ta
|
|
|
3889
3948
|
});
|
|
3890
3949
|
if (!props.found) {
|
|
3891
3950
|
if (props.anchor || props.tag || value) {
|
|
3892
|
-
if (value
|
|
3951
|
+
if (value?.type === 'block-seq')
|
|
3893
3952
|
onError(props.end, 'BAD_INDENT', 'All sequence items must start at the same column');
|
|
3894
3953
|
else
|
|
3895
3954
|
onError(offset, 'MISSING_CHAR', 'Sequence item without - indicator');
|
|
@@ -3960,6 +4019,8 @@ function resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onErr
|
|
|
3960
4019
|
const atRoot = ctx.atRoot;
|
|
3961
4020
|
if (atRoot)
|
|
3962
4021
|
ctx.atRoot = false;
|
|
4022
|
+
if (ctx.atKey)
|
|
4023
|
+
ctx.atKey = false;
|
|
3963
4024
|
let offset = fc.offset + fc.start.source.length;
|
|
3964
4025
|
for (let i = 0; i < fc.items.length; ++i) {
|
|
3965
4026
|
const collItem = fc.items[i];
|
|
@@ -4039,12 +4100,14 @@ function resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onErr
|
|
|
4039
4100
|
else {
|
|
4040
4101
|
// item is a key+value pair
|
|
4041
4102
|
// key value
|
|
4103
|
+
ctx.atKey = true;
|
|
4042
4104
|
const keyStart = props.end;
|
|
4043
4105
|
const keyNode = key
|
|
4044
4106
|
? composeNode(ctx, key, props, onError)
|
|
4045
4107
|
: composeEmptyNode(ctx, keyStart, start, null, props, onError);
|
|
4046
4108
|
if (isBlock(key))
|
|
4047
4109
|
onError(keyNode.range, 'BLOCK_IN_FLOW', blockMsg);
|
|
4110
|
+
ctx.atKey = false;
|
|
4048
4111
|
// value properties
|
|
4049
4112
|
const valueProps = resolveProps(sep ?? [], {
|
|
4050
4113
|
flow: fcName,
|
|
@@ -4071,7 +4134,7 @@ function resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onErr
|
|
|
4071
4134
|
}
|
|
4072
4135
|
}
|
|
4073
4136
|
else if (value) {
|
|
4074
|
-
if ('source' in value && value.source
|
|
4137
|
+
if ('source' in value && value.source?.[0] === ':')
|
|
4075
4138
|
onError(value, 'MISSING_CHAR', `Missing space after : in ${fcName}`);
|
|
4076
4139
|
else
|
|
4077
4140
|
onError(valueProps.start, 'MISSING_CHAR', `Missing , or : between ${fcName} items`);
|
|
@@ -4115,7 +4178,7 @@ function resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onErr
|
|
|
4115
4178
|
const expectedEnd = isMap ? '}' : ']';
|
|
4116
4179
|
const [ce, ...ee] = fc.end;
|
|
4117
4180
|
let cePos = offset;
|
|
4118
|
-
if (ce
|
|
4181
|
+
if (ce?.source === expectedEnd)
|
|
4119
4182
|
cePos = ce.offset + ce.source.length;
|
|
4120
4183
|
else {
|
|
4121
4184
|
const name = fcName[0].toUpperCase() + fcName.substring(1);
|
|
@@ -4195,13 +4258,13 @@ function composeCollection(CN, ctx, token, props, onError) {
|
|
|
4195
4258
|
let tag = ctx.schema.tags.find(t => t.tag === tagName && t.collection === expType);
|
|
4196
4259
|
if (!tag) {
|
|
4197
4260
|
const kt = ctx.schema.knownTags[tagName];
|
|
4198
|
-
if (kt
|
|
4261
|
+
if (kt?.collection === expType) {
|
|
4199
4262
|
ctx.schema.tags.push(Object.assign({}, kt, { default: false }));
|
|
4200
4263
|
tag = kt;
|
|
4201
4264
|
}
|
|
4202
4265
|
else {
|
|
4203
|
-
if (kt
|
|
4204
|
-
onError(tagToken, 'BAD_COLLECTION_TYPE', `${kt.tag} used for ${expType} collection, but expects ${kt.collection}`, true);
|
|
4266
|
+
if (kt) {
|
|
4267
|
+
onError(tagToken, 'BAD_COLLECTION_TYPE', `${kt.tag} used for ${expType} collection, but expects ${kt.collection ?? 'scalar'}`, true);
|
|
4205
4268
|
}
|
|
4206
4269
|
else {
|
|
4207
4270
|
onError(tagToken, 'TAG_RESOLVE_FAILED', `Unresolved tag: ${tagName}`, true);
|
|
@@ -4557,7 +4620,7 @@ function doubleQuotedValue(source, onError) {
|
|
|
4557
4620
|
next = source[++i + 1];
|
|
4558
4621
|
}
|
|
4559
4622
|
else if (next === 'x' || next === 'u' || next === 'U') {
|
|
4560
|
-
const length =
|
|
4623
|
+
const length = next === 'x' ? 2 : next === 'u' ? 4 : 8;
|
|
4561
4624
|
res += parseCharCode(source, i + 1, length, onError);
|
|
4562
4625
|
i += length;
|
|
4563
4626
|
}
|
|
@@ -4627,12 +4690,14 @@ function parseCharCode(source, offset, length, onError) {
|
|
|
4627
4690
|
const cc = source.substr(offset, length);
|
|
4628
4691
|
const ok = cc.length === length && /^[0-9a-fA-F]+$/.test(cc);
|
|
4629
4692
|
const code = ok ? parseInt(cc, 16) : NaN;
|
|
4630
|
-
|
|
4693
|
+
try {
|
|
4694
|
+
return String.fromCodePoint(code);
|
|
4695
|
+
}
|
|
4696
|
+
catch {
|
|
4631
4697
|
const raw = source.substr(offset - 2, length + 2);
|
|
4632
4698
|
onError(offset - 2, 'BAD_DQ_ESCAPE', `Invalid escape sequence ${raw}`);
|
|
4633
4699
|
return raw;
|
|
4634
4700
|
}
|
|
4635
|
-
return String.fromCodePoint(code);
|
|
4636
4701
|
}
|
|
4637
4702
|
|
|
4638
4703
|
function composeScalar(ctx, token, tagToken, onError) {
|
|
@@ -4642,11 +4707,16 @@ function composeScalar(ctx, token, tagToken, onError) {
|
|
|
4642
4707
|
const tagName = tagToken
|
|
4643
4708
|
? ctx.directives.tagName(tagToken.source, msg => onError(tagToken, 'TAG_RESOLVE_FAILED', msg))
|
|
4644
4709
|
: null;
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4710
|
+
let tag;
|
|
4711
|
+
if (ctx.options.stringKeys && ctx.atKey) {
|
|
4712
|
+
tag = ctx.schema[SCALAR$1];
|
|
4713
|
+
}
|
|
4714
|
+
else if (tagName)
|
|
4715
|
+
tag = findScalarTagByName(ctx.schema, value, tagName, tagToken, onError);
|
|
4716
|
+
else if (token.type === 'scalar')
|
|
4717
|
+
tag = findScalarTagByTest(ctx, value, token, onError);
|
|
4718
|
+
else
|
|
4719
|
+
tag = ctx.schema[SCALAR$1];
|
|
4650
4720
|
let scalar;
|
|
4651
4721
|
try {
|
|
4652
4722
|
const res = tag.resolve(value, msg => onError(tagToken ?? token, 'TAG_RESOLVE_FAILED', msg), ctx.options);
|
|
@@ -4694,8 +4764,9 @@ function findScalarTagByName(schema, value, tagName, tagToken, onError) {
|
|
|
4694
4764
|
onError(tagToken, 'TAG_RESOLVE_FAILED', `Unresolved tag: ${tagName}`, tagName !== 'tag:yaml.org,2002:str');
|
|
4695
4765
|
return schema[SCALAR$1];
|
|
4696
4766
|
}
|
|
4697
|
-
function findScalarTagByTest({ directives, schema }, value, token, onError) {
|
|
4698
|
-
const tag = schema.tags.find(tag => tag.default && tag.
|
|
4767
|
+
function findScalarTagByTest({ atKey, directives, schema }, value, token, onError) {
|
|
4768
|
+
const tag = schema.tags.find(tag => (tag.default === true || (atKey && tag.default === 'key')) &&
|
|
4769
|
+
tag.test?.test(value)) || schema[SCALAR$1];
|
|
4699
4770
|
if (schema.compat) {
|
|
4700
4771
|
const compat = schema.compat.find(tag => tag.default && tag.test?.test(value)) ??
|
|
4701
4772
|
schema[SCALAR$1];
|
|
@@ -4711,8 +4782,7 @@ function findScalarTagByTest({ directives, schema }, value, token, onError) {
|
|
|
4711
4782
|
|
|
4712
4783
|
function emptyScalarPosition(offset, before, pos) {
|
|
4713
4784
|
if (before) {
|
|
4714
|
-
|
|
4715
|
-
pos = before.length;
|
|
4785
|
+
pos ?? (pos = before.length);
|
|
4716
4786
|
for (let i = pos - 1; i >= 0; --i) {
|
|
4717
4787
|
let st = before[i];
|
|
4718
4788
|
switch (st.type) {
|
|
@@ -4737,6 +4807,7 @@ function emptyScalarPosition(offset, before, pos) {
|
|
|
4737
4807
|
|
|
4738
4808
|
const CN = { composeNode, composeEmptyNode };
|
|
4739
4809
|
function composeNode(ctx, token, props, onError) {
|
|
4810
|
+
const atKey = ctx.atKey;
|
|
4740
4811
|
const { spaceBefore, comment, anchor, tag } = props;
|
|
4741
4812
|
let node;
|
|
4742
4813
|
let isSrcToken = true;
|
|
@@ -4757,21 +4828,36 @@ function composeNode(ctx, token, props, onError) {
|
|
|
4757
4828
|
case 'block-map':
|
|
4758
4829
|
case 'block-seq':
|
|
4759
4830
|
case 'flow-collection':
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4831
|
+
try {
|
|
4832
|
+
node = composeCollection(CN, ctx, token, props, onError);
|
|
4833
|
+
if (anchor)
|
|
4834
|
+
node.anchor = anchor.source.substring(1);
|
|
4835
|
+
}
|
|
4836
|
+
catch (error) {
|
|
4837
|
+
// Almost certainly here due to a stack overflow
|
|
4838
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4839
|
+
onError(token, 'RESOURCE_EXHAUSTION', message);
|
|
4840
|
+
}
|
|
4763
4841
|
break;
|
|
4764
4842
|
default: {
|
|
4765
4843
|
const message = token.type === 'error'
|
|
4766
4844
|
? token.message
|
|
4767
4845
|
: `Unsupported token (type: ${token.type})`;
|
|
4768
4846
|
onError(token, 'UNEXPECTED_TOKEN', message);
|
|
4769
|
-
node = composeEmptyNode(ctx, token.offset, undefined, null, props, onError);
|
|
4770
4847
|
isSrcToken = false;
|
|
4771
4848
|
}
|
|
4772
4849
|
}
|
|
4850
|
+
node ?? (node = composeEmptyNode(ctx, token.offset, undefined, null, props, onError));
|
|
4773
4851
|
if (anchor && node.anchor === '')
|
|
4774
4852
|
onError(anchor, 'BAD_ALIAS', 'Anchor cannot be an empty string');
|
|
4853
|
+
if (atKey &&
|
|
4854
|
+
ctx.options.stringKeys &&
|
|
4855
|
+
(!isScalar$1(node) ||
|
|
4856
|
+
typeof node.value !== 'string' ||
|
|
4857
|
+
(node.tag && node.tag !== 'tag:yaml.org,2002:str'))) {
|
|
4858
|
+
const msg = 'With stringKeys, all keys must be strings';
|
|
4859
|
+
onError(tag ?? token, 'NON_STRING_KEY', msg);
|
|
4860
|
+
}
|
|
4775
4861
|
if (spaceBefore)
|
|
4776
4862
|
node.spaceBefore = true;
|
|
4777
4863
|
if (comment) {
|
|
@@ -4824,6 +4910,7 @@ function composeDoc(options, directives, { offset, start, value, end }, onError)
|
|
|
4824
4910
|
const opts = Object.assign({ _directives: directives }, options);
|
|
4825
4911
|
const doc = new Document(undefined, opts);
|
|
4826
4912
|
const ctx = {
|
|
4913
|
+
atKey: false,
|
|
4827
4914
|
atRoot: true,
|
|
4828
4915
|
directives: doc.directives,
|
|
4829
4916
|
options: doc.options,
|
|
@@ -4945,8 +5032,10 @@ class Composer {
|
|
|
4945
5032
|
}
|
|
4946
5033
|
}
|
|
4947
5034
|
if (afterDoc) {
|
|
4948
|
-
|
|
4949
|
-
|
|
5035
|
+
for (let i = 0; i < this.errors.length; ++i)
|
|
5036
|
+
doc.errors.push(this.errors[i]);
|
|
5037
|
+
for (let i = 0; i < this.warnings.length; ++i)
|
|
5038
|
+
doc.warnings.push(this.warnings[i]);
|
|
4950
5039
|
}
|
|
4951
5040
|
else {
|
|
4952
5041
|
doc.errors = this.errors;
|
|
@@ -5849,7 +5938,7 @@ class Lexer {
|
|
|
5849
5938
|
const n = (yield* this.pushCount(1)) + (yield* this.pushSpaces(true));
|
|
5850
5939
|
this.indentNext = this.indentValue + 1;
|
|
5851
5940
|
this.indentValue += n;
|
|
5852
|
-
return
|
|
5941
|
+
return 'block-start';
|
|
5853
5942
|
}
|
|
5854
5943
|
return 'doc';
|
|
5855
5944
|
}
|
|
@@ -6170,32 +6259,36 @@ class Lexer {
|
|
|
6170
6259
|
return 0;
|
|
6171
6260
|
}
|
|
6172
6261
|
*pushIndicators() {
|
|
6173
|
-
|
|
6174
|
-
|
|
6175
|
-
|
|
6176
|
-
|
|
6177
|
-
|
|
6178
|
-
|
|
6179
|
-
|
|
6180
|
-
|
|
6181
|
-
|
|
6182
|
-
|
|
6183
|
-
|
|
6184
|
-
|
|
6185
|
-
|
|
6186
|
-
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
|
|
6262
|
+
let n = 0;
|
|
6263
|
+
loop: while (true) {
|
|
6264
|
+
switch (this.charAt(0)) {
|
|
6265
|
+
case '!':
|
|
6266
|
+
n += yield* this.pushTag();
|
|
6267
|
+
n += yield* this.pushSpaces(true);
|
|
6268
|
+
continue loop;
|
|
6269
|
+
case '&':
|
|
6270
|
+
n += yield* this.pushUntil(isNotAnchorChar);
|
|
6271
|
+
n += yield* this.pushSpaces(true);
|
|
6272
|
+
continue loop;
|
|
6273
|
+
case '-': // this is an error
|
|
6274
|
+
case '?': // this is an error outside flow collections
|
|
6275
|
+
case ':': {
|
|
6276
|
+
const inFlow = this.flowLevel > 0;
|
|
6277
|
+
const ch1 = this.charAt(1);
|
|
6278
|
+
if (isEmpty(ch1) || (inFlow && flowIndicatorChars.has(ch1))) {
|
|
6279
|
+
if (!inFlow)
|
|
6280
|
+
this.indentNext = this.indentValue + 1;
|
|
6281
|
+
else if (this.flowKey)
|
|
6282
|
+
this.flowKey = false;
|
|
6283
|
+
n += yield* this.pushCount(1);
|
|
6284
|
+
n += yield* this.pushSpaces(true);
|
|
6285
|
+
continue loop;
|
|
6286
|
+
}
|
|
6195
6287
|
}
|
|
6196
6288
|
}
|
|
6289
|
+
break loop;
|
|
6197
6290
|
}
|
|
6198
|
-
return
|
|
6291
|
+
return n;
|
|
6199
6292
|
}
|
|
6200
6293
|
*pushTag() {
|
|
6201
6294
|
if (this.charAt(1) === '<') {
|
|
@@ -6357,6 +6450,14 @@ function getFirstKeyStartProps(prev) {
|
|
|
6357
6450
|
}
|
|
6358
6451
|
return prev.splice(i, prev.length);
|
|
6359
6452
|
}
|
|
6453
|
+
function arrayPushArray(target, source) {
|
|
6454
|
+
// May exhaust call stack with large `source` array
|
|
6455
|
+
if (source.length < 1e5)
|
|
6456
|
+
Array.prototype.push.apply(target, source);
|
|
6457
|
+
else
|
|
6458
|
+
for (let i = 0; i < source.length; ++i)
|
|
6459
|
+
target.push(source[i]);
|
|
6460
|
+
}
|
|
6360
6461
|
function fixFlowSeqItems(fc) {
|
|
6361
6462
|
if (fc.start.type === 'flow-seq-start') {
|
|
6362
6463
|
for (const it of fc.items) {
|
|
@@ -6369,12 +6470,12 @@ function fixFlowSeqItems(fc) {
|
|
|
6369
6470
|
delete it.key;
|
|
6370
6471
|
if (isFlowToken(it.value)) {
|
|
6371
6472
|
if (it.value.end)
|
|
6372
|
-
|
|
6473
|
+
arrayPushArray(it.value.end, it.sep);
|
|
6373
6474
|
else
|
|
6374
6475
|
it.value.end = it.sep;
|
|
6375
6476
|
}
|
|
6376
6477
|
else
|
|
6377
|
-
|
|
6478
|
+
arrayPushArray(it.start, it.sep);
|
|
6378
6479
|
delete it.sep;
|
|
6379
6480
|
}
|
|
6380
6481
|
}
|
|
@@ -6516,7 +6617,7 @@ class Parser {
|
|
|
6516
6617
|
}
|
|
6517
6618
|
*step() {
|
|
6518
6619
|
const top = this.peek(1);
|
|
6519
|
-
if (this.type === 'doc-end' &&
|
|
6620
|
+
if (this.type === 'doc-end' && top?.type !== 'doc-end') {
|
|
6520
6621
|
while (this.stack.length > 0)
|
|
6521
6622
|
yield* this.pop();
|
|
6522
6623
|
this.stack.push({
|
|
@@ -6792,7 +6893,7 @@ class Parser {
|
|
|
6792
6893
|
const prev = map.items[map.items.length - 2];
|
|
6793
6894
|
const end = prev?.value?.end;
|
|
6794
6895
|
if (Array.isArray(end)) {
|
|
6795
|
-
|
|
6896
|
+
arrayPushArray(end, it.start);
|
|
6796
6897
|
end.push(this.sourceToken);
|
|
6797
6898
|
map.items.pop();
|
|
6798
6899
|
return;
|
|
@@ -6958,7 +7059,20 @@ class Parser {
|
|
|
6958
7059
|
default: {
|
|
6959
7060
|
const bv = this.startBlockValue(map);
|
|
6960
7061
|
if (bv) {
|
|
6961
|
-
if (
|
|
7062
|
+
if (bv.type === 'block-seq') {
|
|
7063
|
+
if (!it.explicitKey &&
|
|
7064
|
+
it.sep &&
|
|
7065
|
+
!includesToken(it.sep, 'newline')) {
|
|
7066
|
+
yield* this.pop({
|
|
7067
|
+
type: 'error',
|
|
7068
|
+
offset: this.offset,
|
|
7069
|
+
message: 'Unexpected block-seq-ind on same line with key',
|
|
7070
|
+
source: this.source
|
|
7071
|
+
});
|
|
7072
|
+
return;
|
|
7073
|
+
}
|
|
7074
|
+
}
|
|
7075
|
+
else if (atMapIndent) {
|
|
6962
7076
|
map.items.push({ start });
|
|
6963
7077
|
}
|
|
6964
7078
|
this.stack.push(bv);
|
|
@@ -6994,7 +7108,7 @@ class Parser {
|
|
|
6994
7108
|
const prev = seq.items[seq.items.length - 2];
|
|
6995
7109
|
const end = prev?.value?.end;
|
|
6996
7110
|
if (Array.isArray(end)) {
|
|
6997
|
-
|
|
7111
|
+
arrayPushArray(end, it.start);
|
|
6998
7112
|
end.push(this.sourceToken);
|
|
6999
7113
|
seq.items.pop();
|
|
7000
7114
|
return;
|
|
@@ -7035,7 +7149,7 @@ class Parser {
|
|
|
7035
7149
|
do {
|
|
7036
7150
|
yield* this.pop();
|
|
7037
7151
|
top = this.peek(1);
|
|
7038
|
-
} while (top
|
|
7152
|
+
} while (top?.type === 'flow-collection');
|
|
7039
7153
|
}
|
|
7040
7154
|
else if (fc.end.length === 0) {
|
|
7041
7155
|
switch (this.type) {
|
|
@@ -7329,6 +7443,8 @@ function stringify(value, replacer, options) {
|
|
|
7329
7443
|
if (!keepUndefined)
|
|
7330
7444
|
return undefined;
|
|
7331
7445
|
}
|
|
7446
|
+
if (isDocument(value) && !_replacer)
|
|
7447
|
+
return value.toString(options);
|
|
7332
7448
|
return new Document(value, _replacer, options).toString(options);
|
|
7333
7449
|
}
|
|
7334
7450
|
|