yaml 2.0.0-4 → 2.0.0-8

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 (220) hide show
  1. package/README.md +5 -5
  2. package/browser/dist/compose/compose-collection.js +12 -9
  3. package/browser/dist/compose/compose-doc.js +23 -6
  4. package/browser/dist/compose/compose-node.js +27 -17
  5. package/browser/dist/compose/compose-scalar.js +21 -23
  6. package/browser/dist/compose/composer.js +108 -78
  7. package/browser/dist/compose/resolve-block-map.js +41 -29
  8. package/browser/dist/compose/resolve-block-scalar.js +14 -17
  9. package/browser/dist/compose/resolve-block-seq.js +21 -17
  10. package/browser/dist/compose/resolve-end.js +7 -8
  11. package/browser/dist/compose/resolve-flow-collection.js +158 -199
  12. package/browser/dist/compose/resolve-flow-scalar.js +62 -26
  13. package/browser/dist/compose/resolve-props.js +72 -37
  14. package/browser/dist/compose/util-contains-newline.js +15 -12
  15. package/browser/dist/compose/util-map-includes.js +17 -0
  16. package/browser/dist/doc/Document.js +74 -99
  17. package/browser/dist/doc/anchors.js +72 -0
  18. package/browser/dist/doc/createNode.js +35 -19
  19. package/browser/dist/doc/directives.js +5 -0
  20. package/browser/dist/errors.js +16 -12
  21. package/browser/dist/index.js +3 -3
  22. package/browser/dist/nodes/Alias.js +51 -28
  23. package/browser/dist/nodes/Collection.js +23 -92
  24. package/browser/dist/nodes/Node.js +9 -1
  25. package/browser/dist/nodes/Pair.js +16 -231
  26. package/browser/dist/nodes/YAMLMap.js +8 -4
  27. package/browser/dist/nodes/YAMLSeq.js +7 -4
  28. package/browser/dist/nodes/addPairToJSMap.js +103 -0
  29. package/browser/dist/nodes/toJS.js +12 -10
  30. package/browser/dist/options.js +1 -2
  31. package/browser/dist/parse/cst-scalar.js +219 -0
  32. package/browser/dist/parse/cst-stringify.js +61 -0
  33. package/browser/dist/parse/cst-visit.js +97 -0
  34. package/{dist/parse/tokens.js → browser/dist/parse/cst.js} +12 -7
  35. package/browser/dist/parse/lexer.js +149 -125
  36. package/browser/dist/parse/parser.js +272 -196
  37. package/browser/dist/public-api.js +11 -14
  38. package/browser/dist/schema/Schema.js +28 -0
  39. package/browser/dist/{tags/failsafe → schema/common}/map.js +0 -0
  40. package/browser/dist/schema/common/null.js +13 -0
  41. package/browser/dist/{tags/failsafe → schema/common}/seq.js +1 -1
  42. package/browser/dist/{tags/failsafe → schema/common}/string.js +0 -0
  43. package/browser/dist/schema/core/bool.js +19 -0
  44. package/browser/dist/schema/core/float.js +40 -0
  45. package/browser/dist/schema/core/int.js +38 -0
  46. package/browser/dist/schema/core/schema.js +23 -0
  47. package/browser/dist/{tags/json.js → schema/json/schema.js} +5 -6
  48. package/browser/dist/schema/tags.js +79 -0
  49. package/browser/dist/{tags → schema}/yaml-1.1/binary.js +0 -0
  50. package/browser/dist/schema/yaml-1.1/bool.js +26 -0
  51. package/browser/dist/schema/yaml-1.1/float.js +43 -0
  52. package/browser/dist/schema/yaml-1.1/int.js +71 -0
  53. package/browser/dist/{tags → schema}/yaml-1.1/omap.js +0 -0
  54. package/browser/dist/{tags → schema}/yaml-1.1/pairs.js +9 -6
  55. package/browser/dist/schema/yaml-1.1/schema.js +37 -0
  56. package/browser/dist/{tags → schema}/yaml-1.1/set.js +0 -0
  57. package/browser/dist/{tags → schema}/yaml-1.1/timestamp.js +0 -0
  58. package/browser/dist/stringify/stringify.js +8 -6
  59. package/browser/dist/stringify/stringifyCollection.js +122 -0
  60. package/browser/dist/stringify/stringifyComment.js +14 -0
  61. package/browser/dist/stringify/stringifyDocument.js +64 -0
  62. package/browser/dist/stringify/stringifyPair.js +111 -0
  63. package/browser/dist/stringify/stringifyString.js +53 -52
  64. package/browser/dist/visit.js +20 -1
  65. package/dist/compose/compose-collection.d.ts +4 -4
  66. package/dist/compose/compose-collection.js +12 -9
  67. package/dist/compose/compose-doc.d.ts +4 -3
  68. package/dist/compose/compose-doc.js +23 -6
  69. package/dist/compose/compose-node.d.ts +15 -7
  70. package/dist/compose/compose-node.js +27 -17
  71. package/dist/compose/compose-scalar.d.ts +4 -3
  72. package/dist/compose/compose-scalar.js +20 -22
  73. package/dist/compose/composer.d.ts +28 -23
  74. package/dist/compose/composer.js +109 -79
  75. package/dist/compose/resolve-block-map.d.ts +5 -4
  76. package/dist/compose/resolve-block-map.js +41 -29
  77. package/dist/compose/resolve-block-scalar.d.ts +5 -3
  78. package/dist/compose/resolve-block-scalar.js +14 -17
  79. package/dist/compose/resolve-block-seq.d.ts +4 -4
  80. package/dist/compose/resolve-block-seq.js +21 -17
  81. package/dist/compose/resolve-end.d.ts +3 -2
  82. package/dist/compose/resolve-end.js +7 -8
  83. package/dist/compose/resolve-flow-collection.d.ts +4 -5
  84. package/dist/compose/resolve-flow-collection.js +157 -198
  85. package/dist/compose/resolve-flow-scalar.d.ts +5 -3
  86. package/dist/compose/resolve-flow-scalar.js +62 -26
  87. package/dist/compose/resolve-props.d.ts +16 -10
  88. package/dist/compose/resolve-props.js +72 -37
  89. package/dist/compose/util-contains-newline.d.ts +1 -1
  90. package/dist/compose/util-contains-newline.js +15 -12
  91. package/dist/compose/util-empty-scalar-position.d.ts +1 -1
  92. package/dist/compose/util-map-includes.d.ts +4 -0
  93. package/dist/compose/util-map-includes.js +19 -0
  94. package/dist/doc/Document.d.ts +35 -15
  95. package/dist/doc/Document.js +72 -97
  96. package/dist/doc/anchors.d.ts +24 -0
  97. package/dist/doc/anchors.js +77 -0
  98. package/dist/doc/createNode.d.ts +10 -11
  99. package/dist/doc/createNode.js +34 -18
  100. package/dist/doc/directives.d.ts +1 -0
  101. package/dist/doc/directives.js +5 -0
  102. package/dist/errors.d.ts +11 -8
  103. package/dist/errors.js +16 -12
  104. package/dist/index.d.ts +5 -3
  105. package/dist/index.js +3 -3
  106. package/dist/nodes/Alias.d.ts +19 -9
  107. package/dist/nodes/Alias.js +51 -28
  108. package/dist/nodes/Collection.d.ts +9 -17
  109. package/dist/nodes/Collection.js +22 -91
  110. package/dist/nodes/Node.d.ts +10 -4
  111. package/dist/nodes/Node.js +9 -0
  112. package/dist/nodes/Pair.d.ts +10 -13
  113. package/dist/nodes/Pair.js +15 -230
  114. package/dist/nodes/Scalar.d.ts +6 -3
  115. package/dist/nodes/YAMLMap.d.ts +3 -3
  116. package/dist/nodes/YAMLMap.js +8 -4
  117. package/dist/nodes/YAMLSeq.d.ts +3 -3
  118. package/dist/nodes/YAMLSeq.js +7 -4
  119. package/dist/nodes/addPairToJSMap.d.ts +3 -0
  120. package/dist/nodes/addPairToJSMap.js +105 -0
  121. package/dist/nodes/toJS.d.ts +4 -5
  122. package/dist/nodes/toJS.js +12 -10
  123. package/dist/options.d.ts +41 -25
  124. package/dist/options.js +1 -2
  125. package/dist/parse/cst-scalar.d.ts +58 -0
  126. package/dist/parse/cst-scalar.js +223 -0
  127. package/dist/parse/cst-stringify.d.ts +8 -0
  128. package/dist/parse/cst-stringify.js +63 -0
  129. package/dist/parse/cst-visit.d.ts +39 -0
  130. package/dist/parse/cst-visit.js +99 -0
  131. package/dist/parse/{tokens.d.ts → cst.d.ts} +23 -7
  132. package/{browser/dist/parse/tokens.js → dist/parse/cst.js} +27 -1
  133. package/dist/parse/lexer.d.ts +7 -14
  134. package/dist/parse/lexer.js +150 -126
  135. package/dist/parse/parser.d.ts +31 -24
  136. package/dist/parse/parser.js +274 -198
  137. package/dist/public-api.d.ts +7 -7
  138. package/dist/public-api.js +11 -14
  139. package/dist/{doc → schema}/Schema.d.ts +6 -3
  140. package/dist/schema/Schema.js +30 -0
  141. package/dist/{tags/failsafe → schema/common}/map.d.ts +0 -0
  142. package/dist/{tags/failsafe → schema/common}/map.js +0 -0
  143. package/dist/schema/common/null.d.ts +4 -0
  144. package/dist/schema/common/null.js +15 -0
  145. package/dist/{tags/failsafe → schema/common}/seq.d.ts +0 -0
  146. package/dist/{tags/failsafe → schema/common}/seq.js +1 -1
  147. package/dist/{tags/failsafe → schema/common}/string.d.ts +0 -0
  148. package/dist/{tags/failsafe → schema/common}/string.js +0 -0
  149. package/dist/schema/core/bool.d.ts +4 -0
  150. package/dist/schema/core/bool.js +21 -0
  151. package/dist/schema/core/float.d.ts +4 -0
  152. package/dist/schema/core/float.js +44 -0
  153. package/dist/schema/core/int.d.ts +4 -0
  154. package/dist/schema/core/int.js +42 -0
  155. package/dist/schema/core/schema.d.ts +1 -0
  156. package/dist/schema/core/schema.js +25 -0
  157. package/dist/schema/json/schema.d.ts +2 -0
  158. package/dist/{tags/json.js → schema/json/schema.js} +5 -6
  159. package/dist/schema/tags.d.ts +41 -0
  160. package/dist/schema/tags.js +82 -0
  161. package/dist/{tags → schema}/types.d.ts +3 -7
  162. package/dist/{tags → schema}/yaml-1.1/binary.d.ts +0 -0
  163. package/dist/{tags → schema}/yaml-1.1/binary.js +0 -0
  164. package/dist/schema/yaml-1.1/bool.d.ts +7 -0
  165. package/dist/schema/yaml-1.1/bool.js +29 -0
  166. package/dist/schema/yaml-1.1/float.d.ts +4 -0
  167. package/dist/schema/yaml-1.1/float.js +47 -0
  168. package/dist/schema/yaml-1.1/int.d.ts +5 -0
  169. package/dist/schema/yaml-1.1/int.js +76 -0
  170. package/dist/{tags → schema}/yaml-1.1/omap.d.ts +0 -0
  171. package/dist/{tags → schema}/yaml-1.1/omap.js +0 -0
  172. package/dist/{tags → schema}/yaml-1.1/pairs.d.ts +3 -2
  173. package/dist/{tags → schema}/yaml-1.1/pairs.js +9 -6
  174. package/dist/schema/yaml-1.1/schema.d.ts +1 -0
  175. package/dist/schema/yaml-1.1/schema.js +39 -0
  176. package/dist/{tags → schema}/yaml-1.1/set.d.ts +1 -1
  177. package/dist/{tags → schema}/yaml-1.1/set.js +0 -0
  178. package/dist/{tags → schema}/yaml-1.1/timestamp.d.ts +0 -0
  179. package/dist/{tags → schema}/yaml-1.1/timestamp.js +0 -0
  180. package/dist/stringify/stringify.d.ts +1 -2
  181. package/dist/stringify/stringify.js +8 -6
  182. package/dist/stringify/stringifyCollection.d.ts +21 -0
  183. package/dist/stringify/stringifyCollection.js +124 -0
  184. package/dist/stringify/stringifyComment.d.ts +2 -0
  185. package/dist/stringify/stringifyComment.js +17 -0
  186. package/dist/stringify/stringifyDocument.d.ts +3 -0
  187. package/dist/stringify/stringifyDocument.js +66 -0
  188. package/dist/stringify/stringifyPair.d.ts +3 -0
  189. package/dist/stringify/stringifyPair.js +113 -0
  190. package/dist/stringify/stringifyString.js +53 -52
  191. package/dist/test-events.d.ts +1 -2
  192. package/dist/test-events.js +25 -12
  193. package/dist/util.d.ts +1 -1
  194. package/dist/visit.d.ts +10 -1
  195. package/dist/visit.js +20 -1
  196. package/package.json +9 -8
  197. package/browser/dist/doc/Anchors.js +0 -102
  198. package/browser/dist/doc/Schema.js +0 -27
  199. package/browser/dist/doc/getSchemaTags.js +0 -30
  200. package/browser/dist/stringify/addComment.js +0 -17
  201. package/browser/dist/tags/core.js +0 -109
  202. package/browser/dist/tags/failsafe/index.js +0 -7
  203. package/browser/dist/tags/index.js +0 -34
  204. package/browser/dist/tags/yaml-1.1/index.js +0 -152
  205. package/dist/doc/Anchors.d.ts +0 -36
  206. package/dist/doc/Anchors.js +0 -104
  207. package/dist/doc/Schema.js +0 -29
  208. package/dist/doc/getSchemaTags.d.ts +0 -3
  209. package/dist/doc/getSchemaTags.js +0 -32
  210. package/dist/stringify/addComment.d.ts +0 -2
  211. package/dist/stringify/addComment.js +0 -20
  212. package/dist/tags/core.d.ts +0 -14
  213. package/dist/tags/core.js +0 -119
  214. package/dist/tags/failsafe/index.d.ts +0 -1
  215. package/dist/tags/failsafe/index.js +0 -9
  216. package/dist/tags/index.d.ts +0 -31
  217. package/dist/tags/index.js +0 -37
  218. package/dist/tags/json.d.ts +0 -2
  219. package/dist/tags/yaml-1.1/index.d.ts +0 -2
  220. package/dist/tags/yaml-1.1/index.js +0 -154
@@ -3,10 +3,11 @@
3
3
  var Scalar = require('../nodes/Scalar.js');
4
4
  var resolveEnd = require('./resolve-end.js');
5
5
 
6
- function resolveFlowScalar({ offset, type, source, end }, strict, onError) {
6
+ function resolveFlowScalar(scalar, strict, onError) {
7
+ const { offset, type, source, end } = scalar;
7
8
  let _type;
8
9
  let value;
9
- const _onError = (rel, msg) => onError(offset + rel, msg);
10
+ const _onError = (rel, code, msg) => onError(offset + rel, code, msg);
10
11
  switch (type) {
11
12
  case 'scalar':
12
13
  _type = Scalar.Scalar.PLAIN;
@@ -22,68 +23,97 @@ function resolveFlowScalar({ offset, type, source, end }, strict, onError) {
22
23
  break;
23
24
  /* istanbul ignore next should not happen */
24
25
  default:
25
- onError(offset, `Expected a flow scalar value, but found: ${type}`);
26
+ onError(scalar, 'UNEXPECTED_TOKEN', `Expected a flow scalar value, but found: ${type}`);
26
27
  return {
27
28
  value: '',
28
29
  type: null,
29
30
  comment: '',
30
- length: source.length
31
+ range: [offset, offset + source.length, offset + source.length]
31
32
  };
32
33
  }
33
- const re = resolveEnd.resolveEnd(end, 0, strict, _onError);
34
+ const valueEnd = offset + source.length;
35
+ const re = resolveEnd.resolveEnd(end, valueEnd, strict, onError);
34
36
  return {
35
37
  value,
36
38
  type: _type,
37
39
  comment: re.comment,
38
- length: source.length + re.offset
40
+ range: [offset, valueEnd, re.offset]
39
41
  };
40
42
  }
41
43
  function plainValue(source, onError) {
44
+ let badChar = '';
42
45
  switch (source[0]) {
43
46
  /* istanbul ignore next should not happen */
44
47
  case '\t':
45
- onError(0, 'Plain value cannot start with a tab character');
48
+ badChar = 'a tab character';
49
+ break;
50
+ case ',':
51
+ badChar = 'flow indicator character ,';
52
+ break;
53
+ case '%':
54
+ badChar = 'directive indicator character %';
46
55
  break;
47
56
  case '|':
48
57
  case '>': {
49
- const message = `Plain value cannot start with block scalar indicator ${source[0]}`;
50
- onError(0, message);
58
+ badChar = `block scalar indicator ${source[0]}`;
51
59
  break;
52
60
  }
53
61
  case '@':
54
62
  case '`': {
55
- const message = `Plain value cannot start with reserved character ${source[0]}`;
56
- onError(0, message);
63
+ badChar = `reserved character ${source[0]}`;
57
64
  break;
58
65
  }
59
66
  }
60
- return foldLines(source.trim());
67
+ if (badChar)
68
+ onError(0, 'BAD_SCALAR_START', `Plain value cannot start with ${badChar}`);
69
+ return foldLines(source);
61
70
  }
62
71
  function singleQuotedValue(source, onError) {
63
72
  if (source[source.length - 1] !== "'" || source.length === 1)
64
- onError(source.length, "Missing closing 'quote");
73
+ onError(source.length, 'MISSING_CHAR', "Missing closing 'quote");
65
74
  return foldLines(source.slice(1, -1)).replace(/''/g, "'");
66
75
  }
67
76
  function foldLines(source) {
68
- const lines = source.split(/[ \t]*\r?\n[ \t]*/);
69
- let res = lines[0];
77
+ /**
78
+ * The negative lookbehind here and in the `re` RegExp is to
79
+ * prevent causing a polynomial search time in certain cases.
80
+ *
81
+ * The try-catch is for Safari, which doesn't support this yet:
82
+ * https://caniuse.com/js-regexp-lookbehind
83
+ */
84
+ let first, line;
85
+ try {
86
+ first = new RegExp('(.*?)(?<![ \t])[ \t]*\r?\n', 'sy');
87
+ line = new RegExp('[ \t]*(.*?)(?:(?<![ \t])[ \t]*)?\r?\n', 'sy');
88
+ }
89
+ catch (_) {
90
+ first = /(.*?)[ \t]*\r?\n/sy;
91
+ line = /[ \t]*(.*?)[ \t]*\r?\n/sy;
92
+ }
93
+ let match = first.exec(source);
94
+ if (!match)
95
+ return source;
96
+ let res = match[1];
70
97
  let sep = ' ';
71
- for (let i = 1; i < lines.length - 1; ++i) {
72
- const line = lines[i];
73
- if (line === '') {
98
+ let pos = first.lastIndex;
99
+ line.lastIndex = pos;
100
+ while ((match = line.exec(source))) {
101
+ if (match[1] === '') {
74
102
  if (sep === '\n')
75
103
  res += sep;
76
104
  else
77
105
  sep = '\n';
78
106
  }
79
107
  else {
80
- res += sep + line;
108
+ res += sep + match[1];
81
109
  sep = ' ';
82
110
  }
111
+ pos = line.lastIndex;
83
112
  }
84
- if (lines.length > 1)
85
- res += sep + lines[lines.length - 1];
86
- return res;
113
+ const last = /[ \t]*(.*)/sy;
114
+ last.lastIndex = pos;
115
+ match = last.exec(source);
116
+ return res + sep + ((match && match[1]) || '');
87
117
  }
88
118
  function doubleQuotedValue(source, onError) {
89
119
  let res = '';
@@ -107,6 +137,12 @@ function doubleQuotedValue(source, onError) {
107
137
  while (next === ' ' || next === '\t')
108
138
  next = source[++i + 1];
109
139
  }
140
+ else if (next === '\r' && source[i + 1] === '\n') {
141
+ // skip escaped CRLF newlines, but still trim the following line
142
+ next = source[++i + 1];
143
+ while (next === ' ' || next === '\t')
144
+ next = source[++i + 1];
145
+ }
110
146
  else if (next === 'x' || next === 'u' || next === 'U') {
111
147
  const length = { x: 2, u: 4, U: 8 }[next];
112
148
  res += parseCharCode(source, i + 1, length, onError);
@@ -114,7 +150,7 @@ function doubleQuotedValue(source, onError) {
114
150
  }
115
151
  else {
116
152
  const raw = source.substr(i - 1, 2);
117
- onError(i - 1, `Invalid escape sequence ${raw}`);
153
+ onError(i - 1, 'BAD_DQ_ESCAPE', `Invalid escape sequence ${raw}`);
118
154
  res += raw;
119
155
  }
120
156
  }
@@ -124,7 +160,7 @@ function doubleQuotedValue(source, onError) {
124
160
  let next = source[i + 1];
125
161
  while (next === ' ' || next === '\t')
126
162
  next = source[++i + 1];
127
- if (next !== '\n')
163
+ if (next !== '\n' && !(next === '\r' && source[i + 2] === '\n'))
128
164
  res += i > wsStart ? source.slice(wsStart, i + 1) : ch;
129
165
  }
130
166
  else {
@@ -132,7 +168,7 @@ function doubleQuotedValue(source, onError) {
132
168
  }
133
169
  }
134
170
  if (source[source.length - 1] !== '"' || source.length === 1)
135
- onError(source.length, 'Missing closing "quote');
171
+ onError(source.length, 'MISSING_CHAR', 'Missing closing "quote');
136
172
  return res;
137
173
  }
138
174
  /**
@@ -180,7 +216,7 @@ function parseCharCode(source, offset, length, onError) {
180
216
  const code = ok ? parseInt(cc, 16) : NaN;
181
217
  if (isNaN(code)) {
182
218
  const raw = source.substr(offset - 2, length + 2);
183
- onError(offset - 2, `Invalid escape sequence ${raw}`);
219
+ onError(offset - 2, 'BAD_DQ_ESCAPE', `Invalid escape sequence ${raw}`);
184
220
  return raw;
185
221
  }
186
222
  return String.fromCodePoint(code);
@@ -1,15 +1,21 @@
1
- import type { Document } from '../doc/Document.js';
2
- import type { SourceToken } from '../parse/tokens.js';
3
- export declare function resolveProps(doc: Document.Parsed, tokens: SourceToken[], startOnNewline: boolean, indicator: 'doc-start' | 'explicit-key-ind' | 'map-value-ind' | 'seq-item-ind', offset: number, onError: (offset: number, message: string) => void): {
4
- found: {
5
- indent: number;
6
- offset: number;
7
- } | null;
1
+ import type { SourceToken, Token } from '../parse/cst.js';
2
+ import type { ComposeErrorHandler } from './composer.js';
3
+ export interface ResolvePropsArg {
4
+ flow?: string;
5
+ indicator: 'doc-start' | 'explicit-key-ind' | 'map-value-ind' | 'seq-item-ind';
6
+ next: Token | null | undefined;
7
+ offset: number;
8
+ onError: ComposeErrorHandler;
9
+ startOnNewline: boolean;
10
+ }
11
+ export declare function resolveProps(tokens: SourceToken[], { flow, indicator, next, offset, onError, startOnNewline }: ResolvePropsArg): {
12
+ comma: SourceToken | null;
13
+ found: SourceToken | null;
8
14
  spaceBefore: boolean;
9
15
  comment: string;
10
16
  hasNewline: boolean;
11
- anchor: string;
12
- tagName: string;
13
- length: number;
17
+ anchor: SourceToken | null;
18
+ tag: SourceToken | null;
19
+ end: number;
14
20
  start: number;
15
21
  };
@@ -1,92 +1,127 @@
1
1
  'use strict';
2
2
 
3
- function resolveProps(doc, tokens, startOnNewline, indicator, offset, onError) {
4
- let length = 0;
3
+ function resolveProps(tokens, { flow, indicator, next, offset, onError, startOnNewline }) {
5
4
  let spaceBefore = false;
6
5
  let atNewline = startOnNewline;
7
6
  let hasSpace = startOnNewline;
8
7
  let comment = '';
9
- let hasComment = false;
8
+ let commentSep = '';
10
9
  let hasNewline = false;
11
- let sep = '';
12
- let anchor = '';
13
- let tagName = '';
10
+ let reqSpace = false;
11
+ let anchor = null;
12
+ let tag = null;
13
+ let comma = null;
14
14
  let found = null;
15
15
  let start = null;
16
16
  for (const token of tokens) {
17
+ if (reqSpace) {
18
+ if (token.type !== 'space' &&
19
+ token.type !== 'newline' &&
20
+ token.type !== 'comma')
21
+ onError(token.offset, 'MISSING_CHAR', 'Tags and anchors must be separated from the next token by white space');
22
+ reqSpace = false;
23
+ }
17
24
  switch (token.type) {
18
25
  case 'space':
19
- // At the doc level, tabs at line start may be parsed as leading
20
- // white space rather than indentation.
21
- if (atNewline && indicator !== 'doc-start' && token.source[0] === '\t')
22
- onError(offset + length, 'Tabs are not allowed as indentation');
26
+ // At the doc level, tabs at line start may be parsed
27
+ // as leading white space rather than indentation.
28
+ // In a flow collection, only the parser handles indent.
29
+ if (!flow &&
30
+ atNewline &&
31
+ indicator !== 'doc-start' &&
32
+ token.source[0] === '\t')
33
+ onError(token, 'TAB_AS_INDENT', 'Tabs are not allowed as indentation');
23
34
  hasSpace = true;
24
35
  break;
25
36
  case 'comment': {
26
- if (doc.options.strict && !hasSpace)
27
- onError(offset + length, 'Comments must be separated from other tokens by white space characters');
28
- const cb = token.source.substring(1);
29
- if (!hasComment)
37
+ if (!hasSpace)
38
+ onError(token, 'MISSING_CHAR', 'Comments must be separated from other tokens by white space characters');
39
+ const cb = token.source.substring(1) || ' ';
40
+ if (!comment)
30
41
  comment = cb;
31
42
  else
32
- comment += sep + cb;
33
- hasComment = true;
34
- sep = '';
43
+ comment += commentSep + cb;
44
+ commentSep = '';
45
+ atNewline = false;
35
46
  break;
36
47
  }
37
48
  case 'newline':
38
- if (atNewline && !hasComment)
39
- spaceBefore = true;
49
+ if (atNewline) {
50
+ if (comment)
51
+ comment += token.source;
52
+ else
53
+ spaceBefore = true;
54
+ }
55
+ else
56
+ commentSep += token.source;
40
57
  atNewline = true;
41
58
  hasNewline = true;
42
59
  hasSpace = true;
43
- sep += token.source;
44
60
  break;
45
61
  case 'anchor':
46
62
  if (anchor)
47
- onError(offset + length, 'A node can have at most one anchor');
48
- anchor = token.source.substring(1);
63
+ onError(token, 'MULTIPLE_ANCHORS', 'A node can have at most one anchor');
64
+ anchor = token;
49
65
  if (start === null)
50
- start = offset + length;
66
+ start = token.offset;
51
67
  atNewline = false;
52
68
  hasSpace = false;
69
+ reqSpace = true;
53
70
  break;
54
71
  case 'tag': {
55
- if (tagName)
56
- onError(offset + length, 'A node can have at most one tag');
57
- const tn = doc.directives.tagName(token.source, msg => onError(offset, msg));
58
- if (tn)
59
- tagName = tn;
72
+ if (tag)
73
+ onError(token, 'MULTIPLE_TAGS', 'A node can have at most one tag');
74
+ tag = token;
60
75
  if (start === null)
61
- start = offset + length;
76
+ start = token.offset;
62
77
  atNewline = false;
63
78
  hasSpace = false;
79
+ reqSpace = true;
64
80
  break;
65
81
  }
66
82
  case indicator:
67
83
  // Could here handle preceding comments differently
68
- found = { indent: token.indent, offset: offset + length };
84
+ if (anchor || tag)
85
+ onError(token, 'BAD_PROP_ORDER', `Anchors and tags must be after the ${token.source} indicator`);
86
+ found = token;
69
87
  atNewline = false;
70
88
  hasSpace = false;
71
89
  break;
90
+ case 'comma':
91
+ if (flow) {
92
+ if (comma)
93
+ onError(token, 'UNEXPECTED_TOKEN', `Unexpected , in ${flow}`);
94
+ comma = token;
95
+ atNewline = false;
96
+ hasSpace = false;
97
+ break;
98
+ }
99
+ // else fallthrough
72
100
  default:
73
- onError(offset + length, `Unexpected ${token.type} token`);
101
+ onError(token, 'UNEXPECTED_TOKEN', `Unexpected ${token.type} token`);
74
102
  atNewline = false;
75
103
  hasSpace = false;
76
104
  }
77
- /* istanbul ignore else should not happen */
78
- if (token.source)
79
- length += token.source.length;
80
105
  }
106
+ const last = tokens[tokens.length - 1];
107
+ const end = last ? last.offset + last.source.length : offset;
108
+ if (reqSpace &&
109
+ next &&
110
+ next.type !== 'space' &&
111
+ next.type !== 'newline' &&
112
+ next.type !== 'comma' &&
113
+ (next.type !== 'scalar' || next.source !== ''))
114
+ onError(next.offset, 'MISSING_CHAR', 'Tags and anchors must be separated from the next token by white space');
81
115
  return {
116
+ comma,
82
117
  found,
83
118
  spaceBefore,
84
119
  comment,
85
120
  hasNewline,
86
121
  anchor,
87
- tagName,
88
- length,
89
- start: start !== null && start !== void 0 ? start : offset + length
122
+ tag,
123
+ end,
124
+ start: start !== null && start !== void 0 ? start : end
90
125
  };
91
126
  }
92
127
 
@@ -1,2 +1,2 @@
1
- import type { Token } from '../parse/tokens.js';
1
+ import type { Token } from '../parse/cst.js';
2
2
  export declare function containsNewline(key: Token | null | undefined): boolean | null;
@@ -8,21 +8,24 @@ function containsNewline(key) {
8
8
  case 'scalar':
9
9
  case 'double-quoted-scalar':
10
10
  case 'single-quoted-scalar':
11
- return key.source.includes('\n');
11
+ if (key.source.includes('\n'))
12
+ return true;
13
+ if (key.end)
14
+ for (const st of key.end)
15
+ if (st.type === 'newline')
16
+ return true;
17
+ return false;
12
18
  case 'flow-collection':
13
- for (const token of key.items) {
14
- switch (token.type) {
15
- case 'newline':
19
+ for (const it of key.items) {
20
+ for (const st of it.start)
21
+ if (st.type === 'newline')
16
22
  return true;
17
- case 'alias':
18
- case 'scalar':
19
- case 'double-quoted-scalar':
20
- case 'single-quoted-scalar':
21
- case 'flow-collection':
22
- if (containsNewline(token))
23
+ if (it.sep)
24
+ for (const st of it.sep)
25
+ if (st.type === 'newline')
23
26
  return true;
24
- break;
25
- }
27
+ if (containsNewline(it.key) || containsNewline(it.value))
28
+ return true;
26
29
  }
27
30
  return false;
28
31
  default:
@@ -1,2 +1,2 @@
1
- import type { Token } from '../parse/tokens.js';
1
+ import type { Token } from '../parse/cst.js';
2
2
  export declare function emptyScalarPosition(offset: number, before: Token[] | undefined, pos: number | null): number;
@@ -0,0 +1,4 @@
1
+ import { ParsedNode } from '../nodes/Node';
2
+ import { Pair } from '../nodes/Pair';
3
+ import { ComposeContext } from './compose-node';
4
+ export declare function mapIncludes(ctx: ComposeContext, items: Pair<ParsedNode>[], search: ParsedNode): boolean;
@@ -0,0 +1,19 @@
1
+ 'use strict';
2
+
3
+ var Node = require('../nodes/Node.js');
4
+
5
+ function mapIncludes(ctx, items, search) {
6
+ const { uniqueKeys } = ctx.options;
7
+ if (uniqueKeys === false)
8
+ return false;
9
+ const isEqual = typeof uniqueKeys === 'function'
10
+ ? uniqueKeys
11
+ : (a, b) => a === b ||
12
+ (Node.isScalar(a) &&
13
+ Node.isScalar(b) &&
14
+ a.value === b.value &&
15
+ !(a.value === '<<' && ctx.schema.merge));
16
+ return items.some(pair => isEqual(pair.key, search));
17
+ }
18
+
19
+ exports.mapIncludes = mapIncludes;
@@ -1,25 +1,21 @@
1
1
  import type { YAMLError, YAMLWarning } from '../errors.js';
2
- import { Node, NODE_TYPE, ParsedNode } from '../nodes/Node.js';
2
+ import { Alias } from '../nodes/Alias.js';
3
+ import { Node, NODE_TYPE, ParsedNode, Range } from '../nodes/Node.js';
3
4
  import { Pair } from '../nodes/Pair.js';
4
- import { CreateNodeOptions, DocumentOptions, Options, ParseOptions, SchemaOptions, ToJSOptions, ToStringOptions } from '../options.js';
5
- import { Anchors } from './Anchors.js';
6
- import { Schema } from './Schema.js';
5
+ import type { Scalar } from '../nodes/Scalar.js';
6
+ import type { YAMLMap } from '../nodes/YAMLMap.js';
7
+ import type { YAMLSeq } from '../nodes/YAMLSeq.js';
8
+ import { CreateNodeOptions, DocumentOptions, ParseOptions, SchemaOptions, ToJSOptions, ToStringOptions } from '../options.js';
9
+ import { Schema } from '../schema/Schema.js';
7
10
  import { Directives } from './directives.js';
8
11
  export declare type Replacer = any[] | ((key: any, value: any) => unknown);
9
12
  export declare namespace Document {
10
13
  interface Parsed<T extends ParsedNode = ParsedNode> extends Document<T> {
11
- range: [number, number];
12
- /** The schema used with the document. */
13
- schema: Schema;
14
+ range: Range;
14
15
  }
15
16
  }
16
17
  export declare class Document<T = unknown> {
17
18
  readonly [NODE_TYPE]: symbol;
18
- /**
19
- * Anchors associated with the document's nodes;
20
- * also provides alias & merge node creators.
21
- */
22
- anchors: Anchors;
23
19
  /** A comment before this Document */
24
20
  commentBefore: string | null;
25
21
  /** A comment immediately after this Document */
@@ -30,6 +26,13 @@ export declare class Document<T = unknown> {
30
26
  /** Errors encountered during parsing. */
31
27
  errors: YAMLError[];
32
28
  options: Required<Omit<ParseOptions & DocumentOptions, 'lineCounter' | 'directives' | 'version'>>;
29
+ /**
30
+ * The `[start, value-end, node-end]` character offsets for the part of the
31
+ * source parsed into this document (undefined if not parsed). The `value-end`
32
+ * and `node-end` positions are themselves not included in their respective
33
+ * ranges.
34
+ */
35
+ range?: Range;
33
36
  /** The schema used with the document. Use `setSchema()` to change. */
34
37
  schema: Schema;
35
38
  /** Warnings encountered during parsing. */
@@ -38,17 +41,34 @@ export declare class Document<T = unknown> {
38
41
  * @param value - The initial value for the document, which will be wrapped
39
42
  * in a Node container.
40
43
  */
41
- constructor(value?: any, options?: Options);
42
- constructor(value: any, replacer: null | Replacer, options?: Options);
44
+ constructor(value?: any, options?: DocumentOptions & SchemaOptions & ParseOptions & CreateNodeOptions);
45
+ constructor(value: any, replacer: null | Replacer, options?: DocumentOptions & SchemaOptions & ParseOptions & CreateNodeOptions);
46
+ /**
47
+ * Create a deep copy of this Document and its contents.
48
+ *
49
+ * Custom Node values that inherit from `Object` still refer to their original instances.
50
+ */
51
+ clone(): Document<T>;
43
52
  /** Adds a value to the document. */
44
53
  add(value: any): void;
45
54
  /** Adds a value to the document. */
46
55
  addIn(path: Iterable<unknown>, value: unknown): void;
56
+ /**
57
+ * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
58
+ *
59
+ * If `node` already has an anchor, `name` is ignored.
60
+ * Otherwise, the `node.anchor` value will be set to `name`,
61
+ * or if an anchor with that name is already present in the document,
62
+ * `name` will be used as a prefix for a new unique anchor.
63
+ * If `name` is undefined, the generated anchor will use 'a' as a prefix.
64
+ */
65
+ createAlias(node: Scalar | YAMLMap | YAMLSeq, name?: string): Alias;
47
66
  /**
48
67
  * Convert any value into a `Node` using the current schema, recursively
49
68
  * turning objects into collections.
50
69
  */
51
- createNode(value: unknown, { flow, keepUndefined, onTagObj, replacer, tag }?: CreateNodeOptions): Node;
70
+ createNode(value: unknown, options?: CreateNodeOptions): Node;
71
+ createNode(value: unknown, replacer: Replacer | CreateNodeOptions | null, options?: CreateNodeOptions): Node;
52
72
  /**
53
73
  * Convert a key and a value into a `Pair` using the current schema,
54
74
  * recursively wrapping all values as `Scalar` or `Collection` nodes.