@thoughtspot/visual-embed-sdk 1.49.1 → 1.49.3

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 (151) hide show
  1. package/cjs/package.json +4 -10
  2. package/cjs/src/css-variables.d.ts +17 -0
  3. package/cjs/src/css-variables.d.ts.map +1 -1
  4. package/cjs/src/embed/app.d.ts +7 -1
  5. package/cjs/src/embed/app.d.ts.map +1 -1
  6. package/cjs/src/embed/app.js +4 -1
  7. package/cjs/src/embed/app.js.map +1 -1
  8. package/cjs/src/embed/app.spec.js +97 -0
  9. package/cjs/src/embed/app.spec.js.map +1 -1
  10. package/cjs/src/embed/conversation.d.ts +8 -0
  11. package/cjs/src/embed/conversation.d.ts.map +1 -1
  12. package/cjs/src/embed/conversation.js +2 -1
  13. package/cjs/src/embed/conversation.js.map +1 -1
  14. package/cjs/src/embed/conversation.spec.js +12 -0
  15. package/cjs/src/embed/conversation.spec.js.map +1 -1
  16. package/cjs/src/embed/events.spec.js +5 -0
  17. package/cjs/src/embed/events.spec.js.map +1 -1
  18. package/cjs/src/embed/liveboard.d.ts +6 -0
  19. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  20. package/cjs/src/embed/liveboard.js +4 -1
  21. package/cjs/src/embed/liveboard.js.map +1 -1
  22. package/cjs/src/embed/liveboard.spec.js +11 -0
  23. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  24. package/cjs/src/embed/spotter-viz-utils.d.ts +29 -0
  25. package/cjs/src/embed/spotter-viz-utils.d.ts.map +1 -1
  26. package/cjs/src/embed/spotter-viz-utils.js.map +1 -1
  27. package/cjs/src/embed/ts-embed.d.ts +38 -0
  28. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  29. package/cjs/src/embed/ts-embed.js +166 -9
  30. package/cjs/src/embed/ts-embed.js.map +1 -1
  31. package/cjs/src/embed/ts-embed.spec.js +237 -0
  32. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  33. package/cjs/src/index.d.ts +2 -2
  34. package/cjs/src/index.d.ts.map +1 -1
  35. package/cjs/src/index.js.map +1 -1
  36. package/cjs/src/types.d.ts +87 -4
  37. package/cjs/src/types.d.ts.map +1 -1
  38. package/cjs/src/types.js +47 -3
  39. package/cjs/src/types.js.map +1 -1
  40. package/cjs/src/utils/graphql/answerService/answerService.spec.js +15 -0
  41. package/cjs/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
  42. package/cjs/src/utils/processTrigger.d.ts.map +1 -1
  43. package/cjs/src/utils/processTrigger.js +6 -5
  44. package/cjs/src/utils/processTrigger.js.map +1 -1
  45. package/cjs/src/utils/processTrigger.spec.js +13 -0
  46. package/cjs/src/utils/processTrigger.spec.js.map +1 -1
  47. package/cjs/src/utils.d.ts +10 -0
  48. package/cjs/src/utils.d.ts.map +1 -1
  49. package/cjs/src/utils.js +25 -4
  50. package/cjs/src/utils.js.map +1 -1
  51. package/cjs/src/utils.spec.js +48 -0
  52. package/cjs/src/utils.spec.js.map +1 -1
  53. package/dist/{index-B6Rn561t.js → index-DsSQndIB.js} +303 -187
  54. package/dist/src/css-variables.d.ts +17 -0
  55. package/dist/src/css-variables.d.ts.map +1 -1
  56. package/dist/src/embed/app.d.ts +7 -1
  57. package/dist/src/embed/app.d.ts.map +1 -1
  58. package/dist/src/embed/conversation.d.ts +8 -0
  59. package/dist/src/embed/conversation.d.ts.map +1 -1
  60. package/dist/src/embed/liveboard.d.ts +6 -0
  61. package/dist/src/embed/liveboard.d.ts.map +1 -1
  62. package/dist/src/embed/spotter-viz-utils.d.ts +29 -0
  63. package/dist/src/embed/spotter-viz-utils.d.ts.map +1 -1
  64. package/dist/src/embed/ts-embed.d.ts +38 -0
  65. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  66. package/dist/src/index.d.ts +2 -2
  67. package/dist/src/index.d.ts.map +1 -1
  68. package/dist/src/types.d.ts +87 -4
  69. package/dist/src/types.d.ts.map +1 -1
  70. package/dist/src/utils/processTrigger.d.ts.map +1 -1
  71. package/dist/src/utils.d.ts +10 -0
  72. package/dist/src/utils.d.ts.map +1 -1
  73. package/dist/tsembed-react.es.js +282 -35
  74. package/dist/tsembed-react.js +583 -220
  75. package/dist/tsembed.es.js +282 -35
  76. package/dist/tsembed.js +583 -220
  77. package/dist/visual-embed-sdk-react-full.d.ts +190 -4
  78. package/dist/visual-embed-sdk-react.d.ts +190 -4
  79. package/dist/visual-embed-sdk.d.ts +190 -4
  80. package/lib/package.json +4 -10
  81. package/lib/src/css-variables.d.ts +17 -0
  82. package/lib/src/css-variables.d.ts.map +1 -1
  83. package/lib/src/embed/app.d.ts +7 -1
  84. package/lib/src/embed/app.d.ts.map +1 -1
  85. package/lib/src/embed/app.js +4 -1
  86. package/lib/src/embed/app.js.map +1 -1
  87. package/lib/src/embed/app.spec.js +97 -0
  88. package/lib/src/embed/app.spec.js.map +1 -1
  89. package/lib/src/embed/conversation.d.ts +8 -0
  90. package/lib/src/embed/conversation.d.ts.map +1 -1
  91. package/lib/src/embed/conversation.js +2 -1
  92. package/lib/src/embed/conversation.js.map +1 -1
  93. package/lib/src/embed/conversation.spec.js +12 -0
  94. package/lib/src/embed/conversation.spec.js.map +1 -1
  95. package/lib/src/embed/events.spec.js +5 -0
  96. package/lib/src/embed/events.spec.js.map +1 -1
  97. package/lib/src/embed/liveboard.d.ts +6 -0
  98. package/lib/src/embed/liveboard.d.ts.map +1 -1
  99. package/lib/src/embed/liveboard.js +4 -1
  100. package/lib/src/embed/liveboard.js.map +1 -1
  101. package/lib/src/embed/liveboard.spec.js +11 -0
  102. package/lib/src/embed/liveboard.spec.js.map +1 -1
  103. package/lib/src/embed/spotter-viz-utils.d.ts +29 -0
  104. package/lib/src/embed/spotter-viz-utils.d.ts.map +1 -1
  105. package/lib/src/embed/spotter-viz-utils.js.map +1 -1
  106. package/lib/src/embed/ts-embed.d.ts +38 -0
  107. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  108. package/lib/src/embed/ts-embed.js +167 -10
  109. package/lib/src/embed/ts-embed.js.map +1 -1
  110. package/lib/src/embed/ts-embed.spec.js +237 -0
  111. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  112. package/lib/src/index.d.ts +2 -2
  113. package/lib/src/index.d.ts.map +1 -1
  114. package/lib/src/index.js.map +1 -1
  115. package/lib/src/types.d.ts +87 -4
  116. package/lib/src/types.d.ts.map +1 -1
  117. package/lib/src/types.js +47 -3
  118. package/lib/src/types.js.map +1 -1
  119. package/lib/src/utils/graphql/answerService/answerService.spec.js +15 -0
  120. package/lib/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
  121. package/lib/src/utils/processTrigger.d.ts.map +1 -1
  122. package/lib/src/utils/processTrigger.js +6 -5
  123. package/lib/src/utils/processTrigger.js.map +1 -1
  124. package/lib/src/utils/processTrigger.spec.js +13 -0
  125. package/lib/src/utils/processTrigger.spec.js.map +1 -1
  126. package/lib/src/utils.d.ts +10 -0
  127. package/lib/src/utils.d.ts.map +1 -1
  128. package/lib/src/utils.js +22 -1
  129. package/lib/src/utils.js.map +1 -1
  130. package/lib/src/utils.spec.js +49 -1
  131. package/lib/src/utils.spec.js.map +1 -1
  132. package/lib/src/visual-embed-sdk.d.ts +190 -4
  133. package/package.json +4 -10
  134. package/src/css-variables.ts +20 -0
  135. package/src/embed/app.spec.ts +109 -0
  136. package/src/embed/app.ts +11 -1
  137. package/src/embed/conversation.spec.ts +17 -0
  138. package/src/embed/conversation.ts +10 -0
  139. package/src/embed/events.spec.ts +7 -0
  140. package/src/embed/liveboard.spec.ts +15 -0
  141. package/src/embed/liveboard.ts +10 -0
  142. package/src/embed/spotter-viz-utils.ts +30 -0
  143. package/src/embed/ts-embed.spec.ts +294 -0
  144. package/src/embed/ts-embed.ts +180 -9
  145. package/src/index.ts +2 -1
  146. package/src/types.ts +86 -3
  147. package/src/utils/graphql/answerService/answerService.spec.ts +18 -0
  148. package/src/utils/processTrigger.spec.ts +23 -0
  149. package/src/utils/processTrigger.ts +8 -6
  150. package/src/utils.spec.ts +63 -0
  151. package/src/utils.ts +25 -1
package/dist/tsembed.js CHANGED
@@ -1,4 +1,4 @@
1
- /* @thoughtspot/visual-embed-sdk version 1.49.1 */
1
+ /* @thoughtspot/visual-embed-sdk version 1.49.3 */
2
2
  'use client';
3
3
  (function (global, factory) {
4
4
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
@@ -2249,11 +2249,30 @@
2249
2249
  /**
2250
2250
  * Navigate to a specific page in the embedded ThoughtSpot application.
2251
2251
  * This is the same as calling `appEmbed.navigateToPage(path, true)`.
2252
- * @param - `path` - the path to navigate to go forward or back. The path value can
2253
- * be a number; for example, `1`, `-1`.
2252
+ *
2253
+ * Accepts either a plain value or an object with `path`
2254
+ * and an optional `replace` flag.
2255
+ *
2256
+ * @param data - A string path, a numeric history delta, or an object
2257
+ * `{ path: string | number, replace?: boolean }`.
2258
+ * - `path` — the route to navigate to, or a history delta such as `1`
2259
+ * or `-1` (calls `window.history.go()`).
2260
+ * - `replace` — when `true`, replaces the current history entry instead
2261
+ * of pushing a new one (uses `window.location.replace`).
2262
+ *
2254
2263
  * @example
2255
2264
  * ```js
2256
- * appEmbed.navigateToPage(-1)
2265
+ * // Preferred: use navigateToPage directly
2266
+ * appEmbed.navigateToPage(-1);
2267
+ *
2268
+ * // Numeric delta — go back one step
2269
+ * appEmbed.trigger(HostEvent.Navigate, -1);
2270
+ *
2271
+ * // String path — push a new history entry
2272
+ * appEmbed.trigger(HostEvent.Navigate, 'home');
2273
+ *
2274
+ * // Object format — replace current history entry
2275
+ * appEmbed.trigger(HostEvent.Navigate, { path: 'home', replace: true }); // SDK: 1.51.0 | ThoughtSpot Cloud: 26.8.0.cl
2257
2276
  * ```
2258
2277
  * @version SDK: 1.12.0 | ThoughtSpot: 8.4.0.cl, 8.4.1.sw
2259
2278
  */
@@ -4242,6 +4261,7 @@
4242
4261
  Param["EnableLiveboardDataCache"] = "enableLiveboardDataCache";
4243
4262
  Param["SpotterFileUploadEnabled"] = "spotterFileUploadEnabled";
4244
4263
  Param["SpotterFileUploadFileTypes"] = "spotterFileUploadFileTypes";
4264
+ Param["IsStarterPromptsEnabled"] = "enableStarterPrompts";
4245
4265
  })(Param || (Param = {}));
4246
4266
  /**
4247
4267
  * ThoughtSpot application pages include actions and menu commands
@@ -4884,6 +4904,16 @@
4884
4904
  * @version SDK: 1.9.0 | ThoughtSpot: 8.1.0.cl, 8.4.1.sw
4885
4905
  */
4886
4906
  Action["AddToFavorites"] = "addToFavorites";
4907
+ /**
4908
+ * Remove from Favorites option in home page v3 sidebar.
4909
+ * Allows removing an object from the user's favorites list from home-page v3 sidebar.
4910
+ * @version SDK: 1.51.0 | ThoughtSpot Cloud: 26.8.0.cl
4911
+ * @example
4912
+ * ```js
4913
+ * disabledActions: [Action.RemoveFromFavorites]
4914
+ * ```
4915
+ */
4916
+ Action["RemoveFromFavorites"] = "removeFromFavorites";
4887
4917
  /**
4888
4918
  * The edit icon on Liveboards (Classic experience).
4889
4919
  * @example
@@ -5941,6 +5971,20 @@
5941
5971
  * ```
5942
5972
  */
5943
5973
  Action["SpotterViz"] = "spotterViz";
5974
+ /**
5975
+ * The reference-mode toggle button inside the SpotterViz chat input.
5976
+ * When users enable reference mode, clicking tiles, filters, or
5977
+ * parameters adds them as chat context. Hide this action to remove
5978
+ * the reference-mode capability entirely.
5979
+ * Visible by default.
5980
+ * @version SDK: 1.51.0 | ThoughtSpot Cloud: 26.8.0.cl
5981
+ * @example
5982
+ * ```js
5983
+ * hiddenActions: [Action.SpotterVizReferenceMode]
5984
+ * disabledActions: [Action.SpotterVizReferenceMode]
5985
+ * ```
5986
+ */
5987
+ Action["SpotterVizReferenceMode"] = "spotterVizReferenceMode";
5944
5988
  /**
5945
5989
  * Clears browser cache and fetches new data for liveboard ChartViz Containers.
5946
5990
  * Requires `enableLiveboardDataCache` to be enabled.
@@ -6417,7 +6461,7 @@
6417
6461
  TableContentDensity["Compact"] = "COMPACT";
6418
6462
  })(exports.TableContentDensity || (exports.TableContentDensity = {}));
6419
6463
 
6420
- var version$1="1.49.1";var pkg = {version:version$1};
6464
+ var version$1="1.49.3";var pkg = {version:version$1};
6421
6465
 
6422
6466
  const { version } = pkg;
6423
6467
 
@@ -6502,28 +6546,45 @@
6502
6546
  }
6503
6547
  return false;
6504
6548
  };
6505
- const merge = (...objects) => objects.reduce((result, current) => {
6549
+ const UNSAFE_KEYS = new Set([
6550
+ "__proto__",
6551
+ "constructor",
6552
+ "prototype",
6553
+ "toString",
6554
+ "valueOf",
6555
+ "hasOwnProperty",
6556
+ "isPrototypeOf",
6557
+ "propertyIsEnumerable",
6558
+ "toLocaleString",
6559
+ ]);
6560
+ const merge$1 = (...objects) => objects.reduce((result, current) => {
6561
+ if (current === undefined) {
6562
+ return result;
6563
+ }
6506
6564
  if (Array.isArray(current)) {
6507
6565
  throw new TypeError("Arguments provided to ts-deepmerge must be objects, not arrays.");
6508
6566
  }
6509
6567
  Object.keys(current).forEach((key) => {
6510
- if (["__proto__", "constructor", "prototype"].includes(key)) {
6568
+ if (UNSAFE_KEYS.has(key)) {
6511
6569
  return;
6512
6570
  }
6513
6571
  if (Array.isArray(result[key]) && Array.isArray(current[key])) {
6514
- result[key] = merge.options.mergeArrays
6515
- ? merge.options.uniqueArrayItems
6572
+ result[key] = merge$1.options.mergeArrays
6573
+ ? merge$1.options.uniqueArrayItems
6516
6574
  ? Array.from(new Set(result[key].concat(current[key])))
6517
6575
  : [...result[key], ...current[key]]
6518
6576
  : current[key];
6519
6577
  }
6520
6578
  else if (isObject$1(result[key]) && isObject$1(current[key])) {
6521
- result[key] = merge(result[key], current[key]);
6579
+ result[key] = merge$1(result[key], current[key]);
6580
+ }
6581
+ else if (!isObject$1(result[key]) && isObject$1(current[key])) {
6582
+ result[key] = merge$1(current[key], undefined);
6522
6583
  }
6523
6584
  else {
6524
6585
  result[key] =
6525
6586
  current[key] === undefined
6526
- ? merge.options.allowUndefinedOverrides
6587
+ ? merge$1.options.allowUndefinedOverrides
6527
6588
  ? current[key]
6528
6589
  : result[key]
6529
6590
  : current[key];
@@ -6536,11 +6597,11 @@
6536
6597
  mergeArrays: true,
6537
6598
  uniqueArrayItems: true,
6538
6599
  };
6539
- merge.options = defaultOptions;
6540
- merge.withOptions = (options, ...objects) => {
6541
- merge.options = Object.assign(Object.assign({}, defaultOptions), options);
6542
- const result = merge(...objects);
6543
- merge.options = defaultOptions;
6600
+ merge$1.options = defaultOptions;
6601
+ merge$1.withOptions = (options, ...objects) => {
6602
+ merge$1.options = Object.assign(Object.assign({}, defaultOptions), options);
6603
+ const result = merge$1(...objects);
6604
+ merge$1.options = defaultOptions;
6544
6605
  return result;
6545
6606
  };
6546
6607
 
@@ -6816,7 +6877,28 @@
6816
6877
  function getDOMNode(domSelector) {
6817
6878
  return typeof domSelector === 'string' ? document.querySelector(domSelector) : domSelector;
6818
6879
  }
6819
- const deepMerge = (target, source) => merge(target, source);
6880
+ /**
6881
+ * Resolves a CSS selector to an element. `document.querySelector` cannot pierce
6882
+ * shadow boundaries, so when the document lookup misses and a reference node is
6883
+ * provided, this also searches the shadow root the reference node lives in —
6884
+ * letting a selector target an element inside the same shadow root as the embed
6885
+ * instead of silently falling back to the light DOM.
6886
+ * @param selector CSS selector string.
6887
+ * @param referenceNode Node whose shadow root is searched when the document lookup misses.
6888
+ */
6889
+ function querySelectorAcrossShadowRoot(selector, referenceNode) {
6890
+ var _a;
6891
+ const fromDocument = document.querySelector(selector);
6892
+ if (fromDocument) {
6893
+ return fromDocument;
6894
+ }
6895
+ const rootNode = (_a = referenceNode === null || referenceNode === void 0 ? void 0 : referenceNode.getRootNode) === null || _a === void 0 ? void 0 : _a.call(referenceNode);
6896
+ if (typeof ShadowRoot !== 'undefined' && rootNode instanceof ShadowRoot) {
6897
+ return rootNode.querySelector(selector);
6898
+ }
6899
+ return null;
6900
+ }
6901
+ const deepMerge = (target, source) => merge$1(target, source);
6820
6902
  const getOperationNameFromQuery = (query) => {
6821
6903
  const regex = /(?:query|mutation)\s+(\w+)/;
6822
6904
  const matches = query.match(regex);
@@ -19358,8 +19440,14 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
19358
19440
  }
19359
19441
  }
19360
19442
  const channel = new MessageChannel();
19443
+ // Close the messageChannel and resolve the promise if timeout.
19444
+ const timeoutId = setTimeout(() => {
19445
+ channel.port1.close();
19446
+ res(new Error(ERROR_MESSAGE.TRIGGER_TIMED_OUT));
19447
+ }, TRIGGER_TIMEOUT);
19361
19448
  channel.port1.onmessage = ({ data: responseData }) => {
19362
19449
  var _a;
19450
+ clearTimeout(timeoutId);
19363
19451
  channel.port1.close();
19364
19452
  const error = (responseData === null || responseData === void 0 ? void 0 : responseData.error) || ((_a = responseData === null || responseData === void 0 ? void 0 : responseData.data) === null || _a === void 0 ? void 0 : _a.error);
19365
19453
  if (error) {
@@ -19369,11 +19457,6 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
19369
19457
  res(responseData);
19370
19458
  }
19371
19459
  };
19372
- // Close the messageChannel and resolve the promise if timeout.
19373
- setTimeout(() => {
19374
- channel.port1.close();
19375
- res(new Error(ERROR_MESSAGE.TRIGGER_TIMED_OUT));
19376
- }, TRIGGER_TIMEOUT);
19377
19460
  return postIframeMessage(iFrame, { type: messageType, data, context }, thoughtSpotHost, channel);
19378
19461
  });
19379
19462
  }
@@ -20291,6 +20374,14 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
20291
20374
  */
20292
20375
  const THOUGHTSPOT_PARAM_PREFIX = 'ts-';
20293
20376
  const TS_EMBED_ID = '_thoughtspot-embed';
20377
+ /**
20378
+ * dataset key used to stash a custom preRenderContainer's original inline
20379
+ * `position` while we override it to `relative`. Stored on the container (not
20380
+ * per-instance) so the override can be reverted on destroy even when multiple
20381
+ * pre-rendered embeds share the same container.
20382
+ */
20383
+ const PRERENDER_CONTAINER_ORIGINAL_POSITION_KEY = 'tsEmbedOriginalPosition';
20384
+ const PRERENDER_WRAPPER_ID_PREFIX = 'tsEmbed-pre-render-wrapper-';
20294
20385
  /**
20295
20386
  * The event id map from v2 event names to v1 event id
20296
20387
  * v1 events are the classic embed events implemented in Blink v1
@@ -20326,6 +20417,8 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
20326
20417
  */
20327
20418
  this.shouldEncodeUrlQueryParams = false;
20328
20419
  this.defaultHiddenActions = [exports.Action.ReportError];
20420
+ this.preRenderContainerEl = null;
20421
+ this.containerScrollListener = null;
20329
20422
  /**
20330
20423
  * Handler for fullscreen change events
20331
20424
  */
@@ -21191,6 +21284,89 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
21191
21284
  placeholder.id = id.placeHolder;
21192
21285
  return placeholder;
21193
21286
  }
21287
+ /**
21288
+ * Resolves the configured preRenderContainer to a live element, falling
21289
+ * back to `document.body`. A string selector is re-queried on every call so
21290
+ * a remounted container (E.g.: React replacing the node) resolves to the
21291
+ * fresh element; an element passed directly cannot be re-resolved.
21292
+ */
21293
+ resolvePreRenderContainerTarget() {
21294
+ var _a;
21295
+ const containerConfig = this.viewConfig.preRenderContainer;
21296
+ let container = null;
21297
+ if (typeof containerConfig === 'string') {
21298
+ try {
21299
+ // Resolve against the host's shadow root too, so a selector can
21300
+ // target a container inside the same shadow DOM as the embed —
21301
+ // document.querySelector alone cannot pierce shadow boundaries.
21302
+ container = querySelectorAcrossShadowRoot(containerConfig, this.hostElement);
21303
+ }
21304
+ catch (e) {
21305
+ logger$3.error(`Invalid CSS selector for preRenderContainer: ${containerConfig}`, e);
21306
+ }
21307
+ }
21308
+ else if (containerConfig) {
21309
+ container = containerConfig;
21310
+ }
21311
+ return (_a = container) !== null && _a !== void 0 ? _a : document.body;
21312
+ }
21313
+ /**
21314
+ * Makes the container a positioning context for the absolutely positioned
21315
+ * wrapper, stashing the original inline `position` on the element (once) so
21316
+ * destroy() can restore it exactly, leaving no trace. Recording it on the
21317
+ * element rather than per-instance lets the override be reverted even when
21318
+ * embeds share the same container.
21319
+ */
21320
+ applyPreRenderContainerPositioning(container) {
21321
+ if (container === document.body) {
21322
+ return;
21323
+ }
21324
+ const pos = window.getComputedStyle(container).position;
21325
+ if (pos === 'static') {
21326
+ if (container.dataset[PRERENDER_CONTAINER_ORIGINAL_POSITION_KEY] === undefined) {
21327
+ container.dataset[PRERENDER_CONTAINER_ORIGINAL_POSITION_KEY] = container.style.position;
21328
+ }
21329
+ container.style.position = 'relative';
21330
+ }
21331
+ }
21332
+ /**
21333
+ * Re-attaches the wrapper to a live container when the previously resolved
21334
+ * one has been detached or no longer holds the wrapper — e.g. the host app
21335
+ * remounted a custom preRenderContainer, which would otherwise leave a stale
21336
+ * reference and collapse the wrapper. Only string selectors can be
21337
+ * re-resolved; a container passed as an element is left untouched.
21338
+ */
21339
+ reconcilePreRenderContainer() {
21340
+ const wrapper = this.preRenderWrapper;
21341
+ const stored = this.preRenderContainerEl;
21342
+ // Nothing to reconcile until this instance resolved its container.
21343
+ if (!wrapper || !stored) {
21344
+ return;
21345
+ }
21346
+ const storedIsLive = stored === document.body || document.contains(stored);
21347
+ if (storedIsLive && stored.contains(wrapper)) {
21348
+ return;
21349
+ }
21350
+ const resolved = this.resolvePreRenderContainerTarget();
21351
+ // Re-resolution yielded the same (still stale) element — nothing we can
21352
+ // do, e.g. a detached container passed as an HTMLElement.
21353
+ if (resolved === stored && stored.contains(wrapper)) {
21354
+ return;
21355
+ }
21356
+ if (this.containerScrollListener && stored !== resolved) {
21357
+ if (stored !== document.body) {
21358
+ stored.removeEventListener('scroll', this.containerScrollListener);
21359
+ }
21360
+ if (resolved !== document.body) {
21361
+ resolved.addEventListener('scroll', this.containerScrollListener);
21362
+ }
21363
+ }
21364
+ this.applyPreRenderContainerPositioning(resolved);
21365
+ if (wrapper.parentNode !== resolved) {
21366
+ resolved.appendChild(wrapper);
21367
+ }
21368
+ this.preRenderContainerEl = resolved;
21369
+ }
21194
21370
  insertIntoDOMForPreRender(child) {
21195
21371
  const preRenderChild = this.createPreRenderChild(child);
21196
21372
  const preRenderWrapper = this.createPreRenderWrapper();
@@ -21210,7 +21386,10 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
21210
21386
  else {
21211
21387
  this.hidePreRender();
21212
21388
  }
21213
- document.body.appendChild(preRenderWrapper);
21389
+ const targetContainer = this.resolvePreRenderContainerTarget();
21390
+ this.preRenderContainerEl = targetContainer;
21391
+ this.applyPreRenderContainerPositioning(targetContainer);
21392
+ targetContainer.appendChild(preRenderWrapper);
21214
21393
  }
21215
21394
  insertIntoDOM(child) {
21216
21395
  var _a;
@@ -21649,6 +21828,50 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
21649
21828
  tsParams = tsParams ? `?${tsParams}` : '';
21650
21829
  return tsParams;
21651
21830
  }
21831
+ /**
21832
+ * Reverts the custom preRenderContainer's `position` to the value it had
21833
+ * before we overrode it to `relative` (see insertIntoDOMForPreRender).
21834
+ *
21835
+ * We restore the original inline value rather than forcing `static`, and we
21836
+ * skip the restore if another preRender wrapper is still mounted inside the
21837
+ * same container — a shared container still needs the positioning context.
21838
+ */
21839
+ restorePreRenderContainerPosition() {
21840
+ const container = this.preRenderContainerEl;
21841
+ if (!container || container === document.body) {
21842
+ return;
21843
+ }
21844
+ // Drop our reference up front so a destroyed embed never pins a
21845
+ // detached container in memory; restoration uses the local handle.
21846
+ this.preRenderContainerEl = null;
21847
+ const originalPosition = container.dataset[PRERENDER_CONTAINER_ORIGINAL_POSITION_KEY];
21848
+ if (originalPosition === undefined) {
21849
+ // We never overrode this container's position; nothing to restore.
21850
+ return;
21851
+ }
21852
+ // This instance's own wrapper has already been removed by now, so any
21853
+ // match here belongs to another embed still sharing the container — it
21854
+ // continues to rely on the positioning context, so leave it in place.
21855
+ const hasOtherWrapper = container.querySelector(`[id^="${PRERENDER_WRAPPER_ID_PREFIX}"]`);
21856
+ if (hasOtherWrapper) {
21857
+ return;
21858
+ }
21859
+ container.style.position = originalPosition;
21860
+ delete container.dataset[PRERENDER_CONTAINER_ORIGINAL_POSITION_KEY];
21861
+ }
21862
+ /**
21863
+ * Detaches and clears the container scroll listener, if one is attached.
21864
+ */
21865
+ removeContainerScrollListener() {
21866
+ if (!this.containerScrollListener) {
21867
+ return;
21868
+ }
21869
+ const customContainer = this.preRenderContainerEl && this.preRenderContainerEl !== document.body
21870
+ ? this.preRenderContainerEl
21871
+ : null;
21872
+ customContainer === null || customContainer === void 0 ? void 0 : customContainer.removeEventListener('scroll', this.containerScrollListener);
21873
+ this.containerScrollListener = null;
21874
+ }
21652
21875
  /**
21653
21876
  * Destroys the ThoughtSpot embed, and remove any nodes from the DOM.
21654
21877
  * @version SDK: 1.19.1 | ThoughtSpot: *
@@ -21657,8 +21880,10 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
21657
21880
  var _a, _b, _c;
21658
21881
  try {
21659
21882
  this.removeFullscreenChangeHandler();
21883
+ this.removeContainerScrollListener();
21660
21884
  this.unsubscribeToEvents();
21661
21885
  (_a = this.preRenderWrapper) === null || _a === void 0 ? void 0 : _a.remove();
21886
+ this.restorePreRenderContainerPosition();
21662
21887
  if (!this.isRendered) {
21663
21888
  return;
21664
21889
  }
@@ -21768,15 +21993,19 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
21768
21993
  }
21769
21994
  this.hostElement.appendChild(this.insertedDomEl);
21770
21995
  this.syncPreRenderStyle();
21996
+ const customContainer = this.preRenderContainerEl && this.preRenderContainerEl !== document.body
21997
+ ? this.preRenderContainerEl
21998
+ : null;
21999
+ if (customContainer && !this.containerScrollListener) {
22000
+ this.containerScrollListener = () => this.syncPreRenderStyle();
22001
+ customContainer.addEventListener('scroll', this.containerScrollListener);
22002
+ }
21771
22003
  if (!this.viewConfig.doNotTrackPreRenderSize) {
21772
22004
  const observeTarget = (_a = this.insertedDomEl) !== null && _a !== void 0 ? _a : this.hostElement;
21773
22005
  this.resizeObserver = new ResizeObserver((entries) => {
21774
22006
  entries.forEach((entry) => {
21775
- if (entry.contentRect && entry.target === observeTarget) {
21776
- setStyleProperties(this.preRenderWrapper, {
21777
- width: `${entry.contentRect.width}px`,
21778
- height: `${entry.contentRect.height}px`,
21779
- });
22007
+ if (entry.target === observeTarget) {
22008
+ this.syncPreRenderStyle();
21780
22009
  }
21781
22010
  });
21782
22011
  });
@@ -21808,14 +22037,24 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
21808
22037
  * is not defined or not found.
21809
22038
  */
21810
22039
  syncPreRenderStyle() {
22040
+ var _a;
21811
22041
  if (!this.isPreRenderConnected() || !this.getPreRenderPlaceHolderElement()) {
21812
22042
  logger$3.error(ERROR_MESSAGE.SYNC_STYLE_CALLED_BEFORE_RENDER);
21813
22043
  return;
21814
22044
  }
22045
+ // Self-heal if the resolved container was remounted/detached, so we
22046
+ // never measure a stale node (which would collapse the wrapper).
22047
+ this.reconcilePreRenderContainer();
21815
22048
  const elBoundingClient = this.getPreRenderPlaceHolderElement().getBoundingClientRect();
22049
+ const containerEl = this.preRenderContainerEl && this.preRenderContainerEl !== document.body
22050
+ ? this.preRenderContainerEl
22051
+ : null;
22052
+ const containerRect = (_a = containerEl === null || containerEl === void 0 ? void 0 : containerEl.getBoundingClientRect()) !== null && _a !== void 0 ? _a : { x: 0, y: 0 };
22053
+ const scrollX = containerEl ? containerEl.scrollLeft : window.scrollX;
22054
+ const scrollY = containerEl ? containerEl.scrollTop : window.scrollY;
21816
22055
  setStyleProperties(this.preRenderWrapper, {
21817
- top: `${elBoundingClient.y + window.scrollY}px`,
21818
- left: `${elBoundingClient.x + window.scrollX}px`,
22056
+ top: `${elBoundingClient.y - containerRect.y + scrollY}px`,
22057
+ left: `${elBoundingClient.x - containerRect.x + scrollX}px`,
21819
22058
  width: `${elBoundingClient.width}px`,
21820
22059
  height: `${elBoundingClient.height}px`,
21821
22060
  position: 'absolute',
@@ -21842,6 +22081,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
21842
22081
  overflow: 'hidden',
21843
22082
  };
21844
22083
  setStyleProperties(this.preRenderWrapper, preRenderHideStyles);
22084
+ this.removeContainerScrollListener();
21845
22085
  if (this.resizeObserver) {
21846
22086
  this.resizeObserver.disconnect();
21847
22087
  }
@@ -21860,7 +22100,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
21860
22100
  */
21861
22101
  getPreRenderIds() {
21862
22102
  return {
21863
- wrapper: `tsEmbed-pre-render-wrapper-${this.viewConfig.preRenderId}`,
22103
+ wrapper: `${PRERENDER_WRAPPER_ID_PREFIX}${this.viewConfig.preRenderId}`,
21864
22104
  child: `tsEmbed-pre-render-child-${this.viewConfig.preRenderId}`,
21865
22105
  placeHolder: `tsEmbed-pre-render-placeholder-${this.viewConfig.preRenderId}`,
21866
22106
  };
@@ -22297,12 +22537,15 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22297
22537
  }
22298
22538
  // Handle spotterChatConfig params
22299
22539
  if (spotterChatConfig) {
22300
- const { hideToolResponseCardBranding, toolResponseCardBrandingLabel, spotterFileUploadEnabled, spotterFileUploadFileTypes, } = spotterChatConfig;
22540
+ const { hideToolResponseCardBranding, toolResponseCardBrandingLabel, spotterFileUploadEnabled, spotterFileUploadFileTypes, enableStarterPrompts, } = spotterChatConfig;
22301
22541
  setParamIfDefined(params, Param.HideToolResponseCardBranding, hideToolResponseCardBranding, true);
22302
22542
  setParamIfDefined(params, Param.ToolResponseCardBrandingLabel, toolResponseCardBrandingLabel);
22303
22543
  if (spotterFileUploadEnabled !== undefined) {
22304
22544
  params[Param.SpotterFileUploadEnabled] = spotterFileUploadEnabled;
22305
22545
  }
22546
+ if (enableStarterPrompts !== undefined) {
22547
+ params[Param.IsStarterPromptsEnabled] = enableStarterPrompts;
22548
+ }
22306
22549
  if (spotterFileUploadFileTypes !== undefined) {
22307
22550
  params[Param.SpotterFileUploadFileTypes] = JSON.stringify(spotterFileUploadFileTypes);
22308
22551
  }
@@ -22858,12 +23101,15 @@ query GetEurekaVizSnapshots(
22858
23101
  }
22859
23102
  // Handle spotterChatConfig params
22860
23103
  if (spotterChatConfig) {
22861
- const { hideToolResponseCardBranding, toolResponseCardBrandingLabel, spotterFileUploadEnabled, spotterFileUploadFileTypes, } = spotterChatConfig;
23104
+ const { hideToolResponseCardBranding, toolResponseCardBrandingLabel, spotterFileUploadEnabled, spotterFileUploadFileTypes, enableStarterPrompts, } = spotterChatConfig;
22862
23105
  setParamIfDefined(params, Param.HideToolResponseCardBranding, hideToolResponseCardBranding, true);
22863
23106
  setParamIfDefined(params, Param.ToolResponseCardBrandingLabel, toolResponseCardBrandingLabel);
22864
23107
  if (spotterFileUploadEnabled !== undefined) {
22865
23108
  params[Param.SpotterFileUploadEnabled] = spotterFileUploadEnabled;
22866
23109
  }
23110
+ if (enableStarterPrompts !== undefined) {
23111
+ params[Param.IsStarterPromptsEnabled] = enableStarterPrompts;
23112
+ }
22867
23113
  if (spotterFileUploadFileTypes !== undefined) {
22868
23114
  params[Param.SpotterFileUploadFileTypes] = JSON.stringify(spotterFileUploadFileTypes);
22869
23115
  }
@@ -23982,10 +24228,11 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
23982
24228
  setParamIfDefined(queryParams, Param.EnableStopAnswerGenerationEmbed, enableStopAnswerGenerationEmbed, true);
23983
24229
  // Handle spotterChatConfig params
23984
24230
  if (spotterChatConfig) {
23985
- const { hideToolResponseCardBranding, toolResponseCardBrandingLabel, spotterFileUploadEnabled, spotterFileUploadFileTypes, } = spotterChatConfig;
24231
+ const { hideToolResponseCardBranding, toolResponseCardBrandingLabel, spotterFileUploadEnabled, spotterFileUploadFileTypes, enableStarterPrompts, } = spotterChatConfig;
23986
24232
  setParamIfDefined(queryParams, Param.HideToolResponseCardBranding, hideToolResponseCardBranding, true);
23987
24233
  setParamIfDefined(queryParams, Param.ToolResponseCardBrandingLabel, toolResponseCardBrandingLabel);
23988
24234
  setParamIfDefined(queryParams, Param.SpotterFileUploadEnabled, spotterFileUploadEnabled, true);
24235
+ setParamIfDefined(queryParams, Param.IsStarterPromptsEnabled, enableStarterPrompts, true);
23989
24236
  if (spotterFileUploadFileTypes !== undefined) {
23990
24237
  queryParams[Param.SpotterFileUploadFileTypes] = JSON.stringify(spotterFileUploadFileTypes);
23991
24238
  }
@@ -25192,8 +25439,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
25192
25439
  return {
25193
25440
  onAnchor: (source) => {
25194
25441
  aliasObjects.push(source);
25195
- if (!prevAnchors)
25196
- prevAnchors = anchorNames(doc);
25442
+ prevAnchors ?? (prevAnchors = anchorNames(doc));
25197
25443
  const anchor = findNewAnchor(prefix, prevAnchors);
25198
25444
  prevAnchors.add(anchor);
25199
25445
  return anchor;
@@ -25357,23 +25603,38 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
25357
25603
  * Resolve the value of this alias within `doc`, finding the last
25358
25604
  * instance of the `source` anchor before this node.
25359
25605
  */
25360
- resolve(doc) {
25606
+ resolve(doc, ctx) {
25607
+ if (ctx?.maxAliasCount === 0)
25608
+ throw new ReferenceError('Alias resolution is disabled');
25609
+ let nodes;
25610
+ if (ctx?.aliasResolveCache) {
25611
+ nodes = ctx.aliasResolveCache;
25612
+ }
25613
+ else {
25614
+ nodes = [];
25615
+ visit$1(doc, {
25616
+ Node: (_key, node) => {
25617
+ if (isAlias(node) || hasAnchor(node))
25618
+ nodes.push(node);
25619
+ }
25620
+ });
25621
+ if (ctx)
25622
+ ctx.aliasResolveCache = nodes;
25623
+ }
25361
25624
  let found = undefined;
25362
- visit$1(doc, {
25363
- Node: (_key, node) => {
25364
- if (node === this)
25365
- return visit$1.BREAK;
25366
- if (node.anchor === this.source)
25367
- found = node;
25368
- }
25369
- });
25625
+ for (const node of nodes) {
25626
+ if (node === this)
25627
+ break;
25628
+ if (node.anchor === this.source)
25629
+ found = node;
25630
+ }
25370
25631
  return found;
25371
25632
  }
25372
25633
  toJSON(_arg, ctx) {
25373
25634
  if (!ctx)
25374
25635
  return { source: this.source };
25375
25636
  const { anchors, doc, maxAliasCount } = ctx;
25376
- const source = this.resolve(doc);
25637
+ const source = this.resolve(doc, ctx);
25377
25638
  if (!source) {
25378
25639
  const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;
25379
25640
  throw new ReferenceError(msg);
@@ -25385,7 +25646,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
25385
25646
  data = anchors.get(source);
25386
25647
  }
25387
25648
  /* istanbul ignore if */
25388
- if (!data || data.res === undefined) {
25649
+ if (data?.res === undefined) {
25389
25650
  const msg = 'This should not happen: Alias anchor was not resolved?';
25390
25651
  throw new ReferenceError(msg);
25391
25652
  }
@@ -25492,8 +25753,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
25492
25753
  if (aliasDuplicateObjects && value && typeof value === 'object') {
25493
25754
  ref = sourceObjects.get(value);
25494
25755
  if (ref) {
25495
- if (!ref.anchor)
25496
- ref.anchor = onAnchor(value);
25756
+ ref.anchor ?? (ref.anchor = onAnchor(value));
25497
25757
  return new Alias(ref.anchor);
25498
25758
  }
25499
25759
  else {
@@ -26004,7 +26264,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
26004
26264
  const { blockQuote, commentString, lineWidth } = ctx.options;
26005
26265
  // 1. Block can't end in whitespace unless the last line is non-empty.
26006
26266
  // 2. Strings consisting of only whitespace are best rendered explicitly.
26007
- if (!blockQuote || /\n[\t ]+$/.test(value) || /^\s*$/.test(value)) {
26267
+ if (!blockQuote || /\n[\t ]+$/.test(value)) {
26008
26268
  return quotedString(value, ctx);
26009
26269
  }
26010
26270
  const indent = ctx.indent ||
@@ -26064,23 +26324,32 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
26064
26324
  start = start.replace(/\n+/g, `$&${indent}`);
26065
26325
  }
26066
26326
  const indentSize = indent ? '2' : '1'; // root is at -1
26067
- let header = (literal ? '|' : '>') + (startWithSpace ? indentSize : '') + chomp;
26327
+ // Leading | or > is added later
26328
+ let header = (startWithSpace ? indentSize : '') + chomp;
26068
26329
  if (comment) {
26069
26330
  header += ' ' + commentString(comment.replace(/ ?[\r\n]+/g, ' '));
26070
26331
  if (onComment)
26071
26332
  onComment();
26072
26333
  }
26073
- if (literal) {
26074
- value = value.replace(/\n+/g, `$&${indent}`);
26075
- return `${header}\n${indent}${start}${value}${end}`;
26334
+ if (!literal) {
26335
+ const foldedValue = value
26336
+ .replace(/\n+/g, '\n$&')
26337
+ .replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, '$1$2') // more-indented lines aren't folded
26338
+ // ^ more-ind. ^ empty ^ capture next empty lines only at end of indent
26339
+ .replace(/\n+/g, `$&${indent}`);
26340
+ let literalFallback = false;
26341
+ const foldOptions = getFoldOptions(ctx, true);
26342
+ if (blockQuote !== 'folded' && type !== Scalar.BLOCK_FOLDED) {
26343
+ foldOptions.onOverflow = () => {
26344
+ literalFallback = true;
26345
+ };
26346
+ }
26347
+ const body = foldFlowLines(`${start}${foldedValue}${end}`, indent, FOLD_BLOCK, foldOptions);
26348
+ if (!literalFallback)
26349
+ return `>${header}\n${indent}${body}`;
26076
26350
  }
26077
- value = value
26078
- .replace(/\n+/g, '\n$&')
26079
- .replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, '$1$2') // more-indented lines aren't folded
26080
- // ^ more-ind. ^ empty ^ capture next empty lines only at end of indent
26081
- .replace(/\n+/g, `$&${indent}`);
26082
- const body = foldFlowLines(`${start}${value}${end}`, indent, FOLD_BLOCK, getFoldOptions(ctx, true));
26083
- return `${header}\n${indent}${body}`;
26351
+ value = value.replace(/\n+/g, `$&${indent}`);
26352
+ return `|${header}\n${indent}${start}${value}${end}`;
26084
26353
  }
26085
26354
  function plainString(item, ctx, onComment, onChompKeep) {
26086
26355
  const { type, value } = item;
@@ -26089,10 +26358,9 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
26089
26358
  (inFlow && /[[\]{},]/.test(value))) {
26090
26359
  return quotedString(value, ctx);
26091
26360
  }
26092
- if (!value ||
26093
- /^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(value)) {
26361
+ if (/^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(value)) {
26094
26362
  // not allowed:
26095
- // - empty string, '-' or '?'
26363
+ // - '-' or '?'
26096
26364
  // - start with an indicator character (except [?:-]) or /[?-] /
26097
26365
  // - '\n ', ': ' or ' \n' anywhere
26098
26366
  // - '#' not preceded by a non-space char
@@ -26187,6 +26455,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
26187
26455
  nullStr: 'null',
26188
26456
  simpleKeys: false,
26189
26457
  singleQuote: null,
26458
+ trailingComma: false,
26190
26459
  trueStr: 'true',
26191
26460
  verifyAliasOrder: true
26192
26461
  }, doc.schema.toStringOptions, options);
@@ -26221,7 +26490,12 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
26221
26490
  let obj;
26222
26491
  if (isScalar$1(item)) {
26223
26492
  obj = item.value;
26224
- const match = tags.filter(t => t.identify?.(obj));
26493
+ let match = tags.filter(t => t.identify?.(obj));
26494
+ if (match.length > 1) {
26495
+ const testMatch = match.filter(t => t.test);
26496
+ if (testMatch.length > 0)
26497
+ match = testMatch;
26498
+ }
26225
26499
  tagObj =
26226
26500
  match.find(t => t.format === item.format) ?? match.find(t => !t.format);
26227
26501
  }
@@ -26230,7 +26504,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
26230
26504
  tagObj = tags.find(t => t.nodeClass && obj instanceof t.nodeClass);
26231
26505
  }
26232
26506
  if (!tagObj) {
26233
- const name = obj?.constructor?.name ?? typeof obj;
26507
+ const name = obj?.constructor?.name ?? (obj === null ? 'null' : typeof obj);
26234
26508
  throw new Error(`Tag not resolved for ${name} value`);
26235
26509
  }
26236
26510
  return tagObj;
@@ -26245,7 +26519,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
26245
26519
  anchors.add(anchor);
26246
26520
  props.push(`&${anchor}`);
26247
26521
  }
26248
- const tag = node.tag ? node.tag : tagObj.default ? null : tagObj.tag;
26522
+ const tag = node.tag ?? (tagObj.default ? null : tagObj.tag);
26249
26523
  if (tag)
26250
26524
  props.push(doc.directives.tagString(tag));
26251
26525
  return props.join(' ');
@@ -26271,8 +26545,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
26271
26545
  const node = isNode(item)
26272
26546
  ? item
26273
26547
  : ctx.doc.createNode(item, { onTagObj: o => (tagObj = o) });
26274
- if (!tagObj)
26275
- tagObj = getTagObject(ctx.doc.schema.tags, node);
26548
+ tagObj ?? (tagObj = getTagObject(ctx.doc.schema.tags, node));
26276
26549
  const props = stringifyProps(node, tagObj, ctx);
26277
26550
  if (props.length > 0)
26278
26551
  ctx.indentAtStart = (ctx.indentAtStart ?? 0) + props.length + 1;
@@ -26386,7 +26659,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
26386
26659
  ws += `\n${indentComment(cs, ctx.indent)}`;
26387
26660
  }
26388
26661
  if (valueStr === '' && !ctx.inFlow) {
26389
- if (ws === '\n')
26662
+ if (ws === '\n' && valueComment)
26390
26663
  ws = '\n\n';
26391
26664
  }
26392
26665
  else {
@@ -26434,54 +26707,10 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
26434
26707
 
26435
26708
  function warn(logLevel, warning) {
26436
26709
  if (logLevel === 'debug' || logLevel === 'warn') {
26437
- if (typeof process !== 'undefined' && process.emitWarning)
26438
- process.emitWarning(warning);
26439
- else
26440
- console.warn(warning);
26710
+ console.warn(warning);
26441
26711
  }
26442
26712
  }
26443
26713
 
26444
- const MERGE_KEY = '<<';
26445
- function addPairToJSMap(ctx, map, { key, value }) {
26446
- if (ctx?.doc.schema.merge && isMergeKey(key)) {
26447
- value = isAlias(value) ? value.resolve(ctx.doc) : value;
26448
- if (isSeq(value))
26449
- for (const it of value.items)
26450
- mergeToJSMap(ctx, map, it);
26451
- else if (Array.isArray(value))
26452
- for (const it of value)
26453
- mergeToJSMap(ctx, map, it);
26454
- else
26455
- mergeToJSMap(ctx, map, value);
26456
- }
26457
- else {
26458
- const jsKey = toJS(key, '', ctx);
26459
- if (map instanceof Map) {
26460
- map.set(jsKey, toJS(value, jsKey, ctx));
26461
- }
26462
- else if (map instanceof Set) {
26463
- map.add(jsKey);
26464
- }
26465
- else {
26466
- const stringKey = stringifyKey(key, jsKey, ctx);
26467
- const jsValue = toJS(value, stringKey, ctx);
26468
- if (stringKey in map)
26469
- Object.defineProperty(map, stringKey, {
26470
- value: jsValue,
26471
- writable: true,
26472
- enumerable: true,
26473
- configurable: true
26474
- });
26475
- else
26476
- map[stringKey] = jsValue;
26477
- }
26478
- }
26479
- return map;
26480
- }
26481
- const isMergeKey = (key) => key === MERGE_KEY ||
26482
- (isScalar$1(key) &&
26483
- key.value === MERGE_KEY &&
26484
- (!key.type || key.type === Scalar.PLAIN));
26485
26714
  // If the value associated with a merge key is a single mapping node, each of
26486
26715
  // its key/value pairs is inserted into the current mapping, unless the key
26487
26716
  // already exists in it. If the value associated with the merge key is a
@@ -26489,8 +26718,36 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
26489
26718
  // of these nodes is merged in turn according to its order in the sequence.
26490
26719
  // Keys in mapping nodes earlier in the sequence override keys specified in
26491
26720
  // later mapping nodes. -- http://yaml.org/type/merge.html
26492
- function mergeToJSMap(ctx, map, value) {
26493
- const source = ctx && isAlias(value) ? value.resolve(ctx.doc) : value;
26721
+ const MERGE_KEY = '<<';
26722
+ const merge = {
26723
+ identify: value => value === MERGE_KEY ||
26724
+ (typeof value === 'symbol' && value.description === MERGE_KEY),
26725
+ default: 'key',
26726
+ tag: 'tag:yaml.org,2002:merge',
26727
+ test: /^<<$/,
26728
+ resolve: () => Object.assign(new Scalar(Symbol(MERGE_KEY)), {
26729
+ addToJSMap: addMergeToJSMap
26730
+ }),
26731
+ stringify: () => MERGE_KEY
26732
+ };
26733
+ const isMergeKey = (ctx, key) => (merge.identify(key) ||
26734
+ (isScalar$1(key) &&
26735
+ (!key.type || key.type === Scalar.PLAIN) &&
26736
+ merge.identify(key.value))) &&
26737
+ ctx?.doc.schema.tags.some(tag => tag.tag === merge.tag && tag.default);
26738
+ function addMergeToJSMap(ctx, map, value) {
26739
+ const source = resolveAliasValue(ctx, value);
26740
+ if (isSeq(source))
26741
+ for (const it of source.items)
26742
+ mergeValue(ctx, map, it);
26743
+ else if (Array.isArray(source))
26744
+ for (const it of source)
26745
+ mergeValue(ctx, map, it);
26746
+ else
26747
+ mergeValue(ctx, map, source);
26748
+ }
26749
+ function mergeValue(ctx, map, value) {
26750
+ const source = resolveAliasValue(ctx, value);
26494
26751
  if (!isMap(source))
26495
26752
  throw new Error('Merge sources must be maps or map aliases');
26496
26753
  const srcMap = source.toJSON(null, ctx, Map);
@@ -26513,9 +26770,44 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
26513
26770
  }
26514
26771
  return map;
26515
26772
  }
26773
+ function resolveAliasValue(ctx, value) {
26774
+ return ctx && isAlias(value) ? value.resolve(ctx.doc, ctx) : value;
26775
+ }
26776
+
26777
+ function addPairToJSMap(ctx, map, { key, value }) {
26778
+ if (isNode(key) && key.addToJSMap)
26779
+ key.addToJSMap(ctx, map, value);
26780
+ // TODO: Should drop this special case for bare << handling
26781
+ else if (isMergeKey(ctx, key))
26782
+ addMergeToJSMap(ctx, map, value);
26783
+ else {
26784
+ const jsKey = toJS(key, '', ctx);
26785
+ if (map instanceof Map) {
26786
+ map.set(jsKey, toJS(value, jsKey, ctx));
26787
+ }
26788
+ else if (map instanceof Set) {
26789
+ map.add(jsKey);
26790
+ }
26791
+ else {
26792
+ const stringKey = stringifyKey(key, jsKey, ctx);
26793
+ const jsValue = toJS(value, stringKey, ctx);
26794
+ if (stringKey in map)
26795
+ Object.defineProperty(map, stringKey, {
26796
+ value: jsValue,
26797
+ writable: true,
26798
+ enumerable: true,
26799
+ configurable: true
26800
+ });
26801
+ else
26802
+ map[stringKey] = jsValue;
26803
+ }
26804
+ }
26805
+ return map;
26806
+ }
26516
26807
  function stringifyKey(key, jsKey, ctx) {
26517
26808
  if (jsKey === null)
26518
26809
  return '';
26810
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
26519
26811
  if (typeof jsKey !== 'object')
26520
26812
  return String(jsKey);
26521
26813
  if (isNode(key) && ctx?.doc) {
@@ -26668,12 +26960,22 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
26668
26960
  if (comment)
26669
26961
  reqNewline = true;
26670
26962
  let str = stringify$2(item, itemCtx, () => (comment = null));
26671
- if (i < items.length - 1)
26963
+ reqNewline || (reqNewline = lines.length > linesAtValue || str.includes('\n'));
26964
+ if (i < items.length - 1) {
26672
26965
  str += ',';
26966
+ }
26967
+ else if (ctx.options.trailingComma) {
26968
+ if (ctx.options.lineWidth > 0) {
26969
+ reqNewline || (reqNewline = lines.reduce((sum, line) => sum + line.length + 2, 2) +
26970
+ (str.length + 2) >
26971
+ ctx.options.lineWidth);
26972
+ }
26973
+ if (reqNewline) {
26974
+ str += ',';
26975
+ }
26976
+ }
26673
26977
  if (comment)
26674
26978
  str += lineComment(str, itemIndent, commentString(comment));
26675
- if (!reqNewline && (lines.length > linesAtValue || str.includes('\n')))
26676
- reqNewline = true;
26677
26979
  lines.push(str);
26678
26980
  linesAtValue = lines.length;
26679
26981
  }
@@ -27018,11 +27320,12 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
27018
27320
  const num = typeof value === 'number' ? value : Number(value);
27019
27321
  if (!isFinite(num))
27020
27322
  return isNaN(num) ? '.nan' : num < 0 ? '-.inf' : '.inf';
27021
- let n = JSON.stringify(value);
27323
+ let n = Object.is(value, -0) ? '-0' : JSON.stringify(value);
27022
27324
  if (!format &&
27023
27325
  minFractionDigits &&
27024
27326
  (!tag || tag === 'tag:yaml.org,2002:float') &&
27025
- /^\d/.test(n)) {
27327
+ /^-?\d/.test(n) &&
27328
+ !n.includes('e')) {
27026
27329
  let i = n.indexOf('.');
27027
27330
  if (i < 0) {
27028
27331
  i = n.length;
@@ -27148,7 +27451,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
27148
27451
  identify: value => typeof value === 'boolean',
27149
27452
  default: true,
27150
27453
  tag: 'tag:yaml.org,2002:bool',
27151
- test: /^true|false$/,
27454
+ test: /^true$|^false$/,
27152
27455
  resolve: str => str === 'true',
27153
27456
  stringify: stringifyJSON
27154
27457
  },
@@ -27193,10 +27496,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
27193
27496
  * document.querySelector('#photo').src = URL.createObjectURL(blob)
27194
27497
  */
27195
27498
  resolve(src, onError) {
27196
- if (typeof Buffer === 'function') {
27197
- return Buffer.from(src, 'base64');
27198
- }
27199
- else if (typeof atob === 'function') {
27499
+ if (typeof atob === 'function') {
27200
27500
  // On IE 11, atob() can't handle newlines
27201
27501
  const str = atob(src.replace(/[\n\r]/g, ''));
27202
27502
  const buffer = new Uint8Array(str.length);
@@ -27210,15 +27510,11 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
27210
27510
  }
27211
27511
  },
27212
27512
  stringify({ comment, type, value }, ctx, onComment, onChompKeep) {
27513
+ if (!value)
27514
+ return '';
27213
27515
  const buf = value; // checked earlier by binary.identify()
27214
27516
  let str;
27215
- if (typeof Buffer === 'function') {
27216
- str =
27217
- buf instanceof Buffer
27218
- ? buf.toString('base64')
27219
- : Buffer.from(buf.buffer).toString('base64');
27220
- }
27221
- else if (typeof btoa === 'function') {
27517
+ if (typeof btoa === 'function') {
27222
27518
  let s = '';
27223
27519
  for (let i = 0; i < buf.length; ++i)
27224
27520
  s += String.fromCharCode(buf[i]);
@@ -27227,8 +27523,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
27227
27523
  else {
27228
27524
  throw new Error('This environment does not support writing binary tags; either Buffer or btoa is required');
27229
27525
  }
27230
- if (!type)
27231
- type = Scalar.BLOCK_LITERAL;
27526
+ type ?? (type = Scalar.BLOCK_LITERAL);
27232
27527
  if (type !== Scalar.QUOTE_DOUBLE) {
27233
27528
  const lineWidth = Math.max(ctx.options.lineWidth - ctx.indent.length, ctx.options.minContentWidth);
27234
27529
  const n = Math.ceil(str.length / lineWidth);
@@ -27697,7 +27992,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
27697
27992
  }
27698
27993
  return new Date(date);
27699
27994
  },
27700
- stringify: ({ value }) => value.toISOString().replace(/((T00:00)?:00)?\.000Z$/, '')
27995
+ stringify: ({ value }) => value?.toISOString().replace(/(T00:00:00)?\.000Z$/, '') ?? ''
27701
27996
  };
27702
27997
 
27703
27998
  const schema = [
@@ -27715,6 +28010,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
27715
28010
  floatExp,
27716
28011
  float,
27717
28012
  binary,
28013
+ merge,
27718
28014
  omap,
27719
28015
  pairs,
27720
28016
  set,
@@ -27742,6 +28038,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
27742
28038
  intOct: intOct$1,
27743
28039
  intTime,
27744
28040
  map,
28041
+ merge,
27745
28042
  null: nullTag,
27746
28043
  omap,
27747
28044
  pairs,
@@ -27751,13 +28048,20 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
27751
28048
  };
27752
28049
  const coreKnownTags = {
27753
28050
  'tag:yaml.org,2002:binary': binary,
28051
+ 'tag:yaml.org,2002:merge': merge,
27754
28052
  'tag:yaml.org,2002:omap': omap,
27755
28053
  'tag:yaml.org,2002:pairs': pairs,
27756
28054
  'tag:yaml.org,2002:set': set,
27757
28055
  'tag:yaml.org,2002:timestamp': timestamp
27758
28056
  };
27759
- function getTags(customTags, schemaName) {
27760
- let tags = schemas.get(schemaName);
28057
+ function getTags(customTags, schemaName, addMergeTag) {
28058
+ const schemaTags = schemas.get(schemaName);
28059
+ if (schemaTags && !customTags) {
28060
+ return addMergeTag && !schemaTags.includes(merge)
28061
+ ? schemaTags.concat(merge)
28062
+ : schemaTags.slice();
28063
+ }
28064
+ let tags = schemaTags;
27761
28065
  if (!tags) {
27762
28066
  if (Array.isArray(customTags))
27763
28067
  tags = [];
@@ -27776,17 +28080,21 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
27776
28080
  else if (typeof customTags === 'function') {
27777
28081
  tags = customTags(tags.slice());
27778
28082
  }
27779
- return tags.map(tag => {
27780
- if (typeof tag !== 'string')
27781
- return tag;
27782
- const tagObj = tagsByName[tag];
27783
- if (tagObj)
27784
- return tagObj;
27785
- const keys = Object.keys(tagsByName)
27786
- .map(key => JSON.stringify(key))
27787
- .join(', ');
27788
- throw new Error(`Unknown custom tag "${tag}"; use one of ${keys}`);
27789
- });
28083
+ if (addMergeTag)
28084
+ tags = tags.concat(merge);
28085
+ return tags.reduce((tags, tag) => {
28086
+ const tagObj = typeof tag === 'string' ? tagsByName[tag] : tag;
28087
+ if (!tagObj) {
28088
+ const tagName = JSON.stringify(tag);
28089
+ const keys = Object.keys(tagsByName)
28090
+ .map(key => JSON.stringify(key))
28091
+ .join(', ');
28092
+ throw new Error(`Unknown custom tag ${tagName}; use one of ${keys}`);
28093
+ }
28094
+ if (!tags.includes(tagObj))
28095
+ tags.push(tagObj);
28096
+ return tags;
28097
+ }, []);
27790
28098
  }
27791
28099
 
27792
28100
  const sortMapEntriesByKey = (a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0;
@@ -27797,10 +28105,9 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
27797
28105
  : compat
27798
28106
  ? getTags(null, compat)
27799
28107
  : null;
27800
- this.merge = !!merge;
27801
28108
  this.name = (typeof schema === 'string' && schema) || 'core';
27802
28109
  this.knownTags = resolveKnownTags ? coreKnownTags : {};
27803
- this.tags = getTags(customTags, this.name);
28110
+ this.tags = getTags(customTags, this.name, merge);
27804
28111
  this.toStringOptions = toStringDefaults ?? null;
27805
28112
  Object.defineProperty(this, MAP, { value: map });
27806
28113
  Object.defineProperty(this, SCALAR$1, { value: string });
@@ -27925,6 +28232,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
27925
28232
  logLevel: 'warn',
27926
28233
  prettyErrors: true,
27927
28234
  strict: true,
28235
+ stringKeys: false,
27928
28236
  uniqueKeys: true,
27929
28237
  version: '1.2'
27930
28238
  }, options);
@@ -28148,7 +28456,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
28148
28456
  this.directives.yaml.version = '1.1';
28149
28457
  else
28150
28458
  this.directives = new Directives({ version: '1.1' });
28151
- opt = { merge: true, resolveKnownTags: false, schema: 'yaml-1.1' };
28459
+ opt = { resolveKnownTags: false, schema: 'yaml-1.1' };
28152
28460
  break;
28153
28461
  case '1.2':
28154
28462
  case 'next':
@@ -28156,7 +28464,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
28156
28464
  this.directives.yaml.version = version;
28157
28465
  else
28158
28466
  this.directives = new Directives({ version });
28159
- opt = { merge: false, resolveKnownTags: true, schema: 'core' };
28467
+ opt = { resolveKnownTags: true, schema: 'core' };
28160
28468
  break;
28161
28469
  case null:
28162
28470
  if (this.directives)
@@ -28269,7 +28577,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
28269
28577
  if (/[^ ]/.test(lineStr)) {
28270
28578
  let count = 1;
28271
28579
  const end = error.linePos[1];
28272
- if (end && end.line === line && end.col > col) {
28580
+ if (end?.line === line && end.col > col) {
28273
28581
  count = Math.max(1, Math.min(end.col - col, 80 - ci));
28274
28582
  }
28275
28583
  const pointer = ' '.repeat(ci) + '^'.repeat(count);
@@ -28334,7 +28642,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
28334
28642
  if (atNewline) {
28335
28643
  if (comment)
28336
28644
  comment += token.source;
28337
- else
28645
+ else if (!found || indicator !== 'seq-item-ind')
28338
28646
  spaceBefore = true;
28339
28647
  }
28340
28648
  else
@@ -28351,8 +28659,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
28351
28659
  if (token.source.endsWith(':'))
28352
28660
  onError(token.offset + token.source.length - 1, 'BAD_ALIAS', 'Anchor ending in : is ambiguous', true);
28353
28661
  anchor = token;
28354
- if (start === null)
28355
- start = token.offset;
28662
+ start ?? (start = token.offset);
28356
28663
  atNewline = false;
28357
28664
  hasSpace = false;
28358
28665
  reqSpace = true;
@@ -28361,8 +28668,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
28361
28668
  if (tag)
28362
28669
  onError(token, 'MULTIPLE_TAGS', 'A node can have at most one tag');
28363
28670
  tag = token;
28364
- if (start === null)
28365
- start = token.offset;
28671
+ start ?? (start = token.offset);
28366
28672
  atNewline = false;
28367
28673
  hasSpace = false;
28368
28674
  reqSpace = true;
@@ -28475,11 +28781,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
28475
28781
  return false;
28476
28782
  const isEqual = typeof uniqueKeys === 'function'
28477
28783
  ? uniqueKeys
28478
- : (a, b) => a === b ||
28479
- (isScalar$1(a) &&
28480
- isScalar$1(b) &&
28481
- a.value === b.value &&
28482
- !(a.value === '<<' && ctx.schema.merge));
28784
+ : (a, b) => a === b || (isScalar$1(a) && isScalar$1(b) && a.value === b.value);
28483
28785
  return items.some(pair => isEqual(pair.key, search));
28484
28786
  }
28485
28787
 
@@ -28528,12 +28830,14 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
28528
28830
  onError(offset, 'BAD_INDENT', startColMsg);
28529
28831
  }
28530
28832
  // key value
28833
+ ctx.atKey = true;
28531
28834
  const keyStart = keyProps.end;
28532
28835
  const keyNode = key
28533
28836
  ? composeNode(ctx, key, keyProps, onError)
28534
28837
  : composeEmptyNode(ctx, keyStart, start, null, keyProps, onError);
28535
28838
  if (ctx.schema.compat)
28536
28839
  flowIndentCheck(bm.indent, key, onError);
28840
+ ctx.atKey = false;
28537
28841
  if (mapIncludes(ctx, map.items, keyNode))
28538
28842
  onError(keyStart, 'DUPLICATE_KEY', 'Map keys must be unique');
28539
28843
  // value properties
@@ -28593,6 +28897,8 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
28593
28897
  const seq = new NodeClass(ctx.schema);
28594
28898
  if (ctx.atRoot)
28595
28899
  ctx.atRoot = false;
28900
+ if (ctx.atKey)
28901
+ ctx.atKey = false;
28596
28902
  let offset = bs.offset;
28597
28903
  let commentEnd = null;
28598
28904
  for (const { start, value } of bs.items) {
@@ -28606,7 +28912,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
28606
28912
  });
28607
28913
  if (!props.found) {
28608
28914
  if (props.anchor || props.tag || value) {
28609
- if (value && value.type === 'block-seq')
28915
+ if (value?.type === 'block-seq')
28610
28916
  onError(props.end, 'BAD_INDENT', 'All sequence items must start at the same column');
28611
28917
  else
28612
28918
  onError(offset, 'MISSING_CHAR', 'Sequence item without - indicator');
@@ -28677,6 +28983,8 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
28677
28983
  const atRoot = ctx.atRoot;
28678
28984
  if (atRoot)
28679
28985
  ctx.atRoot = false;
28986
+ if (ctx.atKey)
28987
+ ctx.atKey = false;
28680
28988
  let offset = fc.offset + fc.start.source.length;
28681
28989
  for (let i = 0; i < fc.items.length; ++i) {
28682
28990
  const collItem = fc.items[i];
@@ -28756,12 +29064,14 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
28756
29064
  else {
28757
29065
  // item is a key+value pair
28758
29066
  // key value
29067
+ ctx.atKey = true;
28759
29068
  const keyStart = props.end;
28760
29069
  const keyNode = key
28761
29070
  ? composeNode(ctx, key, props, onError)
28762
29071
  : composeEmptyNode(ctx, keyStart, start, null, props, onError);
28763
29072
  if (isBlock(key))
28764
29073
  onError(keyNode.range, 'BLOCK_IN_FLOW', blockMsg);
29074
+ ctx.atKey = false;
28765
29075
  // value properties
28766
29076
  const valueProps = resolveProps(sep ?? [], {
28767
29077
  flow: fcName,
@@ -28788,7 +29098,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
28788
29098
  }
28789
29099
  }
28790
29100
  else if (value) {
28791
- if ('source' in value && value.source && value.source[0] === ':')
29101
+ if ('source' in value && value.source?.[0] === ':')
28792
29102
  onError(value, 'MISSING_CHAR', `Missing space after : in ${fcName}`);
28793
29103
  else
28794
29104
  onError(valueProps.start, 'MISSING_CHAR', `Missing , or : between ${fcName} items`);
@@ -28832,7 +29142,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
28832
29142
  const expectedEnd = isMap ? '}' : ']';
28833
29143
  const [ce, ...ee] = fc.end;
28834
29144
  let cePos = offset;
28835
- if (ce && ce.source === expectedEnd)
29145
+ if (ce?.source === expectedEnd)
28836
29146
  cePos = ce.offset + ce.source.length;
28837
29147
  else {
28838
29148
  const name = fcName[0].toUpperCase() + fcName.substring(1);
@@ -28912,13 +29222,13 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
28912
29222
  let tag = ctx.schema.tags.find(t => t.tag === tagName && t.collection === expType);
28913
29223
  if (!tag) {
28914
29224
  const kt = ctx.schema.knownTags[tagName];
28915
- if (kt && kt.collection === expType) {
29225
+ if (kt?.collection === expType) {
28916
29226
  ctx.schema.tags.push(Object.assign({}, kt, { default: false }));
28917
29227
  tag = kt;
28918
29228
  }
28919
29229
  else {
28920
- if (kt?.collection) {
28921
- onError(tagToken, 'BAD_COLLECTION_TYPE', `${kt.tag} used for ${expType} collection, but expects ${kt.collection}`, true);
29230
+ if (kt) {
29231
+ onError(tagToken, 'BAD_COLLECTION_TYPE', `${kt.tag} used for ${expType} collection, but expects ${kt.collection ?? 'scalar'}`, true);
28922
29232
  }
28923
29233
  else {
28924
29234
  onError(tagToken, 'TAG_RESOLVE_FAILED', `Unresolved tag: ${tagName}`, true);
@@ -29274,7 +29584,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
29274
29584
  next = source[++i + 1];
29275
29585
  }
29276
29586
  else if (next === 'x' || next === 'u' || next === 'U') {
29277
- const length = { x: 2, u: 4, U: 8 }[next];
29587
+ const length = next === 'x' ? 2 : next === 'u' ? 4 : 8;
29278
29588
  res += parseCharCode(source, i + 1, length, onError);
29279
29589
  i += length;
29280
29590
  }
@@ -29344,12 +29654,14 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
29344
29654
  const cc = source.substr(offset, length);
29345
29655
  const ok = cc.length === length && /^[0-9a-fA-F]+$/.test(cc);
29346
29656
  const code = ok ? parseInt(cc, 16) : NaN;
29347
- if (isNaN(code)) {
29657
+ try {
29658
+ return String.fromCodePoint(code);
29659
+ }
29660
+ catch {
29348
29661
  const raw = source.substr(offset - 2, length + 2);
29349
29662
  onError(offset - 2, 'BAD_DQ_ESCAPE', `Invalid escape sequence ${raw}`);
29350
29663
  return raw;
29351
29664
  }
29352
- return String.fromCodePoint(code);
29353
29665
  }
29354
29666
 
29355
29667
  function composeScalar(ctx, token, tagToken, onError) {
@@ -29359,11 +29671,16 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
29359
29671
  const tagName = tagToken
29360
29672
  ? ctx.directives.tagName(tagToken.source, msg => onError(tagToken, 'TAG_RESOLVE_FAILED', msg))
29361
29673
  : null;
29362
- const tag = tagToken && tagName
29363
- ? findScalarTagByName(ctx.schema, value, tagName, tagToken, onError)
29364
- : token.type === 'scalar'
29365
- ? findScalarTagByTest(ctx, value, token, onError)
29366
- : ctx.schema[SCALAR$1];
29674
+ let tag;
29675
+ if (ctx.options.stringKeys && ctx.atKey) {
29676
+ tag = ctx.schema[SCALAR$1];
29677
+ }
29678
+ else if (tagName)
29679
+ tag = findScalarTagByName(ctx.schema, value, tagName, tagToken, onError);
29680
+ else if (token.type === 'scalar')
29681
+ tag = findScalarTagByTest(ctx, value, token, onError);
29682
+ else
29683
+ tag = ctx.schema[SCALAR$1];
29367
29684
  let scalar;
29368
29685
  try {
29369
29686
  const res = tag.resolve(value, msg => onError(tagToken ?? token, 'TAG_RESOLVE_FAILED', msg), ctx.options);
@@ -29411,8 +29728,9 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
29411
29728
  onError(tagToken, 'TAG_RESOLVE_FAILED', `Unresolved tag: ${tagName}`, tagName !== 'tag:yaml.org,2002:str');
29412
29729
  return schema[SCALAR$1];
29413
29730
  }
29414
- function findScalarTagByTest({ directives, schema }, value, token, onError) {
29415
- const tag = schema.tags.find(tag => tag.default && tag.test?.test(value)) || schema[SCALAR$1];
29731
+ function findScalarTagByTest({ atKey, directives, schema }, value, token, onError) {
29732
+ const tag = schema.tags.find(tag => (tag.default === true || (atKey && tag.default === 'key')) &&
29733
+ tag.test?.test(value)) || schema[SCALAR$1];
29416
29734
  if (schema.compat) {
29417
29735
  const compat = schema.compat.find(tag => tag.default && tag.test?.test(value)) ??
29418
29736
  schema[SCALAR$1];
@@ -29428,8 +29746,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
29428
29746
 
29429
29747
  function emptyScalarPosition(offset, before, pos) {
29430
29748
  if (before) {
29431
- if (pos === null)
29432
- pos = before.length;
29749
+ pos ?? (pos = before.length);
29433
29750
  for (let i = pos - 1; i >= 0; --i) {
29434
29751
  let st = before[i];
29435
29752
  switch (st.type) {
@@ -29454,6 +29771,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
29454
29771
 
29455
29772
  const CN = { composeNode, composeEmptyNode };
29456
29773
  function composeNode(ctx, token, props, onError) {
29774
+ const atKey = ctx.atKey;
29457
29775
  const { spaceBefore, comment, anchor, tag } = props;
29458
29776
  let node;
29459
29777
  let isSrcToken = true;
@@ -29474,21 +29792,36 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
29474
29792
  case 'block-map':
29475
29793
  case 'block-seq':
29476
29794
  case 'flow-collection':
29477
- node = composeCollection(CN, ctx, token, props, onError);
29478
- if (anchor)
29479
- node.anchor = anchor.source.substring(1);
29795
+ try {
29796
+ node = composeCollection(CN, ctx, token, props, onError);
29797
+ if (anchor)
29798
+ node.anchor = anchor.source.substring(1);
29799
+ }
29800
+ catch (error) {
29801
+ // Almost certainly here due to a stack overflow
29802
+ const message = error instanceof Error ? error.message : String(error);
29803
+ onError(token, 'RESOURCE_EXHAUSTION', message);
29804
+ }
29480
29805
  break;
29481
29806
  default: {
29482
29807
  const message = token.type === 'error'
29483
29808
  ? token.message
29484
29809
  : `Unsupported token (type: ${token.type})`;
29485
29810
  onError(token, 'UNEXPECTED_TOKEN', message);
29486
- node = composeEmptyNode(ctx, token.offset, undefined, null, props, onError);
29487
29811
  isSrcToken = false;
29488
29812
  }
29489
29813
  }
29814
+ node ?? (node = composeEmptyNode(ctx, token.offset, undefined, null, props, onError));
29490
29815
  if (anchor && node.anchor === '')
29491
29816
  onError(anchor, 'BAD_ALIAS', 'Anchor cannot be an empty string');
29817
+ if (atKey &&
29818
+ ctx.options.stringKeys &&
29819
+ (!isScalar$1(node) ||
29820
+ typeof node.value !== 'string' ||
29821
+ (node.tag && node.tag !== 'tag:yaml.org,2002:str'))) {
29822
+ const msg = 'With stringKeys, all keys must be strings';
29823
+ onError(tag ?? token, 'NON_STRING_KEY', msg);
29824
+ }
29492
29825
  if (spaceBefore)
29493
29826
  node.spaceBefore = true;
29494
29827
  if (comment) {
@@ -29541,6 +29874,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
29541
29874
  const opts = Object.assign({ _directives: directives }, options);
29542
29875
  const doc = new Document(undefined, opts);
29543
29876
  const ctx = {
29877
+ atKey: false,
29544
29878
  atRoot: true,
29545
29879
  directives: doc.directives,
29546
29880
  options: doc.options,
@@ -29662,8 +29996,10 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
29662
29996
  }
29663
29997
  }
29664
29998
  if (afterDoc) {
29665
- Array.prototype.push.apply(doc.errors, this.errors);
29666
- Array.prototype.push.apply(doc.warnings, this.warnings);
29999
+ for (let i = 0; i < this.errors.length; ++i)
30000
+ doc.errors.push(this.errors[i]);
30001
+ for (let i = 0; i < this.warnings.length; ++i)
30002
+ doc.warnings.push(this.warnings[i]);
29667
30003
  }
29668
30004
  else {
29669
30005
  doc.errors = this.errors;
@@ -30566,7 +30902,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
30566
30902
  const n = (yield* this.pushCount(1)) + (yield* this.pushSpaces(true));
30567
30903
  this.indentNext = this.indentValue + 1;
30568
30904
  this.indentValue += n;
30569
- return yield* this.parseBlockStart();
30905
+ return 'block-start';
30570
30906
  }
30571
30907
  return 'doc';
30572
30908
  }
@@ -30887,32 +31223,36 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
30887
31223
  return 0;
30888
31224
  }
30889
31225
  *pushIndicators() {
30890
- switch (this.charAt(0)) {
30891
- case '!':
30892
- return ((yield* this.pushTag()) +
30893
- (yield* this.pushSpaces(true)) +
30894
- (yield* this.pushIndicators()));
30895
- case '&':
30896
- return ((yield* this.pushUntil(isNotAnchorChar)) +
30897
- (yield* this.pushSpaces(true)) +
30898
- (yield* this.pushIndicators()));
30899
- case '-': // this is an error
30900
- case '?': // this is an error outside flow collections
30901
- case ':': {
30902
- const inFlow = this.flowLevel > 0;
30903
- const ch1 = this.charAt(1);
30904
- if (isEmpty(ch1) || (inFlow && flowIndicatorChars.has(ch1))) {
30905
- if (!inFlow)
30906
- this.indentNext = this.indentValue + 1;
30907
- else if (this.flowKey)
30908
- this.flowKey = false;
30909
- return ((yield* this.pushCount(1)) +
30910
- (yield* this.pushSpaces(true)) +
30911
- (yield* this.pushIndicators()));
31226
+ let n = 0;
31227
+ loop: while (true) {
31228
+ switch (this.charAt(0)) {
31229
+ case '!':
31230
+ n += yield* this.pushTag();
31231
+ n += yield* this.pushSpaces(true);
31232
+ continue loop;
31233
+ case '&':
31234
+ n += yield* this.pushUntil(isNotAnchorChar);
31235
+ n += yield* this.pushSpaces(true);
31236
+ continue loop;
31237
+ case '-': // this is an error
31238
+ case '?': // this is an error outside flow collections
31239
+ case ':': {
31240
+ const inFlow = this.flowLevel > 0;
31241
+ const ch1 = this.charAt(1);
31242
+ if (isEmpty(ch1) || (inFlow && flowIndicatorChars.has(ch1))) {
31243
+ if (!inFlow)
31244
+ this.indentNext = this.indentValue + 1;
31245
+ else if (this.flowKey)
31246
+ this.flowKey = false;
31247
+ n += yield* this.pushCount(1);
31248
+ n += yield* this.pushSpaces(true);
31249
+ continue loop;
31250
+ }
30912
31251
  }
30913
31252
  }
31253
+ break loop;
30914
31254
  }
30915
- return 0;
31255
+ return n;
30916
31256
  }
30917
31257
  *pushTag() {
30918
31258
  if (this.charAt(1) === '<') {
@@ -31074,6 +31414,14 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
31074
31414
  }
31075
31415
  return prev.splice(i, prev.length);
31076
31416
  }
31417
+ function arrayPushArray(target, source) {
31418
+ // May exhaust call stack with large `source` array
31419
+ if (source.length < 1e5)
31420
+ Array.prototype.push.apply(target, source);
31421
+ else
31422
+ for (let i = 0; i < source.length; ++i)
31423
+ target.push(source[i]);
31424
+ }
31077
31425
  function fixFlowSeqItems(fc) {
31078
31426
  if (fc.start.type === 'flow-seq-start') {
31079
31427
  for (const it of fc.items) {
@@ -31086,12 +31434,12 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
31086
31434
  delete it.key;
31087
31435
  if (isFlowToken(it.value)) {
31088
31436
  if (it.value.end)
31089
- Array.prototype.push.apply(it.value.end, it.sep);
31437
+ arrayPushArray(it.value.end, it.sep);
31090
31438
  else
31091
31439
  it.value.end = it.sep;
31092
31440
  }
31093
31441
  else
31094
- Array.prototype.push.apply(it.start, it.sep);
31442
+ arrayPushArray(it.start, it.sep);
31095
31443
  delete it.sep;
31096
31444
  }
31097
31445
  }
@@ -31233,7 +31581,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
31233
31581
  }
31234
31582
  *step() {
31235
31583
  const top = this.peek(1);
31236
- if (this.type === 'doc-end' && (!top || top.type !== 'doc-end')) {
31584
+ if (this.type === 'doc-end' && top?.type !== 'doc-end') {
31237
31585
  while (this.stack.length > 0)
31238
31586
  yield* this.pop();
31239
31587
  this.stack.push({
@@ -31509,7 +31857,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
31509
31857
  const prev = map.items[map.items.length - 2];
31510
31858
  const end = prev?.value?.end;
31511
31859
  if (Array.isArray(end)) {
31512
- Array.prototype.push.apply(end, it.start);
31860
+ arrayPushArray(end, it.start);
31513
31861
  end.push(this.sourceToken);
31514
31862
  map.items.pop();
31515
31863
  return;
@@ -31675,7 +32023,20 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
31675
32023
  default: {
31676
32024
  const bv = this.startBlockValue(map);
31677
32025
  if (bv) {
31678
- if (atMapIndent && bv.type !== 'block-seq') {
32026
+ if (bv.type === 'block-seq') {
32027
+ if (!it.explicitKey &&
32028
+ it.sep &&
32029
+ !includesToken(it.sep, 'newline')) {
32030
+ yield* this.pop({
32031
+ type: 'error',
32032
+ offset: this.offset,
32033
+ message: 'Unexpected block-seq-ind on same line with key',
32034
+ source: this.source
32035
+ });
32036
+ return;
32037
+ }
32038
+ }
32039
+ else if (atMapIndent) {
31679
32040
  map.items.push({ start });
31680
32041
  }
31681
32042
  this.stack.push(bv);
@@ -31711,7 +32072,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
31711
32072
  const prev = seq.items[seq.items.length - 2];
31712
32073
  const end = prev?.value?.end;
31713
32074
  if (Array.isArray(end)) {
31714
- Array.prototype.push.apply(end, it.start);
32075
+ arrayPushArray(end, it.start);
31715
32076
  end.push(this.sourceToken);
31716
32077
  seq.items.pop();
31717
32078
  return;
@@ -31752,7 +32113,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
31752
32113
  do {
31753
32114
  yield* this.pop();
31754
32115
  top = this.peek(1);
31755
- } while (top && top.type === 'flow-collection');
32116
+ } while (top?.type === 'flow-collection');
31756
32117
  }
31757
32118
  else if (fc.end.length === 0) {
31758
32119
  switch (this.type) {
@@ -32046,6 +32407,8 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
32046
32407
  if (!keepUndefined)
32047
32408
  return undefined;
32048
32409
  }
32410
+ if (isDocument(value) && !_replacer)
32411
+ return value.toString(options);
32049
32412
  return new Document(value, _replacer, options).toString(options);
32050
32413
  }
32051
32414