@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.
Files changed (153) hide show
  1. package/cjs/package.json +4 -10
  2. package/cjs/src/authToken.spec.js +5 -0
  3. package/cjs/src/authToken.spec.js.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 +6 -0
  7. package/cjs/src/embed/app.js.map +1 -1
  8. package/cjs/src/embed/app.spec.js +11 -2
  9. package/cjs/src/embed/app.spec.js.map +1 -1
  10. package/cjs/src/embed/conversation.d.ts +12 -0
  11. package/cjs/src/embed/conversation.d.ts.map +1 -1
  12. package/cjs/src/embed/conversation.js.map +1 -1
  13. package/cjs/src/embed/conversation.spec.js +30 -0
  14. package/cjs/src/embed/conversation.spec.js.map +1 -1
  15. package/cjs/src/embed/embedConfig.spec.d.ts +2 -0
  16. package/cjs/src/embed/embedConfig.spec.d.ts.map +1 -0
  17. package/cjs/src/embed/embedConfig.spec.js +74 -0
  18. package/cjs/src/embed/embedConfig.spec.js.map +1 -0
  19. package/cjs/src/embed/host-events.spec.d.ts +2 -0
  20. package/cjs/src/embed/host-events.spec.d.ts.map +1 -0
  21. package/cjs/src/embed/host-events.spec.js +1219 -0
  22. package/cjs/src/embed/host-events.spec.js.map +1 -0
  23. package/cjs/src/embed/liveboard.d.ts +6 -0
  24. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  25. package/cjs/src/embed/liveboard.js.map +1 -1
  26. package/cjs/src/embed/spotter-viz-utils.d.ts +29 -0
  27. package/cjs/src/embed/spotter-viz-utils.d.ts.map +1 -1
  28. package/cjs/src/embed/spotter-viz-utils.js.map +1 -1
  29. package/cjs/src/index.d.ts +2 -2
  30. package/cjs/src/index.d.ts.map +1 -1
  31. package/cjs/src/index.js.map +1 -1
  32. package/cjs/src/mixpanel-service.spec.js +14 -0
  33. package/cjs/src/mixpanel-service.spec.js.map +1 -1
  34. package/cjs/src/types.d.ts +93 -6
  35. package/cjs/src/types.d.ts.map +1 -1
  36. package/cjs/src/types.js +88 -3
  37. package/cjs/src/types.js.map +1 -1
  38. package/cjs/src/utils/custom-actions.spec.js +26 -0
  39. package/cjs/src/utils/custom-actions.spec.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/processData.spec.js +30 -0
  43. package/cjs/src/utils/processData.spec.js.map +1 -1
  44. package/cjs/src/utils/reporting.spec.js +21 -0
  45. package/cjs/src/utils/reporting.spec.js.map +1 -1
  46. package/cjs/src/utils/sessionInfoService.spec.d.ts +2 -0
  47. package/cjs/src/utils/sessionInfoService.spec.d.ts.map +1 -0
  48. package/cjs/src/utils/sessionInfoService.spec.js +130 -0
  49. package/cjs/src/utils/sessionInfoService.spec.js.map +1 -0
  50. package/cjs/src/utils.js +2 -3
  51. package/cjs/src/utils.js.map +1 -1
  52. package/cjs/src/utils.spec.js +158 -0
  53. package/cjs/src/utils.spec.js.map +1 -1
  54. package/dist/{index-CS7yJ2Jj.js → index-B5xoN6Cp.js} +303 -187
  55. package/dist/src/embed/app.d.ts +7 -1
  56. package/dist/src/embed/app.d.ts.map +1 -1
  57. package/dist/src/embed/conversation.d.ts +12 -0
  58. package/dist/src/embed/conversation.d.ts.map +1 -1
  59. package/dist/src/embed/embedConfig.spec.d.ts +2 -0
  60. package/dist/src/embed/embedConfig.spec.d.ts.map +1 -0
  61. package/dist/src/embed/host-events.spec.d.ts +2 -0
  62. package/dist/src/embed/host-events.spec.d.ts.map +1 -0
  63. package/dist/src/embed/liveboard.d.ts +6 -0
  64. package/dist/src/embed/liveboard.d.ts.map +1 -1
  65. package/dist/src/embed/spotter-viz-utils.d.ts +29 -0
  66. package/dist/src/embed/spotter-viz-utils.d.ts.map +1 -1
  67. package/dist/src/index.d.ts +2 -2
  68. package/dist/src/index.d.ts.map +1 -1
  69. package/dist/src/types.d.ts +93 -6
  70. package/dist/src/types.d.ts.map +1 -1
  71. package/dist/src/utils/sessionInfoService.spec.d.ts +2 -0
  72. package/dist/src/utils/sessionInfoService.spec.d.ts.map +1 -0
  73. package/dist/tsembed-react.es.js +126 -18
  74. package/dist/tsembed-react.js +427 -203
  75. package/dist/tsembed.es.js +126 -18
  76. package/dist/tsembed.js +427 -203
  77. package/dist/visual-embed-sdk-react-full.d.ts +147 -7
  78. package/dist/visual-embed-sdk-react.d.ts +147 -7
  79. package/dist/visual-embed-sdk.d.ts +147 -7
  80. package/lib/package.json +4 -10
  81. package/lib/src/authToken.spec.js +5 -0
  82. package/lib/src/authToken.spec.js.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 +6 -0
  86. package/lib/src/embed/app.js.map +1 -1
  87. package/lib/src/embed/app.spec.js +11 -2
  88. package/lib/src/embed/app.spec.js.map +1 -1
  89. package/lib/src/embed/conversation.d.ts +12 -0
  90. package/lib/src/embed/conversation.d.ts.map +1 -1
  91. package/lib/src/embed/conversation.js.map +1 -1
  92. package/lib/src/embed/conversation.spec.js +30 -0
  93. package/lib/src/embed/conversation.spec.js.map +1 -1
  94. package/lib/src/embed/embedConfig.spec.d.ts +2 -0
  95. package/lib/src/embed/embedConfig.spec.d.ts.map +1 -0
  96. package/lib/src/embed/embedConfig.spec.js +72 -0
  97. package/lib/src/embed/embedConfig.spec.js.map +1 -0
  98. package/lib/src/embed/host-events.spec.d.ts +2 -0
  99. package/lib/src/embed/host-events.spec.d.ts.map +1 -0
  100. package/lib/src/embed/host-events.spec.js +1216 -0
  101. package/lib/src/embed/host-events.spec.js.map +1 -0
  102. package/lib/src/embed/liveboard.d.ts +6 -0
  103. package/lib/src/embed/liveboard.d.ts.map +1 -1
  104. package/lib/src/embed/liveboard.js.map +1 -1
  105. package/lib/src/embed/spotter-viz-utils.d.ts +29 -0
  106. package/lib/src/embed/spotter-viz-utils.d.ts.map +1 -1
  107. package/lib/src/embed/spotter-viz-utils.js.map +1 -1
  108. package/lib/src/index.d.ts +2 -2
  109. package/lib/src/index.d.ts.map +1 -1
  110. package/lib/src/index.js.map +1 -1
  111. package/lib/src/mixpanel-service.spec.js +14 -0
  112. package/lib/src/mixpanel-service.spec.js.map +1 -1
  113. package/lib/src/types.d.ts +93 -6
  114. package/lib/src/types.d.ts.map +1 -1
  115. package/lib/src/types.js +88 -3
  116. package/lib/src/types.js.map +1 -1
  117. package/lib/src/utils/custom-actions.spec.js +26 -0
  118. package/lib/src/utils/custom-actions.spec.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/processData.spec.js +30 -0
  122. package/lib/src/utils/processData.spec.js.map +1 -1
  123. package/lib/src/utils/reporting.spec.js +21 -0
  124. package/lib/src/utils/reporting.spec.js.map +1 -1
  125. package/lib/src/utils/sessionInfoService.spec.d.ts +2 -0
  126. package/lib/src/utils/sessionInfoService.spec.d.ts.map +1 -0
  127. package/lib/src/utils/sessionInfoService.spec.js +127 -0
  128. package/lib/src/utils/sessionInfoService.spec.js.map +1 -0
  129. package/lib/src/utils.js +1 -1
  130. package/lib/src/utils.js.map +1 -1
  131. package/lib/src/utils.spec.js +159 -1
  132. package/lib/src/utils.spec.js.map +1 -1
  133. package/lib/src/visual-embed-sdk.d.ts +147 -7
  134. package/package.json +4 -10
  135. package/src/authToken.spec.ts +6 -0
  136. package/src/embed/app.spec.ts +15 -2
  137. package/src/embed/app.ts +13 -1
  138. package/src/embed/conversation.spec.ts +32 -0
  139. package/src/embed/conversation.ts +12 -0
  140. package/src/embed/embedConfig.spec.ts +79 -0
  141. package/src/embed/host-events.spec.ts +1635 -0
  142. package/src/embed/liveboard.ts +6 -0
  143. package/src/embed/spotter-viz-utils.ts +30 -0
  144. package/src/index.ts +2 -1
  145. package/src/mixpanel-service.spec.ts +15 -0
  146. package/src/types.ts +96 -6
  147. package/src/utils/custom-actions.spec.ts +28 -0
  148. package/src/utils/graphql/answerService/answerService.spec.ts +18 -0
  149. package/src/utils/processData.spec.ts +32 -0
  150. package/src/utils/reporting.spec.ts +27 -0
  151. package/src/utils/sessionInfoService.spec.ts +151 -0
  152. package/src/utils.spec.ts +195 -0
  153. package/src/utils.ts +1 -1
@@ -1,4 +1,4 @@
1
- /* @thoughtspot/visual-embed-sdk version 1.49.2 */
1
+ /* @thoughtspot/visual-embed-sdk version 1.50.0 */
2
2
  'use client';
3
3
  (function (global, factory) {
4
4
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) :
@@ -163,28 +163,45 @@
163
163
  }
164
164
  return false;
165
165
  };
166
- const merge = (...objects) => objects.reduce((result, current) => {
166
+ const UNSAFE_KEYS = new Set([
167
+ "__proto__",
168
+ "constructor",
169
+ "prototype",
170
+ "toString",
171
+ "valueOf",
172
+ "hasOwnProperty",
173
+ "isPrototypeOf",
174
+ "propertyIsEnumerable",
175
+ "toLocaleString",
176
+ ]);
177
+ const merge$1 = (...objects) => objects.reduce((result, current) => {
178
+ if (current === undefined) {
179
+ return result;
180
+ }
167
181
  if (Array.isArray(current)) {
168
182
  throw new TypeError("Arguments provided to ts-deepmerge must be objects, not arrays.");
169
183
  }
170
184
  Object.keys(current).forEach((key) => {
171
- if (["__proto__", "constructor", "prototype"].includes(key)) {
185
+ if (UNSAFE_KEYS.has(key)) {
172
186
  return;
173
187
  }
174
188
  if (Array.isArray(result[key]) && Array.isArray(current[key])) {
175
- result[key] = merge.options.mergeArrays
176
- ? merge.options.uniqueArrayItems
189
+ result[key] = merge$1.options.mergeArrays
190
+ ? merge$1.options.uniqueArrayItems
177
191
  ? Array.from(new Set(result[key].concat(current[key])))
178
192
  : [...result[key], ...current[key]]
179
193
  : current[key];
180
194
  }
181
195
  else if (isObject$1(result[key]) && isObject$1(current[key])) {
182
- result[key] = merge(result[key], current[key]);
196
+ result[key] = merge$1(result[key], current[key]);
197
+ }
198
+ else if (!isObject$1(result[key]) && isObject$1(current[key])) {
199
+ result[key] = merge$1(current[key], undefined);
183
200
  }
184
201
  else {
185
202
  result[key] =
186
203
  current[key] === undefined
187
- ? merge.options.allowUndefinedOverrides
204
+ ? merge$1.options.allowUndefinedOverrides
188
205
  ? current[key]
189
206
  : result[key]
190
207
  : current[key];
@@ -197,11 +214,11 @@
197
214
  mergeArrays: true,
198
215
  uniqueArrayItems: true,
199
216
  };
200
- merge.options = defaultOptions;
201
- merge.withOptions = (options, ...objects) => {
202
- merge.options = Object.assign(Object.assign({}, defaultOptions), options);
203
- const result = merge(...objects);
204
- merge.options = defaultOptions;
217
+ merge$1.options = defaultOptions;
218
+ merge$1.withOptions = (options, ...objects) => {
219
+ merge$1.options = Object.assign(Object.assign({}, defaultOptions), options);
220
+ const result = merge$1(...objects);
221
+ merge$1.options = defaultOptions;
205
222
  return result;
206
223
  };
207
224
 
@@ -2013,10 +2030,11 @@
2013
2030
  */
2014
2031
  EmbedEvent["EmbedPageContextChanged"] = "EmbedPageContextChanged";
2015
2032
  /**
2016
- * Represents a special embed event that is triggered whenever any host event is subscribed.
2033
+ * Represents a special embed event that is triggered whenever any host event is
2034
+ * subscribed.
2017
2035
  *
2018
- * You can listen to this event when you need to dispatch a host event during load or render,
2019
- * particularly in situations where timing issues may occur.
2036
+ * You can listen to this event when you need to dispatch a host event during load or
2037
+ * render, particularly in situations where timing issues may occur.
2020
2038
  *
2021
2039
  * @example
2022
2040
  * ```js
@@ -4256,6 +4274,24 @@
4256
4274
  * ```
4257
4275
  */
4258
4276
  HostEvent["InitSpotterVizConversation"] = "InitSpotterVizConversation";
4277
+ /**
4278
+ * Opens the SpotterViz panel.
4279
+ * @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
4280
+ * @example
4281
+ * ```js
4282
+ * liveboardEmbed.trigger(HostEvent.OpenSpotterVizPanel);
4283
+ * ```
4284
+ */
4285
+ HostEvent["OpenSpotterVizPanel"] = "OpenSpotterVizPanel";
4286
+ /**
4287
+ * Closes the SpotterViz panel.
4288
+ * @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
4289
+ * @example
4290
+ * ```js
4291
+ * liveboardEmbed.trigger(HostEvent.CloseSpotterVizPanel);
4292
+ * ```
4293
+ */
4294
+ HostEvent["CloseSpotterVizPanel"] = "CloseSpotterVizPanel";
4259
4295
  /**
4260
4296
  * Clears browser cache and fetches new data for liveboard ChartViz Containers.
4261
4297
  * Requires `enableLiveboardDataCache` to be enabled.
@@ -6180,6 +6216,72 @@
6180
6216
  * @version SDK: 1.49.0 | ThoughtSpot Cloud: 26.6.0.cl
6181
6217
  */
6182
6218
  Action["RefreshLiveboardBrowserCache"] = "refreshLiveboardBrowserCache";
6219
+ /**
6220
+ * Controls visibility and disable state of the share action
6221
+ * in the Spotter Analyst interface.
6222
+ * @version SDK: 1.51.0 | ThoughtSpot Cloud: 26.8.0.cl
6223
+ * @example
6224
+ * ```js
6225
+ * hiddenActions: [Action.SpotterAnalystShare]
6226
+ * disabledActions: [Action.SpotterAnalystShare]
6227
+ * ```
6228
+ */
6229
+ Action["SpotterAnalystShare"] = "spotterAnalystShare";
6230
+ /**
6231
+ * Controls visibility and disable state of the edit action
6232
+ * in the Spotter Analyst interface.
6233
+ * @version SDK: 1.51.0 | ThoughtSpot Cloud: 26.8.0.cl
6234
+ * @example
6235
+ * ```js
6236
+ * hiddenActions: [Action.SpotterAnalystEdit]
6237
+ * disabledActions: [Action.SpotterAnalystEdit]
6238
+ * ```
6239
+ */
6240
+ Action["SpotterAnalystEdit"] = "spotterAnalystEdit";
6241
+ /**
6242
+ * Controls visibility and disable state of the create action
6243
+ * in the Spotter Analyst interface.
6244
+ * @version SDK: 1.51.0 | ThoughtSpot Cloud: 26.8.0.cl
6245
+ * @example
6246
+ * ```js
6247
+ * hiddenActions: [Action.SpotterAnalystCreate]
6248
+ * disabledActions: [Action.SpotterAnalystCreate]
6249
+ * ```
6250
+ */
6251
+ Action["SpotterAnalystCreate"] = "spotterAnalystCreate";
6252
+ /**
6253
+ * Controls visibility and disable state of the delete action
6254
+ * in the Spotter Analyst interface.
6255
+ * @version SDK: 1.51.0 | ThoughtSpot Cloud: 26.8.0.cl
6256
+ * @example
6257
+ * ```js
6258
+ * hiddenActions: [Action.SpotterAnalystDelete]
6259
+ * disabledActions: [Action.SpotterAnalystDelete]
6260
+ * ```
6261
+ */
6262
+ Action["SpotterAnalystDelete"] = "spotterAnalystDelete";
6263
+ /**
6264
+ * Controls visibility and disable state of the make a copy action
6265
+ * in the Spotter Analyst interface.
6266
+ * @version SDK: 1.51.0 | ThoughtSpot Cloud: 26.8.0.cl
6267
+ * @example
6268
+ * ```js
6269
+ * hiddenActions: [Action.SpotterAnalystMakeACopy]
6270
+ * disabledActions: [Action.SpotterAnalystMakeACopy]
6271
+ * ```
6272
+ */
6273
+ Action["SpotterAnalystMakeACopy"] = "spotterAnalystMakeACopy";
6274
+ /**
6275
+ * Controls visibility and disable state of the sidebar
6276
+ * in the Spotter Analyst interface.
6277
+ * @version SDK: 1.51.0 | ThoughtSpot Cloud: 26.8.0.cl
6278
+ * @example
6279
+ * ```js
6280
+ * hiddenActions: [Action.SpotterAnalystSidebar]
6281
+ * disabledActions: [Action.SpotterAnalystSidebar]
6282
+ * ```
6283
+ */
6284
+ Action["SpotterAnalystSidebar"] = "spotterAnalystSidebar";
6183
6285
  })(exports.Action || (exports.Action = {}));
6184
6286
  var PrefetchFeatures;
6185
6287
  (function (PrefetchFeatures) {
@@ -6645,7 +6747,7 @@
6645
6747
  TableContentDensity["Compact"] = "COMPACT";
6646
6748
  })(TableContentDensity || (TableContentDensity = {}));
6647
6749
 
6648
- var version$1="1.49.2";var pkg = {version:version$1};
6750
+ var version$1="1.50.0";var pkg = {version:version$1};
6649
6751
 
6650
6752
  const { version } = pkg;
6651
6753
 
@@ -7013,7 +7115,7 @@
7013
7115
  }
7014
7116
  return null;
7015
7117
  }
7016
- const deepMerge = (target, source) => merge(target, source);
7118
+ const deepMerge = (target, source) => merge$1(target, source);
7017
7119
  const getOperationNameFromQuery = (query) => {
7018
7120
  const regex = /(?:query|mutation)\s+(\w+)/;
7019
7121
  const matches = query.match(regex);
@@ -22884,6 +22986,12 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22884
22986
  }
22885
22987
  if (discoveryExperience.homePage === HomePage.Focused) {
22886
22988
  params[Param.HomepageVersion] = HomePage.Focused;
22989
+ // The Focused (V4) homepage experience requires the updated
22990
+ // Spotter chat prompt. Enable it automatically unless the
22991
+ // developer has explicitly set updatedSpotterChatPrompt.
22992
+ if (isUndefined(updatedSpotterChatPrompt)) {
22993
+ params[Param.UpdatedSpotterChatPrompt] = true;
22994
+ }
22887
22995
  }
22888
22996
  }
22889
22997
  const queryParams = getQueryParamString(params, true);
@@ -25061,8 +25169,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
25061
25169
  return {
25062
25170
  onAnchor: (source) => {
25063
25171
  aliasObjects.push(source);
25064
- if (!prevAnchors)
25065
- prevAnchors = anchorNames(doc);
25172
+ prevAnchors ?? (prevAnchors = anchorNames(doc));
25066
25173
  const anchor = findNewAnchor(prefix, prevAnchors);
25067
25174
  prevAnchors.add(anchor);
25068
25175
  return anchor;
@@ -25226,23 +25333,38 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
25226
25333
  * Resolve the value of this alias within `doc`, finding the last
25227
25334
  * instance of the `source` anchor before this node.
25228
25335
  */
25229
- resolve(doc) {
25336
+ resolve(doc, ctx) {
25337
+ if (ctx?.maxAliasCount === 0)
25338
+ throw new ReferenceError('Alias resolution is disabled');
25339
+ let nodes;
25340
+ if (ctx?.aliasResolveCache) {
25341
+ nodes = ctx.aliasResolveCache;
25342
+ }
25343
+ else {
25344
+ nodes = [];
25345
+ visit$1(doc, {
25346
+ Node: (_key, node) => {
25347
+ if (isAlias(node) || hasAnchor(node))
25348
+ nodes.push(node);
25349
+ }
25350
+ });
25351
+ if (ctx)
25352
+ ctx.aliasResolveCache = nodes;
25353
+ }
25230
25354
  let found = undefined;
25231
- visit$1(doc, {
25232
- Node: (_key, node) => {
25233
- if (node === this)
25234
- return visit$1.BREAK;
25235
- if (node.anchor === this.source)
25236
- found = node;
25237
- }
25238
- });
25355
+ for (const node of nodes) {
25356
+ if (node === this)
25357
+ break;
25358
+ if (node.anchor === this.source)
25359
+ found = node;
25360
+ }
25239
25361
  return found;
25240
25362
  }
25241
25363
  toJSON(_arg, ctx) {
25242
25364
  if (!ctx)
25243
25365
  return { source: this.source };
25244
25366
  const { anchors, doc, maxAliasCount } = ctx;
25245
- const source = this.resolve(doc);
25367
+ const source = this.resolve(doc, ctx);
25246
25368
  if (!source) {
25247
25369
  const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;
25248
25370
  throw new ReferenceError(msg);
@@ -25254,7 +25376,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
25254
25376
  data = anchors.get(source);
25255
25377
  }
25256
25378
  /* istanbul ignore if */
25257
- if (!data || data.res === undefined) {
25379
+ if (data?.res === undefined) {
25258
25380
  const msg = 'This should not happen: Alias anchor was not resolved?';
25259
25381
  throw new ReferenceError(msg);
25260
25382
  }
@@ -25361,8 +25483,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
25361
25483
  if (aliasDuplicateObjects && value && typeof value === 'object') {
25362
25484
  ref = sourceObjects.get(value);
25363
25485
  if (ref) {
25364
- if (!ref.anchor)
25365
- ref.anchor = onAnchor(value);
25486
+ ref.anchor ?? (ref.anchor = onAnchor(value));
25366
25487
  return new Alias(ref.anchor);
25367
25488
  }
25368
25489
  else {
@@ -25873,7 +25994,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
25873
25994
  const { blockQuote, commentString, lineWidth } = ctx.options;
25874
25995
  // 1. Block can't end in whitespace unless the last line is non-empty.
25875
25996
  // 2. Strings consisting of only whitespace are best rendered explicitly.
25876
- if (!blockQuote || /\n[\t ]+$/.test(value) || /^\s*$/.test(value)) {
25997
+ if (!blockQuote || /\n[\t ]+$/.test(value)) {
25877
25998
  return quotedString(value, ctx);
25878
25999
  }
25879
26000
  const indent = ctx.indent ||
@@ -25933,23 +26054,32 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
25933
26054
  start = start.replace(/\n+/g, `$&${indent}`);
25934
26055
  }
25935
26056
  const indentSize = indent ? '2' : '1'; // root is at -1
25936
- let header = (literal ? '|' : '>') + (startWithSpace ? indentSize : '') + chomp;
26057
+ // Leading | or > is added later
26058
+ let header = (startWithSpace ? indentSize : '') + chomp;
25937
26059
  if (comment) {
25938
26060
  header += ' ' + commentString(comment.replace(/ ?[\r\n]+/g, ' '));
25939
26061
  if (onComment)
25940
26062
  onComment();
25941
26063
  }
25942
- if (literal) {
25943
- value = value.replace(/\n+/g, `$&${indent}`);
25944
- return `${header}\n${indent}${start}${value}${end}`;
26064
+ if (!literal) {
26065
+ const foldedValue = value
26066
+ .replace(/\n+/g, '\n$&')
26067
+ .replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, '$1$2') // more-indented lines aren't folded
26068
+ // ^ more-ind. ^ empty ^ capture next empty lines only at end of indent
26069
+ .replace(/\n+/g, `$&${indent}`);
26070
+ let literalFallback = false;
26071
+ const foldOptions = getFoldOptions(ctx, true);
26072
+ if (blockQuote !== 'folded' && type !== Scalar.BLOCK_FOLDED) {
26073
+ foldOptions.onOverflow = () => {
26074
+ literalFallback = true;
26075
+ };
26076
+ }
26077
+ const body = foldFlowLines(`${start}${foldedValue}${end}`, indent, FOLD_BLOCK, foldOptions);
26078
+ if (!literalFallback)
26079
+ return `>${header}\n${indent}${body}`;
25945
26080
  }
25946
- value = value
25947
- .replace(/\n+/g, '\n$&')
25948
- .replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, '$1$2') // more-indented lines aren't folded
25949
- // ^ more-ind. ^ empty ^ capture next empty lines only at end of indent
25950
- .replace(/\n+/g, `$&${indent}`);
25951
- const body = foldFlowLines(`${start}${value}${end}`, indent, FOLD_BLOCK, getFoldOptions(ctx, true));
25952
- return `${header}\n${indent}${body}`;
26081
+ value = value.replace(/\n+/g, `$&${indent}`);
26082
+ return `|${header}\n${indent}${start}${value}${end}`;
25953
26083
  }
25954
26084
  function plainString(item, ctx, onComment, onChompKeep) {
25955
26085
  const { type, value } = item;
@@ -25958,10 +26088,9 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
25958
26088
  (inFlow && /[[\]{},]/.test(value))) {
25959
26089
  return quotedString(value, ctx);
25960
26090
  }
25961
- if (!value ||
25962
- /^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(value)) {
26091
+ if (/^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(value)) {
25963
26092
  // not allowed:
25964
- // - empty string, '-' or '?'
26093
+ // - '-' or '?'
25965
26094
  // - start with an indicator character (except [?:-]) or /[?-] /
25966
26095
  // - '\n ', ': ' or ' \n' anywhere
25967
26096
  // - '#' not preceded by a non-space char
@@ -26056,6 +26185,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
26056
26185
  nullStr: 'null',
26057
26186
  simpleKeys: false,
26058
26187
  singleQuote: null,
26188
+ trailingComma: false,
26059
26189
  trueStr: 'true',
26060
26190
  verifyAliasOrder: true
26061
26191
  }, doc.schema.toStringOptions, options);
@@ -26090,7 +26220,12 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
26090
26220
  let obj;
26091
26221
  if (isScalar$1(item)) {
26092
26222
  obj = item.value;
26093
- const match = tags.filter(t => t.identify?.(obj));
26223
+ let match = tags.filter(t => t.identify?.(obj));
26224
+ if (match.length > 1) {
26225
+ const testMatch = match.filter(t => t.test);
26226
+ if (testMatch.length > 0)
26227
+ match = testMatch;
26228
+ }
26094
26229
  tagObj =
26095
26230
  match.find(t => t.format === item.format) ?? match.find(t => !t.format);
26096
26231
  }
@@ -26099,7 +26234,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
26099
26234
  tagObj = tags.find(t => t.nodeClass && obj instanceof t.nodeClass);
26100
26235
  }
26101
26236
  if (!tagObj) {
26102
- const name = obj?.constructor?.name ?? typeof obj;
26237
+ const name = obj?.constructor?.name ?? (obj === null ? 'null' : typeof obj);
26103
26238
  throw new Error(`Tag not resolved for ${name} value`);
26104
26239
  }
26105
26240
  return tagObj;
@@ -26114,7 +26249,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
26114
26249
  anchors.add(anchor);
26115
26250
  props.push(`&${anchor}`);
26116
26251
  }
26117
- const tag = node.tag ? node.tag : tagObj.default ? null : tagObj.tag;
26252
+ const tag = node.tag ?? (tagObj.default ? null : tagObj.tag);
26118
26253
  if (tag)
26119
26254
  props.push(doc.directives.tagString(tag));
26120
26255
  return props.join(' ');
@@ -26140,8 +26275,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
26140
26275
  const node = isNode(item)
26141
26276
  ? item
26142
26277
  : ctx.doc.createNode(item, { onTagObj: o => (tagObj = o) });
26143
- if (!tagObj)
26144
- tagObj = getTagObject(ctx.doc.schema.tags, node);
26278
+ tagObj ?? (tagObj = getTagObject(ctx.doc.schema.tags, node));
26145
26279
  const props = stringifyProps(node, tagObj, ctx);
26146
26280
  if (props.length > 0)
26147
26281
  ctx.indentAtStart = (ctx.indentAtStart ?? 0) + props.length + 1;
@@ -26255,7 +26389,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
26255
26389
  ws += `\n${indentComment(cs, ctx.indent)}`;
26256
26390
  }
26257
26391
  if (valueStr === '' && !ctx.inFlow) {
26258
- if (ws === '\n')
26392
+ if (ws === '\n' && valueComment)
26259
26393
  ws = '\n\n';
26260
26394
  }
26261
26395
  else {
@@ -26303,54 +26437,10 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
26303
26437
 
26304
26438
  function warn(logLevel, warning) {
26305
26439
  if (logLevel === 'debug' || logLevel === 'warn') {
26306
- if (typeof process !== 'undefined' && process.emitWarning)
26307
- process.emitWarning(warning);
26308
- else
26309
- console.warn(warning);
26440
+ console.warn(warning);
26310
26441
  }
26311
26442
  }
26312
26443
 
26313
- const MERGE_KEY = '<<';
26314
- function addPairToJSMap(ctx, map, { key, value }) {
26315
- if (ctx?.doc.schema.merge && isMergeKey(key)) {
26316
- value = isAlias(value) ? value.resolve(ctx.doc) : value;
26317
- if (isSeq(value))
26318
- for (const it of value.items)
26319
- mergeToJSMap(ctx, map, it);
26320
- else if (Array.isArray(value))
26321
- for (const it of value)
26322
- mergeToJSMap(ctx, map, it);
26323
- else
26324
- mergeToJSMap(ctx, map, value);
26325
- }
26326
- else {
26327
- const jsKey = toJS(key, '', ctx);
26328
- if (map instanceof Map) {
26329
- map.set(jsKey, toJS(value, jsKey, ctx));
26330
- }
26331
- else if (map instanceof Set) {
26332
- map.add(jsKey);
26333
- }
26334
- else {
26335
- const stringKey = stringifyKey(key, jsKey, ctx);
26336
- const jsValue = toJS(value, stringKey, ctx);
26337
- if (stringKey in map)
26338
- Object.defineProperty(map, stringKey, {
26339
- value: jsValue,
26340
- writable: true,
26341
- enumerable: true,
26342
- configurable: true
26343
- });
26344
- else
26345
- map[stringKey] = jsValue;
26346
- }
26347
- }
26348
- return map;
26349
- }
26350
- const isMergeKey = (key) => key === MERGE_KEY ||
26351
- (isScalar$1(key) &&
26352
- key.value === MERGE_KEY &&
26353
- (!key.type || key.type === Scalar.PLAIN));
26354
26444
  // If the value associated with a merge key is a single mapping node, each of
26355
26445
  // its key/value pairs is inserted into the current mapping, unless the key
26356
26446
  // already exists in it. If the value associated with the merge key is a
@@ -26358,8 +26448,36 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
26358
26448
  // of these nodes is merged in turn according to its order in the sequence.
26359
26449
  // Keys in mapping nodes earlier in the sequence override keys specified in
26360
26450
  // later mapping nodes. -- http://yaml.org/type/merge.html
26361
- function mergeToJSMap(ctx, map, value) {
26362
- const source = ctx && isAlias(value) ? value.resolve(ctx.doc) : value;
26451
+ const MERGE_KEY = '<<';
26452
+ const merge = {
26453
+ identify: value => value === MERGE_KEY ||
26454
+ (typeof value === 'symbol' && value.description === MERGE_KEY),
26455
+ default: 'key',
26456
+ tag: 'tag:yaml.org,2002:merge',
26457
+ test: /^<<$/,
26458
+ resolve: () => Object.assign(new Scalar(Symbol(MERGE_KEY)), {
26459
+ addToJSMap: addMergeToJSMap
26460
+ }),
26461
+ stringify: () => MERGE_KEY
26462
+ };
26463
+ const isMergeKey = (ctx, key) => (merge.identify(key) ||
26464
+ (isScalar$1(key) &&
26465
+ (!key.type || key.type === Scalar.PLAIN) &&
26466
+ merge.identify(key.value))) &&
26467
+ ctx?.doc.schema.tags.some(tag => tag.tag === merge.tag && tag.default);
26468
+ function addMergeToJSMap(ctx, map, value) {
26469
+ const source = resolveAliasValue(ctx, value);
26470
+ if (isSeq(source))
26471
+ for (const it of source.items)
26472
+ mergeValue(ctx, map, it);
26473
+ else if (Array.isArray(source))
26474
+ for (const it of source)
26475
+ mergeValue(ctx, map, it);
26476
+ else
26477
+ mergeValue(ctx, map, source);
26478
+ }
26479
+ function mergeValue(ctx, map, value) {
26480
+ const source = resolveAliasValue(ctx, value);
26363
26481
  if (!isMap(source))
26364
26482
  throw new Error('Merge sources must be maps or map aliases');
26365
26483
  const srcMap = source.toJSON(null, ctx, Map);
@@ -26382,9 +26500,44 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
26382
26500
  }
26383
26501
  return map;
26384
26502
  }
26503
+ function resolveAliasValue(ctx, value) {
26504
+ return ctx && isAlias(value) ? value.resolve(ctx.doc, ctx) : value;
26505
+ }
26506
+
26507
+ function addPairToJSMap(ctx, map, { key, value }) {
26508
+ if (isNode(key) && key.addToJSMap)
26509
+ key.addToJSMap(ctx, map, value);
26510
+ // TODO: Should drop this special case for bare << handling
26511
+ else if (isMergeKey(ctx, key))
26512
+ addMergeToJSMap(ctx, map, value);
26513
+ else {
26514
+ const jsKey = toJS(key, '', ctx);
26515
+ if (map instanceof Map) {
26516
+ map.set(jsKey, toJS(value, jsKey, ctx));
26517
+ }
26518
+ else if (map instanceof Set) {
26519
+ map.add(jsKey);
26520
+ }
26521
+ else {
26522
+ const stringKey = stringifyKey(key, jsKey, ctx);
26523
+ const jsValue = toJS(value, stringKey, ctx);
26524
+ if (stringKey in map)
26525
+ Object.defineProperty(map, stringKey, {
26526
+ value: jsValue,
26527
+ writable: true,
26528
+ enumerable: true,
26529
+ configurable: true
26530
+ });
26531
+ else
26532
+ map[stringKey] = jsValue;
26533
+ }
26534
+ }
26535
+ return map;
26536
+ }
26385
26537
  function stringifyKey(key, jsKey, ctx) {
26386
26538
  if (jsKey === null)
26387
26539
  return '';
26540
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
26388
26541
  if (typeof jsKey !== 'object')
26389
26542
  return String(jsKey);
26390
26543
  if (isNode(key) && ctx?.doc) {
@@ -26537,12 +26690,22 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
26537
26690
  if (comment)
26538
26691
  reqNewline = true;
26539
26692
  let str = stringify$2(item, itemCtx, () => (comment = null));
26540
- if (i < items.length - 1)
26693
+ reqNewline || (reqNewline = lines.length > linesAtValue || str.includes('\n'));
26694
+ if (i < items.length - 1) {
26541
26695
  str += ',';
26696
+ }
26697
+ else if (ctx.options.trailingComma) {
26698
+ if (ctx.options.lineWidth > 0) {
26699
+ reqNewline || (reqNewline = lines.reduce((sum, line) => sum + line.length + 2, 2) +
26700
+ (str.length + 2) >
26701
+ ctx.options.lineWidth);
26702
+ }
26703
+ if (reqNewline) {
26704
+ str += ',';
26705
+ }
26706
+ }
26542
26707
  if (comment)
26543
26708
  str += lineComment(str, itemIndent, commentString(comment));
26544
- if (!reqNewline && (lines.length > linesAtValue || str.includes('\n')))
26545
- reqNewline = true;
26546
26709
  lines.push(str);
26547
26710
  linesAtValue = lines.length;
26548
26711
  }
@@ -26887,11 +27050,12 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
26887
27050
  const num = typeof value === 'number' ? value : Number(value);
26888
27051
  if (!isFinite(num))
26889
27052
  return isNaN(num) ? '.nan' : num < 0 ? '-.inf' : '.inf';
26890
- let n = JSON.stringify(value);
27053
+ let n = Object.is(value, -0) ? '-0' : JSON.stringify(value);
26891
27054
  if (!format &&
26892
27055
  minFractionDigits &&
26893
27056
  (!tag || tag === 'tag:yaml.org,2002:float') &&
26894
- /^\d/.test(n)) {
27057
+ /^-?\d/.test(n) &&
27058
+ !n.includes('e')) {
26895
27059
  let i = n.indexOf('.');
26896
27060
  if (i < 0) {
26897
27061
  i = n.length;
@@ -27017,7 +27181,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
27017
27181
  identify: value => typeof value === 'boolean',
27018
27182
  default: true,
27019
27183
  tag: 'tag:yaml.org,2002:bool',
27020
- test: /^true|false$/,
27184
+ test: /^true$|^false$/,
27021
27185
  resolve: str => str === 'true',
27022
27186
  stringify: stringifyJSON
27023
27187
  },
@@ -27062,10 +27226,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
27062
27226
  * document.querySelector('#photo').src = URL.createObjectURL(blob)
27063
27227
  */
27064
27228
  resolve(src, onError) {
27065
- if (typeof Buffer === 'function') {
27066
- return Buffer.from(src, 'base64');
27067
- }
27068
- else if (typeof atob === 'function') {
27229
+ if (typeof atob === 'function') {
27069
27230
  // On IE 11, atob() can't handle newlines
27070
27231
  const str = atob(src.replace(/[\n\r]/g, ''));
27071
27232
  const buffer = new Uint8Array(str.length);
@@ -27079,15 +27240,11 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
27079
27240
  }
27080
27241
  },
27081
27242
  stringify({ comment, type, value }, ctx, onComment, onChompKeep) {
27243
+ if (!value)
27244
+ return '';
27082
27245
  const buf = value; // checked earlier by binary.identify()
27083
27246
  let str;
27084
- if (typeof Buffer === 'function') {
27085
- str =
27086
- buf instanceof Buffer
27087
- ? buf.toString('base64')
27088
- : Buffer.from(buf.buffer).toString('base64');
27089
- }
27090
- else if (typeof btoa === 'function') {
27247
+ if (typeof btoa === 'function') {
27091
27248
  let s = '';
27092
27249
  for (let i = 0; i < buf.length; ++i)
27093
27250
  s += String.fromCharCode(buf[i]);
@@ -27096,8 +27253,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
27096
27253
  else {
27097
27254
  throw new Error('This environment does not support writing binary tags; either Buffer or btoa is required');
27098
27255
  }
27099
- if (!type)
27100
- type = Scalar.BLOCK_LITERAL;
27256
+ type ?? (type = Scalar.BLOCK_LITERAL);
27101
27257
  if (type !== Scalar.QUOTE_DOUBLE) {
27102
27258
  const lineWidth = Math.max(ctx.options.lineWidth - ctx.indent.length, ctx.options.minContentWidth);
27103
27259
  const n = Math.ceil(str.length / lineWidth);
@@ -27566,7 +27722,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
27566
27722
  }
27567
27723
  return new Date(date);
27568
27724
  },
27569
- stringify: ({ value }) => value.toISOString().replace(/((T00:00)?:00)?\.000Z$/, '')
27725
+ stringify: ({ value }) => value?.toISOString().replace(/(T00:00:00)?\.000Z$/, '') ?? ''
27570
27726
  };
27571
27727
 
27572
27728
  const schema = [
@@ -27584,6 +27740,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
27584
27740
  floatExp,
27585
27741
  float,
27586
27742
  binary,
27743
+ merge,
27587
27744
  omap,
27588
27745
  pairs,
27589
27746
  set,
@@ -27611,6 +27768,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
27611
27768
  intOct: intOct$1,
27612
27769
  intTime,
27613
27770
  map,
27771
+ merge,
27614
27772
  null: nullTag,
27615
27773
  omap,
27616
27774
  pairs,
@@ -27620,13 +27778,20 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
27620
27778
  };
27621
27779
  const coreKnownTags = {
27622
27780
  'tag:yaml.org,2002:binary': binary,
27781
+ 'tag:yaml.org,2002:merge': merge,
27623
27782
  'tag:yaml.org,2002:omap': omap,
27624
27783
  'tag:yaml.org,2002:pairs': pairs,
27625
27784
  'tag:yaml.org,2002:set': set,
27626
27785
  'tag:yaml.org,2002:timestamp': timestamp
27627
27786
  };
27628
- function getTags(customTags, schemaName) {
27629
- let tags = schemas.get(schemaName);
27787
+ function getTags(customTags, schemaName, addMergeTag) {
27788
+ const schemaTags = schemas.get(schemaName);
27789
+ if (schemaTags && !customTags) {
27790
+ return addMergeTag && !schemaTags.includes(merge)
27791
+ ? schemaTags.concat(merge)
27792
+ : schemaTags.slice();
27793
+ }
27794
+ let tags = schemaTags;
27630
27795
  if (!tags) {
27631
27796
  if (Array.isArray(customTags))
27632
27797
  tags = [];
@@ -27645,17 +27810,21 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
27645
27810
  else if (typeof customTags === 'function') {
27646
27811
  tags = customTags(tags.slice());
27647
27812
  }
27648
- return tags.map(tag => {
27649
- if (typeof tag !== 'string')
27650
- return tag;
27651
- const tagObj = tagsByName[tag];
27652
- if (tagObj)
27653
- return tagObj;
27654
- const keys = Object.keys(tagsByName)
27655
- .map(key => JSON.stringify(key))
27656
- .join(', ');
27657
- throw new Error(`Unknown custom tag "${tag}"; use one of ${keys}`);
27658
- });
27813
+ if (addMergeTag)
27814
+ tags = tags.concat(merge);
27815
+ return tags.reduce((tags, tag) => {
27816
+ const tagObj = typeof tag === 'string' ? tagsByName[tag] : tag;
27817
+ if (!tagObj) {
27818
+ const tagName = JSON.stringify(tag);
27819
+ const keys = Object.keys(tagsByName)
27820
+ .map(key => JSON.stringify(key))
27821
+ .join(', ');
27822
+ throw new Error(`Unknown custom tag ${tagName}; use one of ${keys}`);
27823
+ }
27824
+ if (!tags.includes(tagObj))
27825
+ tags.push(tagObj);
27826
+ return tags;
27827
+ }, []);
27659
27828
  }
27660
27829
 
27661
27830
  const sortMapEntriesByKey = (a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0;
@@ -27666,10 +27835,9 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
27666
27835
  : compat
27667
27836
  ? getTags(null, compat)
27668
27837
  : null;
27669
- this.merge = !!merge;
27670
27838
  this.name = (typeof schema === 'string' && schema) || 'core';
27671
27839
  this.knownTags = resolveKnownTags ? coreKnownTags : {};
27672
- this.tags = getTags(customTags, this.name);
27840
+ this.tags = getTags(customTags, this.name, merge);
27673
27841
  this.toStringOptions = toStringDefaults ?? null;
27674
27842
  Object.defineProperty(this, MAP, { value: map });
27675
27843
  Object.defineProperty(this, SCALAR$1, { value: string });
@@ -27794,6 +27962,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
27794
27962
  logLevel: 'warn',
27795
27963
  prettyErrors: true,
27796
27964
  strict: true,
27965
+ stringKeys: false,
27797
27966
  uniqueKeys: true,
27798
27967
  version: '1.2'
27799
27968
  }, options);
@@ -28017,7 +28186,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
28017
28186
  this.directives.yaml.version = '1.1';
28018
28187
  else
28019
28188
  this.directives = new Directives({ version: '1.1' });
28020
- opt = { merge: true, resolveKnownTags: false, schema: 'yaml-1.1' };
28189
+ opt = { resolveKnownTags: false, schema: 'yaml-1.1' };
28021
28190
  break;
28022
28191
  case '1.2':
28023
28192
  case 'next':
@@ -28025,7 +28194,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
28025
28194
  this.directives.yaml.version = version;
28026
28195
  else
28027
28196
  this.directives = new Directives({ version });
28028
- opt = { merge: false, resolveKnownTags: true, schema: 'core' };
28197
+ opt = { resolveKnownTags: true, schema: 'core' };
28029
28198
  break;
28030
28199
  case null:
28031
28200
  if (this.directives)
@@ -28138,7 +28307,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
28138
28307
  if (/[^ ]/.test(lineStr)) {
28139
28308
  let count = 1;
28140
28309
  const end = error.linePos[1];
28141
- if (end && end.line === line && end.col > col) {
28310
+ if (end?.line === line && end.col > col) {
28142
28311
  count = Math.max(1, Math.min(end.col - col, 80 - ci));
28143
28312
  }
28144
28313
  const pointer = ' '.repeat(ci) + '^'.repeat(count);
@@ -28203,7 +28372,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
28203
28372
  if (atNewline) {
28204
28373
  if (comment)
28205
28374
  comment += token.source;
28206
- else
28375
+ else if (!found || indicator !== 'seq-item-ind')
28207
28376
  spaceBefore = true;
28208
28377
  }
28209
28378
  else
@@ -28220,8 +28389,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
28220
28389
  if (token.source.endsWith(':'))
28221
28390
  onError(token.offset + token.source.length - 1, 'BAD_ALIAS', 'Anchor ending in : is ambiguous', true);
28222
28391
  anchor = token;
28223
- if (start === null)
28224
- start = token.offset;
28392
+ start ?? (start = token.offset);
28225
28393
  atNewline = false;
28226
28394
  hasSpace = false;
28227
28395
  reqSpace = true;
@@ -28230,8 +28398,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
28230
28398
  if (tag)
28231
28399
  onError(token, 'MULTIPLE_TAGS', 'A node can have at most one tag');
28232
28400
  tag = token;
28233
- if (start === null)
28234
- start = token.offset;
28401
+ start ?? (start = token.offset);
28235
28402
  atNewline = false;
28236
28403
  hasSpace = false;
28237
28404
  reqSpace = true;
@@ -28344,11 +28511,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
28344
28511
  return false;
28345
28512
  const isEqual = typeof uniqueKeys === 'function'
28346
28513
  ? uniqueKeys
28347
- : (a, b) => a === b ||
28348
- (isScalar$1(a) &&
28349
- isScalar$1(b) &&
28350
- a.value === b.value &&
28351
- !(a.value === '<<' && ctx.schema.merge));
28514
+ : (a, b) => a === b || (isScalar$1(a) && isScalar$1(b) && a.value === b.value);
28352
28515
  return items.some(pair => isEqual(pair.key, search));
28353
28516
  }
28354
28517
 
@@ -28397,12 +28560,14 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
28397
28560
  onError(offset, 'BAD_INDENT', startColMsg);
28398
28561
  }
28399
28562
  // key value
28563
+ ctx.atKey = true;
28400
28564
  const keyStart = keyProps.end;
28401
28565
  const keyNode = key
28402
28566
  ? composeNode(ctx, key, keyProps, onError)
28403
28567
  : composeEmptyNode(ctx, keyStart, start, null, keyProps, onError);
28404
28568
  if (ctx.schema.compat)
28405
28569
  flowIndentCheck(bm.indent, key, onError);
28570
+ ctx.atKey = false;
28406
28571
  if (mapIncludes(ctx, map.items, keyNode))
28407
28572
  onError(keyStart, 'DUPLICATE_KEY', 'Map keys must be unique');
28408
28573
  // value properties
@@ -28462,6 +28627,8 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
28462
28627
  const seq = new NodeClass(ctx.schema);
28463
28628
  if (ctx.atRoot)
28464
28629
  ctx.atRoot = false;
28630
+ if (ctx.atKey)
28631
+ ctx.atKey = false;
28465
28632
  let offset = bs.offset;
28466
28633
  let commentEnd = null;
28467
28634
  for (const { start, value } of bs.items) {
@@ -28475,7 +28642,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
28475
28642
  });
28476
28643
  if (!props.found) {
28477
28644
  if (props.anchor || props.tag || value) {
28478
- if (value && value.type === 'block-seq')
28645
+ if (value?.type === 'block-seq')
28479
28646
  onError(props.end, 'BAD_INDENT', 'All sequence items must start at the same column');
28480
28647
  else
28481
28648
  onError(offset, 'MISSING_CHAR', 'Sequence item without - indicator');
@@ -28546,6 +28713,8 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
28546
28713
  const atRoot = ctx.atRoot;
28547
28714
  if (atRoot)
28548
28715
  ctx.atRoot = false;
28716
+ if (ctx.atKey)
28717
+ ctx.atKey = false;
28549
28718
  let offset = fc.offset + fc.start.source.length;
28550
28719
  for (let i = 0; i < fc.items.length; ++i) {
28551
28720
  const collItem = fc.items[i];
@@ -28625,12 +28794,14 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
28625
28794
  else {
28626
28795
  // item is a key+value pair
28627
28796
  // key value
28797
+ ctx.atKey = true;
28628
28798
  const keyStart = props.end;
28629
28799
  const keyNode = key
28630
28800
  ? composeNode(ctx, key, props, onError)
28631
28801
  : composeEmptyNode(ctx, keyStart, start, null, props, onError);
28632
28802
  if (isBlock(key))
28633
28803
  onError(keyNode.range, 'BLOCK_IN_FLOW', blockMsg);
28804
+ ctx.atKey = false;
28634
28805
  // value properties
28635
28806
  const valueProps = resolveProps(sep ?? [], {
28636
28807
  flow: fcName,
@@ -28657,7 +28828,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
28657
28828
  }
28658
28829
  }
28659
28830
  else if (value) {
28660
- if ('source' in value && value.source && value.source[0] === ':')
28831
+ if ('source' in value && value.source?.[0] === ':')
28661
28832
  onError(value, 'MISSING_CHAR', `Missing space after : in ${fcName}`);
28662
28833
  else
28663
28834
  onError(valueProps.start, 'MISSING_CHAR', `Missing , or : between ${fcName} items`);
@@ -28701,7 +28872,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
28701
28872
  const expectedEnd = isMap ? '}' : ']';
28702
28873
  const [ce, ...ee] = fc.end;
28703
28874
  let cePos = offset;
28704
- if (ce && ce.source === expectedEnd)
28875
+ if (ce?.source === expectedEnd)
28705
28876
  cePos = ce.offset + ce.source.length;
28706
28877
  else {
28707
28878
  const name = fcName[0].toUpperCase() + fcName.substring(1);
@@ -28781,13 +28952,13 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
28781
28952
  let tag = ctx.schema.tags.find(t => t.tag === tagName && t.collection === expType);
28782
28953
  if (!tag) {
28783
28954
  const kt = ctx.schema.knownTags[tagName];
28784
- if (kt && kt.collection === expType) {
28955
+ if (kt?.collection === expType) {
28785
28956
  ctx.schema.tags.push(Object.assign({}, kt, { default: false }));
28786
28957
  tag = kt;
28787
28958
  }
28788
28959
  else {
28789
- if (kt?.collection) {
28790
- onError(tagToken, 'BAD_COLLECTION_TYPE', `${kt.tag} used for ${expType} collection, but expects ${kt.collection}`, true);
28960
+ if (kt) {
28961
+ onError(tagToken, 'BAD_COLLECTION_TYPE', `${kt.tag} used for ${expType} collection, but expects ${kt.collection ?? 'scalar'}`, true);
28791
28962
  }
28792
28963
  else {
28793
28964
  onError(tagToken, 'TAG_RESOLVE_FAILED', `Unresolved tag: ${tagName}`, true);
@@ -29143,7 +29314,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
29143
29314
  next = source[++i + 1];
29144
29315
  }
29145
29316
  else if (next === 'x' || next === 'u' || next === 'U') {
29146
- const length = { x: 2, u: 4, U: 8 }[next];
29317
+ const length = next === 'x' ? 2 : next === 'u' ? 4 : 8;
29147
29318
  res += parseCharCode(source, i + 1, length, onError);
29148
29319
  i += length;
29149
29320
  }
@@ -29213,12 +29384,14 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
29213
29384
  const cc = source.substr(offset, length);
29214
29385
  const ok = cc.length === length && /^[0-9a-fA-F]+$/.test(cc);
29215
29386
  const code = ok ? parseInt(cc, 16) : NaN;
29216
- if (isNaN(code)) {
29387
+ try {
29388
+ return String.fromCodePoint(code);
29389
+ }
29390
+ catch {
29217
29391
  const raw = source.substr(offset - 2, length + 2);
29218
29392
  onError(offset - 2, 'BAD_DQ_ESCAPE', `Invalid escape sequence ${raw}`);
29219
29393
  return raw;
29220
29394
  }
29221
- return String.fromCodePoint(code);
29222
29395
  }
29223
29396
 
29224
29397
  function composeScalar(ctx, token, tagToken, onError) {
@@ -29228,11 +29401,16 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
29228
29401
  const tagName = tagToken
29229
29402
  ? ctx.directives.tagName(tagToken.source, msg => onError(tagToken, 'TAG_RESOLVE_FAILED', msg))
29230
29403
  : null;
29231
- const tag = tagToken && tagName
29232
- ? findScalarTagByName(ctx.schema, value, tagName, tagToken, onError)
29233
- : token.type === 'scalar'
29234
- ? findScalarTagByTest(ctx, value, token, onError)
29235
- : ctx.schema[SCALAR$1];
29404
+ let tag;
29405
+ if (ctx.options.stringKeys && ctx.atKey) {
29406
+ tag = ctx.schema[SCALAR$1];
29407
+ }
29408
+ else if (tagName)
29409
+ tag = findScalarTagByName(ctx.schema, value, tagName, tagToken, onError);
29410
+ else if (token.type === 'scalar')
29411
+ tag = findScalarTagByTest(ctx, value, token, onError);
29412
+ else
29413
+ tag = ctx.schema[SCALAR$1];
29236
29414
  let scalar;
29237
29415
  try {
29238
29416
  const res = tag.resolve(value, msg => onError(tagToken ?? token, 'TAG_RESOLVE_FAILED', msg), ctx.options);
@@ -29280,8 +29458,9 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
29280
29458
  onError(tagToken, 'TAG_RESOLVE_FAILED', `Unresolved tag: ${tagName}`, tagName !== 'tag:yaml.org,2002:str');
29281
29459
  return schema[SCALAR$1];
29282
29460
  }
29283
- function findScalarTagByTest({ directives, schema }, value, token, onError) {
29284
- const tag = schema.tags.find(tag => tag.default && tag.test?.test(value)) || schema[SCALAR$1];
29461
+ function findScalarTagByTest({ atKey, directives, schema }, value, token, onError) {
29462
+ const tag = schema.tags.find(tag => (tag.default === true || (atKey && tag.default === 'key')) &&
29463
+ tag.test?.test(value)) || schema[SCALAR$1];
29285
29464
  if (schema.compat) {
29286
29465
  const compat = schema.compat.find(tag => tag.default && tag.test?.test(value)) ??
29287
29466
  schema[SCALAR$1];
@@ -29297,8 +29476,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
29297
29476
 
29298
29477
  function emptyScalarPosition(offset, before, pos) {
29299
29478
  if (before) {
29300
- if (pos === null)
29301
- pos = before.length;
29479
+ pos ?? (pos = before.length);
29302
29480
  for (let i = pos - 1; i >= 0; --i) {
29303
29481
  let st = before[i];
29304
29482
  switch (st.type) {
@@ -29323,6 +29501,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
29323
29501
 
29324
29502
  const CN = { composeNode, composeEmptyNode };
29325
29503
  function composeNode(ctx, token, props, onError) {
29504
+ const atKey = ctx.atKey;
29326
29505
  const { spaceBefore, comment, anchor, tag } = props;
29327
29506
  let node;
29328
29507
  let isSrcToken = true;
@@ -29343,21 +29522,36 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
29343
29522
  case 'block-map':
29344
29523
  case 'block-seq':
29345
29524
  case 'flow-collection':
29346
- node = composeCollection(CN, ctx, token, props, onError);
29347
- if (anchor)
29348
- node.anchor = anchor.source.substring(1);
29525
+ try {
29526
+ node = composeCollection(CN, ctx, token, props, onError);
29527
+ if (anchor)
29528
+ node.anchor = anchor.source.substring(1);
29529
+ }
29530
+ catch (error) {
29531
+ // Almost certainly here due to a stack overflow
29532
+ const message = error instanceof Error ? error.message : String(error);
29533
+ onError(token, 'RESOURCE_EXHAUSTION', message);
29534
+ }
29349
29535
  break;
29350
29536
  default: {
29351
29537
  const message = token.type === 'error'
29352
29538
  ? token.message
29353
29539
  : `Unsupported token (type: ${token.type})`;
29354
29540
  onError(token, 'UNEXPECTED_TOKEN', message);
29355
- node = composeEmptyNode(ctx, token.offset, undefined, null, props, onError);
29356
29541
  isSrcToken = false;
29357
29542
  }
29358
29543
  }
29544
+ node ?? (node = composeEmptyNode(ctx, token.offset, undefined, null, props, onError));
29359
29545
  if (anchor && node.anchor === '')
29360
29546
  onError(anchor, 'BAD_ALIAS', 'Anchor cannot be an empty string');
29547
+ if (atKey &&
29548
+ ctx.options.stringKeys &&
29549
+ (!isScalar$1(node) ||
29550
+ typeof node.value !== 'string' ||
29551
+ (node.tag && node.tag !== 'tag:yaml.org,2002:str'))) {
29552
+ const msg = 'With stringKeys, all keys must be strings';
29553
+ onError(tag ?? token, 'NON_STRING_KEY', msg);
29554
+ }
29361
29555
  if (spaceBefore)
29362
29556
  node.spaceBefore = true;
29363
29557
  if (comment) {
@@ -29410,6 +29604,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
29410
29604
  const opts = Object.assign({ _directives: directives }, options);
29411
29605
  const doc = new Document(undefined, opts);
29412
29606
  const ctx = {
29607
+ atKey: false,
29413
29608
  atRoot: true,
29414
29609
  directives: doc.directives,
29415
29610
  options: doc.options,
@@ -29531,8 +29726,10 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
29531
29726
  }
29532
29727
  }
29533
29728
  if (afterDoc) {
29534
- Array.prototype.push.apply(doc.errors, this.errors);
29535
- Array.prototype.push.apply(doc.warnings, this.warnings);
29729
+ for (let i = 0; i < this.errors.length; ++i)
29730
+ doc.errors.push(this.errors[i]);
29731
+ for (let i = 0; i < this.warnings.length; ++i)
29732
+ doc.warnings.push(this.warnings[i]);
29536
29733
  }
29537
29734
  else {
29538
29735
  doc.errors = this.errors;
@@ -30435,7 +30632,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
30435
30632
  const n = (yield* this.pushCount(1)) + (yield* this.pushSpaces(true));
30436
30633
  this.indentNext = this.indentValue + 1;
30437
30634
  this.indentValue += n;
30438
- return yield* this.parseBlockStart();
30635
+ return 'block-start';
30439
30636
  }
30440
30637
  return 'doc';
30441
30638
  }
@@ -30756,32 +30953,36 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
30756
30953
  return 0;
30757
30954
  }
30758
30955
  *pushIndicators() {
30759
- switch (this.charAt(0)) {
30760
- case '!':
30761
- return ((yield* this.pushTag()) +
30762
- (yield* this.pushSpaces(true)) +
30763
- (yield* this.pushIndicators()));
30764
- case '&':
30765
- return ((yield* this.pushUntil(isNotAnchorChar)) +
30766
- (yield* this.pushSpaces(true)) +
30767
- (yield* this.pushIndicators()));
30768
- case '-': // this is an error
30769
- case '?': // this is an error outside flow collections
30770
- case ':': {
30771
- const inFlow = this.flowLevel > 0;
30772
- const ch1 = this.charAt(1);
30773
- if (isEmpty(ch1) || (inFlow && flowIndicatorChars.has(ch1))) {
30774
- if (!inFlow)
30775
- this.indentNext = this.indentValue + 1;
30776
- else if (this.flowKey)
30777
- this.flowKey = false;
30778
- return ((yield* this.pushCount(1)) +
30779
- (yield* this.pushSpaces(true)) +
30780
- (yield* this.pushIndicators()));
30956
+ let n = 0;
30957
+ loop: while (true) {
30958
+ switch (this.charAt(0)) {
30959
+ case '!':
30960
+ n += yield* this.pushTag();
30961
+ n += yield* this.pushSpaces(true);
30962
+ continue loop;
30963
+ case '&':
30964
+ n += yield* this.pushUntil(isNotAnchorChar);
30965
+ n += yield* this.pushSpaces(true);
30966
+ continue loop;
30967
+ case '-': // this is an error
30968
+ case '?': // this is an error outside flow collections
30969
+ case ':': {
30970
+ const inFlow = this.flowLevel > 0;
30971
+ const ch1 = this.charAt(1);
30972
+ if (isEmpty(ch1) || (inFlow && flowIndicatorChars.has(ch1))) {
30973
+ if (!inFlow)
30974
+ this.indentNext = this.indentValue + 1;
30975
+ else if (this.flowKey)
30976
+ this.flowKey = false;
30977
+ n += yield* this.pushCount(1);
30978
+ n += yield* this.pushSpaces(true);
30979
+ continue loop;
30980
+ }
30781
30981
  }
30782
30982
  }
30983
+ break loop;
30783
30984
  }
30784
- return 0;
30985
+ return n;
30785
30986
  }
30786
30987
  *pushTag() {
30787
30988
  if (this.charAt(1) === '<') {
@@ -30943,6 +31144,14 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
30943
31144
  }
30944
31145
  return prev.splice(i, prev.length);
30945
31146
  }
31147
+ function arrayPushArray(target, source) {
31148
+ // May exhaust call stack with large `source` array
31149
+ if (source.length < 1e5)
31150
+ Array.prototype.push.apply(target, source);
31151
+ else
31152
+ for (let i = 0; i < source.length; ++i)
31153
+ target.push(source[i]);
31154
+ }
30946
31155
  function fixFlowSeqItems(fc) {
30947
31156
  if (fc.start.type === 'flow-seq-start') {
30948
31157
  for (const it of fc.items) {
@@ -30955,12 +31164,12 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
30955
31164
  delete it.key;
30956
31165
  if (isFlowToken(it.value)) {
30957
31166
  if (it.value.end)
30958
- Array.prototype.push.apply(it.value.end, it.sep);
31167
+ arrayPushArray(it.value.end, it.sep);
30959
31168
  else
30960
31169
  it.value.end = it.sep;
30961
31170
  }
30962
31171
  else
30963
- Array.prototype.push.apply(it.start, it.sep);
31172
+ arrayPushArray(it.start, it.sep);
30964
31173
  delete it.sep;
30965
31174
  }
30966
31175
  }
@@ -31102,7 +31311,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
31102
31311
  }
31103
31312
  *step() {
31104
31313
  const top = this.peek(1);
31105
- if (this.type === 'doc-end' && (!top || top.type !== 'doc-end')) {
31314
+ if (this.type === 'doc-end' && top?.type !== 'doc-end') {
31106
31315
  while (this.stack.length > 0)
31107
31316
  yield* this.pop();
31108
31317
  this.stack.push({
@@ -31378,7 +31587,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
31378
31587
  const prev = map.items[map.items.length - 2];
31379
31588
  const end = prev?.value?.end;
31380
31589
  if (Array.isArray(end)) {
31381
- Array.prototype.push.apply(end, it.start);
31590
+ arrayPushArray(end, it.start);
31382
31591
  end.push(this.sourceToken);
31383
31592
  map.items.pop();
31384
31593
  return;
@@ -31544,7 +31753,20 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
31544
31753
  default: {
31545
31754
  const bv = this.startBlockValue(map);
31546
31755
  if (bv) {
31547
- if (atMapIndent && bv.type !== 'block-seq') {
31756
+ if (bv.type === 'block-seq') {
31757
+ if (!it.explicitKey &&
31758
+ it.sep &&
31759
+ !includesToken(it.sep, 'newline')) {
31760
+ yield* this.pop({
31761
+ type: 'error',
31762
+ offset: this.offset,
31763
+ message: 'Unexpected block-seq-ind on same line with key',
31764
+ source: this.source
31765
+ });
31766
+ return;
31767
+ }
31768
+ }
31769
+ else if (atMapIndent) {
31548
31770
  map.items.push({ start });
31549
31771
  }
31550
31772
  this.stack.push(bv);
@@ -31580,7 +31802,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
31580
31802
  const prev = seq.items[seq.items.length - 2];
31581
31803
  const end = prev?.value?.end;
31582
31804
  if (Array.isArray(end)) {
31583
- Array.prototype.push.apply(end, it.start);
31805
+ arrayPushArray(end, it.start);
31584
31806
  end.push(this.sourceToken);
31585
31807
  seq.items.pop();
31586
31808
  return;
@@ -31621,7 +31843,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
31621
31843
  do {
31622
31844
  yield* this.pop();
31623
31845
  top = this.peek(1);
31624
- } while (top && top.type === 'flow-collection');
31846
+ } while (top?.type === 'flow-collection');
31625
31847
  }
31626
31848
  else if (fc.end.length === 0) {
31627
31849
  switch (this.type) {
@@ -31915,6 +32137,8 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
31915
32137
  if (!keepUndefined)
31916
32138
  return undefined;
31917
32139
  }
32140
+ if (isDocument(value) && !_replacer)
32141
+ return value.toString(options);
31918
32142
  return new Document(value, _replacer, options).toString(options);
31919
32143
  }
31920
32144