yaml 2.0.0-4 → 2.0.0-5

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 (210) 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 +20 -17
  5. package/browser/dist/compose/compose-scalar.js +20 -23
  6. package/browser/dist/compose/composer.js +105 -76
  7. package/browser/dist/compose/resolve-block-map.js +38 -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 +6 -7
  11. package/browser/dist/compose/resolve-flow-collection.js +153 -199
  12. package/browser/dist/compose/resolve-flow-scalar.js +49 -25
  13. package/browser/dist/compose/resolve-props.js +47 -35
  14. package/browser/dist/compose/util-contains-newline.js +15 -12
  15. package/browser/dist/doc/Document.js +50 -99
  16. package/browser/dist/doc/anchors.js +72 -0
  17. package/browser/dist/doc/createNode.js +27 -17
  18. package/browser/dist/errors.js +16 -12
  19. package/browser/dist/index.js +3 -3
  20. package/browser/dist/nodes/Alias.js +51 -28
  21. package/browser/dist/nodes/Collection.js +5 -83
  22. package/browser/dist/nodes/Node.js +2 -1
  23. package/browser/dist/nodes/Pair.js +9 -232
  24. package/browser/dist/nodes/YAMLMap.js +8 -4
  25. package/browser/dist/nodes/YAMLSeq.js +7 -4
  26. package/browser/dist/nodes/addPairToJSMap.js +103 -0
  27. package/browser/dist/nodes/toJS.js +12 -10
  28. package/browser/dist/options.js +0 -2
  29. package/browser/dist/parse/cst-scalar.js +219 -0
  30. package/browser/dist/parse/cst-stringify.js +61 -0
  31. package/browser/dist/parse/cst-visit.js +97 -0
  32. package/{dist/parse/tokens.js → browser/dist/parse/cst.js} +12 -7
  33. package/browser/dist/parse/lexer.js +99 -105
  34. package/browser/dist/parse/parser.js +219 -144
  35. package/browser/dist/public-api.js +11 -14
  36. package/browser/dist/schema/Schema.js +23 -0
  37. package/browser/dist/{tags/failsafe → schema/common}/map.js +0 -0
  38. package/browser/dist/schema/common/null.js +13 -0
  39. package/browser/dist/{tags/failsafe → schema/common}/seq.js +1 -1
  40. package/browser/dist/{tags/failsafe → schema/common}/string.js +0 -0
  41. package/browser/dist/schema/core/bool.js +19 -0
  42. package/browser/dist/schema/core/float.js +40 -0
  43. package/browser/dist/schema/core/int.js +38 -0
  44. package/browser/dist/schema/core/schema.js +23 -0
  45. package/browser/dist/{tags/json.js → schema/json/schema.js} +5 -6
  46. package/browser/dist/schema/tags.js +79 -0
  47. package/browser/dist/{tags → schema}/yaml-1.1/binary.js +0 -0
  48. package/browser/dist/schema/yaml-1.1/bool.js +26 -0
  49. package/browser/dist/schema/yaml-1.1/float.js +43 -0
  50. package/browser/dist/schema/yaml-1.1/int.js +71 -0
  51. package/browser/dist/{tags → schema}/yaml-1.1/omap.js +0 -0
  52. package/browser/dist/{tags → schema}/yaml-1.1/pairs.js +9 -6
  53. package/browser/dist/schema/yaml-1.1/schema.js +37 -0
  54. package/browser/dist/{tags → schema}/yaml-1.1/set.js +0 -0
  55. package/browser/dist/{tags → schema}/yaml-1.1/timestamp.js +0 -0
  56. package/browser/dist/stringify/addComment.js +1 -7
  57. package/browser/dist/stringify/stringify.js +8 -6
  58. package/browser/dist/stringify/stringifyCollection.js +108 -0
  59. package/browser/dist/stringify/stringifyDocument.js +61 -0
  60. package/browser/dist/stringify/stringifyPair.js +113 -0
  61. package/browser/dist/stringify/stringifyString.js +53 -52
  62. package/browser/dist/visit.js +20 -1
  63. package/dist/compose/compose-collection.d.ts +4 -4
  64. package/dist/compose/compose-collection.js +12 -9
  65. package/dist/compose/compose-doc.d.ts +4 -3
  66. package/dist/compose/compose-doc.js +23 -6
  67. package/dist/compose/compose-node.d.ts +15 -7
  68. package/dist/compose/compose-node.js +20 -17
  69. package/dist/compose/compose-scalar.d.ts +4 -3
  70. package/dist/compose/compose-scalar.js +19 -22
  71. package/dist/compose/composer.d.ts +28 -23
  72. package/dist/compose/composer.js +106 -77
  73. package/dist/compose/resolve-block-map.d.ts +4 -4
  74. package/dist/compose/resolve-block-map.js +38 -29
  75. package/dist/compose/resolve-block-scalar.d.ts +5 -3
  76. package/dist/compose/resolve-block-scalar.js +14 -17
  77. package/dist/compose/resolve-block-seq.d.ts +4 -4
  78. package/dist/compose/resolve-block-seq.js +21 -17
  79. package/dist/compose/resolve-end.d.ts +3 -2
  80. package/dist/compose/resolve-end.js +6 -7
  81. package/dist/compose/resolve-flow-collection.d.ts +4 -5
  82. package/dist/compose/resolve-flow-collection.js +152 -198
  83. package/dist/compose/resolve-flow-scalar.d.ts +5 -3
  84. package/dist/compose/resolve-flow-scalar.js +49 -25
  85. package/dist/compose/resolve-props.d.ts +17 -10
  86. package/dist/compose/resolve-props.js +47 -35
  87. package/dist/compose/util-contains-newline.d.ts +1 -1
  88. package/dist/compose/util-contains-newline.js +15 -12
  89. package/dist/compose/util-empty-scalar-position.d.ts +1 -1
  90. package/dist/doc/Document.d.ts +27 -15
  91. package/dist/doc/Document.js +48 -97
  92. package/dist/doc/anchors.d.ts +24 -0
  93. package/dist/doc/anchors.js +77 -0
  94. package/dist/doc/createNode.d.ts +8 -10
  95. package/dist/doc/createNode.js +26 -16
  96. package/dist/errors.d.ts +11 -8
  97. package/dist/errors.js +16 -12
  98. package/dist/index.d.ts +5 -3
  99. package/dist/index.js +3 -3
  100. package/dist/nodes/Alias.d.ts +19 -9
  101. package/dist/nodes/Alias.js +51 -28
  102. package/dist/nodes/Collection.d.ts +3 -17
  103. package/dist/nodes/Collection.js +4 -82
  104. package/dist/nodes/Node.d.ts +6 -4
  105. package/dist/nodes/Node.js +2 -0
  106. package/dist/nodes/Pair.d.ts +6 -11
  107. package/dist/nodes/Pair.js +8 -231
  108. package/dist/nodes/Scalar.d.ts +6 -3
  109. package/dist/nodes/YAMLMap.d.ts +3 -3
  110. package/dist/nodes/YAMLMap.js +8 -4
  111. package/dist/nodes/YAMLSeq.d.ts +3 -3
  112. package/dist/nodes/YAMLSeq.js +7 -4
  113. package/dist/nodes/addPairToJSMap.d.ts +3 -0
  114. package/dist/nodes/addPairToJSMap.js +105 -0
  115. package/dist/nodes/toJS.d.ts +4 -5
  116. package/dist/nodes/toJS.js +12 -10
  117. package/dist/options.d.ts +20 -26
  118. package/dist/options.js +0 -2
  119. package/dist/parse/cst-scalar.d.ts +58 -0
  120. package/dist/parse/cst-scalar.js +223 -0
  121. package/dist/parse/cst-stringify.d.ts +8 -0
  122. package/dist/parse/cst-stringify.js +63 -0
  123. package/dist/parse/cst-visit.d.ts +39 -0
  124. package/dist/parse/cst-visit.js +99 -0
  125. package/dist/parse/{tokens.d.ts → cst.d.ts} +23 -7
  126. package/{browser/dist/parse/tokens.js → dist/parse/cst.js} +27 -1
  127. package/dist/parse/lexer.d.ts +4 -13
  128. package/dist/parse/lexer.js +100 -106
  129. package/dist/parse/parser.d.ts +30 -24
  130. package/dist/parse/parser.js +221 -146
  131. package/dist/public-api.d.ts +7 -7
  132. package/dist/public-api.js +11 -14
  133. package/dist/{doc → schema}/Schema.d.ts +5 -3
  134. package/dist/schema/Schema.js +25 -0
  135. package/dist/{tags/failsafe → schema/common}/map.d.ts +0 -0
  136. package/dist/{tags/failsafe → schema/common}/map.js +0 -0
  137. package/dist/schema/common/null.d.ts +4 -0
  138. package/dist/schema/common/null.js +15 -0
  139. package/dist/{tags/failsafe → schema/common}/seq.d.ts +0 -0
  140. package/dist/{tags/failsafe → schema/common}/seq.js +1 -1
  141. package/dist/{tags/failsafe → schema/common}/string.d.ts +0 -0
  142. package/dist/{tags/failsafe → schema/common}/string.js +0 -0
  143. package/dist/schema/core/bool.d.ts +4 -0
  144. package/dist/schema/core/bool.js +21 -0
  145. package/dist/schema/core/float.d.ts +4 -0
  146. package/dist/schema/core/float.js +44 -0
  147. package/dist/schema/core/int.d.ts +4 -0
  148. package/dist/schema/core/int.js +42 -0
  149. package/dist/schema/core/schema.d.ts +1 -0
  150. package/dist/schema/core/schema.js +25 -0
  151. package/dist/schema/json/schema.d.ts +2 -0
  152. package/dist/{tags/json.js → schema/json/schema.js} +5 -6
  153. package/dist/schema/tags.d.ts +41 -0
  154. package/dist/schema/tags.js +82 -0
  155. package/dist/{tags → schema}/types.d.ts +3 -7
  156. package/dist/{tags → schema}/yaml-1.1/binary.d.ts +0 -0
  157. package/dist/{tags → schema}/yaml-1.1/binary.js +0 -0
  158. package/dist/schema/yaml-1.1/bool.d.ts +7 -0
  159. package/dist/schema/yaml-1.1/bool.js +29 -0
  160. package/dist/schema/yaml-1.1/float.d.ts +4 -0
  161. package/dist/schema/yaml-1.1/float.js +47 -0
  162. package/dist/schema/yaml-1.1/int.d.ts +5 -0
  163. package/dist/schema/yaml-1.1/int.js +76 -0
  164. package/dist/{tags → schema}/yaml-1.1/omap.d.ts +0 -0
  165. package/dist/{tags → schema}/yaml-1.1/omap.js +0 -0
  166. package/dist/{tags → schema}/yaml-1.1/pairs.d.ts +3 -2
  167. package/dist/{tags → schema}/yaml-1.1/pairs.js +9 -6
  168. package/dist/schema/yaml-1.1/schema.d.ts +1 -0
  169. package/dist/schema/yaml-1.1/schema.js +39 -0
  170. package/dist/{tags → schema}/yaml-1.1/set.d.ts +1 -1
  171. package/dist/{tags → schema}/yaml-1.1/set.js +0 -0
  172. package/dist/{tags → schema}/yaml-1.1/timestamp.d.ts +0 -0
  173. package/dist/{tags → schema}/yaml-1.1/timestamp.js +0 -0
  174. package/dist/stringify/addComment.js +0 -7
  175. package/dist/stringify/stringify.d.ts +1 -2
  176. package/dist/stringify/stringify.js +8 -6
  177. package/dist/stringify/stringifyCollection.d.ts +21 -0
  178. package/dist/stringify/stringifyCollection.js +110 -0
  179. package/dist/stringify/stringifyDocument.d.ts +3 -0
  180. package/dist/stringify/stringifyDocument.js +63 -0
  181. package/dist/stringify/stringifyPair.d.ts +3 -0
  182. package/dist/stringify/stringifyPair.js +115 -0
  183. package/dist/stringify/stringifyString.js +53 -52
  184. package/dist/test-events.d.ts +1 -2
  185. package/dist/test-events.js +25 -12
  186. package/dist/util.d.ts +1 -1
  187. package/dist/visit.d.ts +10 -1
  188. package/dist/visit.js +20 -1
  189. package/package.json +4 -3
  190. package/browser/dist/doc/Anchors.js +0 -102
  191. package/browser/dist/doc/Schema.js +0 -27
  192. package/browser/dist/doc/getSchemaTags.js +0 -30
  193. package/browser/dist/tags/core.js +0 -109
  194. package/browser/dist/tags/failsafe/index.js +0 -7
  195. package/browser/dist/tags/index.js +0 -34
  196. package/browser/dist/tags/yaml-1.1/index.js +0 -152
  197. package/dist/doc/Anchors.d.ts +0 -36
  198. package/dist/doc/Anchors.js +0 -104
  199. package/dist/doc/Schema.js +0 -29
  200. package/dist/doc/getSchemaTags.d.ts +0 -3
  201. package/dist/doc/getSchemaTags.js +0 -32
  202. package/dist/tags/core.d.ts +0 -14
  203. package/dist/tags/core.js +0 -119
  204. package/dist/tags/failsafe/index.d.ts +0 -1
  205. package/dist/tags/failsafe/index.js +0 -9
  206. package/dist/tags/index.d.ts +0 -31
  207. package/dist/tags/index.js +0 -37
  208. package/dist/tags/json.d.ts +0 -2
  209. package/dist/tags/yaml-1.1/index.d.ts +0 -2
  210. package/dist/tags/yaml-1.1/index.js +0 -154
@@ -0,0 +1,61 @@
1
+ import { isNode } from '../nodes/Node.js';
2
+ import { addComment } from './addComment.js';
3
+ import { createStringifyContext, stringify } from './stringify.js';
4
+
5
+ function stringifyDocument(doc, options) {
6
+ const lines = [];
7
+ let hasDirectives = options.directives === true;
8
+ if (options.directives !== false) {
9
+ const dir = doc.directives.toString(doc);
10
+ if (dir) {
11
+ lines.push(dir);
12
+ hasDirectives = true;
13
+ }
14
+ else if (doc.directives.marker)
15
+ hasDirectives = true;
16
+ }
17
+ if (hasDirectives)
18
+ lines.push('---');
19
+ if (doc.commentBefore) {
20
+ if (lines.length !== 1)
21
+ lines.unshift('');
22
+ lines.unshift(doc.commentBefore.replace(/^/gm, '#'));
23
+ }
24
+ const ctx = createStringifyContext(doc, options);
25
+ let chompKeep = false;
26
+ let contentComment = null;
27
+ if (doc.contents) {
28
+ if (isNode(doc.contents)) {
29
+ if (doc.contents.spaceBefore && hasDirectives)
30
+ lines.push('');
31
+ if (doc.contents.commentBefore)
32
+ lines.push(doc.contents.commentBefore.replace(/^/gm, '#'));
33
+ // top-level block scalars need to be indented if followed by a comment
34
+ ctx.forceBlockIndent = !!doc.comment;
35
+ contentComment = doc.contents.comment;
36
+ }
37
+ const onChompKeep = contentComment ? undefined : () => (chompKeep = true);
38
+ let body = stringify(doc.contents, ctx, () => (contentComment = null), onChompKeep);
39
+ if (contentComment)
40
+ body = addComment(body, '', contentComment);
41
+ if ((body[0] === '|' || body[0] === '>') &&
42
+ lines[lines.length - 1] === '---') {
43
+ // Top-level block scalars with a preceding doc marker ought to use the
44
+ // same line for their header.
45
+ lines[lines.length - 1] = `--- ${body}`;
46
+ }
47
+ else
48
+ lines.push(body);
49
+ }
50
+ else {
51
+ lines.push(stringify(doc.contents, ctx));
52
+ }
53
+ if (doc.comment) {
54
+ if ((!chompKeep || contentComment) && lines[lines.length - 1] !== '')
55
+ lines.push('');
56
+ lines.push(doc.comment.replace(/^/gm, '#'));
57
+ }
58
+ return lines.join('\n') + '\n';
59
+ }
60
+
61
+ export { stringifyDocument };
@@ -0,0 +1,113 @@
1
+ import { isCollection, isNode, isScalar, isSeq } from '../nodes/Node.js';
2
+ import { Scalar } from '../nodes/Scalar.js';
3
+ import { addComment } from './addComment.js';
4
+ import { stringify } from './stringify.js';
5
+
6
+ function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
7
+ const { allNullValues, doc, indent, indentStep, options: { indentSeq, simpleKeys } } = ctx;
8
+ let keyComment = (isNode(key) && key.comment) || null;
9
+ if (simpleKeys) {
10
+ if (keyComment) {
11
+ throw new Error('With simple keys, key nodes cannot have comments');
12
+ }
13
+ if (isCollection(key)) {
14
+ const msg = 'With simple keys, collection cannot be used as a key value';
15
+ throw new Error(msg);
16
+ }
17
+ }
18
+ let explicitKey = !simpleKeys &&
19
+ (!key ||
20
+ (keyComment && value == null && !ctx.inFlow) ||
21
+ isCollection(key) ||
22
+ (isScalar(key)
23
+ ? key.type === Scalar.BLOCK_FOLDED || key.type === Scalar.BLOCK_LITERAL
24
+ : typeof key === 'object'));
25
+ ctx = Object.assign({}, ctx, {
26
+ allNullValues: false,
27
+ implicitKey: !explicitKey && (simpleKeys || !allNullValues),
28
+ indent: indent + indentStep
29
+ });
30
+ let keyCommentDone = false;
31
+ let chompKeep = false;
32
+ let str = stringify(key, ctx, () => (keyCommentDone = true), () => (chompKeep = true));
33
+ if (!explicitKey && !ctx.inFlow && str.length > 1024) {
34
+ if (simpleKeys)
35
+ throw new Error('With simple keys, single line scalar must not span more than 1024 characters');
36
+ explicitKey = true;
37
+ }
38
+ if (ctx.inFlow) {
39
+ if (allNullValues || value == null) {
40
+ if (keyCommentDone && onComment)
41
+ onComment();
42
+ return explicitKey ? `? ${str}` : str;
43
+ }
44
+ }
45
+ else if ((allNullValues && !simpleKeys) || (value == null && explicitKey)) {
46
+ if (keyCommentDone)
47
+ keyComment = null;
48
+ if (chompKeep && !keyComment && onChompKeep)
49
+ onChompKeep();
50
+ return addComment(`? ${str}`, ctx.indent, keyComment);
51
+ }
52
+ if (keyCommentDone)
53
+ keyComment = null;
54
+ str = explicitKey
55
+ ? `? ${addComment(str, ctx.indent, keyComment)}\n${indent}:`
56
+ : addComment(`${str}:`, ctx.indent, keyComment);
57
+ let vcb = '';
58
+ let valueComment = null;
59
+ if (isNode(value)) {
60
+ if (value.spaceBefore)
61
+ vcb = '\n';
62
+ if (value.commentBefore) {
63
+ const cs = value.commentBefore.replace(/^/gm, `${ctx.indent}#`);
64
+ vcb += `\n${cs}`;
65
+ }
66
+ valueComment = value.comment;
67
+ }
68
+ else if (value && typeof value === 'object') {
69
+ value = doc.createNode(value);
70
+ }
71
+ ctx.implicitKey = false;
72
+ if (!explicitKey && !keyComment && isScalar(value))
73
+ ctx.indentAtStart = str.length + 1;
74
+ chompKeep = false;
75
+ if (!indentSeq &&
76
+ indentStep.length >= 2 &&
77
+ !ctx.inFlow &&
78
+ !explicitKey &&
79
+ isSeq(value) &&
80
+ !value.flow &&
81
+ !value.tag &&
82
+ !value.anchor) {
83
+ // If indentSeq === false, consider '- ' as part of indentation where possible
84
+ ctx.indent = ctx.indent.substr(2);
85
+ }
86
+ let valueCommentDone = false;
87
+ const valueStr = stringify(value, ctx, () => (valueCommentDone = true), () => (chompKeep = true));
88
+ let ws = ' ';
89
+ if (vcb || keyComment) {
90
+ ws = `${vcb}\n${ctx.indent}`;
91
+ }
92
+ else if (!explicitKey && isCollection(value)) {
93
+ const flow = valueStr[0] === '[' || valueStr[0] === '{';
94
+ if (!flow || valueStr.includes('\n'))
95
+ ws = `\n${ctx.indent}`;
96
+ }
97
+ else if (valueStr[0] === '\n')
98
+ ws = '';
99
+ if (ctx.inFlow) {
100
+ if (valueCommentDone && onComment)
101
+ onComment();
102
+ return str + ws + valueStr;
103
+ }
104
+ else {
105
+ if (valueCommentDone)
106
+ valueComment = null;
107
+ if (chompKeep && !valueComment && onChompKeep)
108
+ onChompKeep();
109
+ return addComment(str + ws + valueStr, ctx.indent, valueComment);
110
+ }
111
+ }
112
+
113
+ export { stringifyPair };
@@ -1,5 +1,4 @@
1
1
  import { Scalar } from '../nodes/Scalar.js';
2
- import { addCommentBefore } from './addComment.js';
3
2
  import { foldFlowLines, FOLD_QUOTED, FOLD_FLOW, FOLD_BLOCK } from './foldFlowLines.js';
4
3
 
5
4
  const getFoldOptions = (ctx) => ({
@@ -142,70 +141,80 @@ function blockString({ comment, type, value }, ctx, onComment, onChompKeep) {
142
141
  }
143
142
  const indent = ctx.indent ||
144
143
  (ctx.forceBlockIndent || containsDocumentMarker(value) ? ' ' : '');
145
- const indentSize = indent ? '2' : '1'; // root is at -1
146
144
  const literal = type === Scalar.BLOCK_FOLDED
147
145
  ? false
148
146
  : type === Scalar.BLOCK_LITERAL
149
147
  ? true
150
148
  : !lineLengthOverLimit(value, ctx.options.lineWidth, indent.length);
151
- let header = literal ? '|' : '>';
152
149
  if (!value)
153
- return header + '\n';
154
- let wsStart = '';
155
- let wsEnd = '';
156
- value = value
157
- .replace(/[\n\t ]*$/, ws => {
158
- const n = ws.indexOf('\n');
159
- if (n === -1) {
160
- header += '-'; // strip
161
- }
162
- else if (value === ws || n !== ws.length - 1) {
163
- header += '+'; // keep
164
- if (onChompKeep)
165
- onChompKeep();
166
- }
167
- wsEnd = ws.replace(/\n$/, '');
168
- return '';
169
- })
170
- .replace(/^[\n ]*/, ws => {
171
- if (ws.indexOf(' ') !== -1)
172
- header += indentSize;
173
- const m = ws.match(/ +$/);
174
- if (m) {
175
- wsStart = ws.slice(0, -m[0].length);
176
- return m[0];
177
- }
178
- else {
179
- wsStart = ws;
180
- return '';
181
- }
182
- });
183
- if (wsEnd)
184
- wsEnd = wsEnd.replace(/\n+(?!\n|$)/g, `$&${indent}`);
185
- if (wsStart)
186
- wsStart = wsStart.replace(/\n+/g, `$&${indent}`);
150
+ return literal ? '|\n' : '>\n';
151
+ // determine chomping from whitespace at value end
152
+ let chomp;
153
+ let endStart;
154
+ for (endStart = value.length; endStart > 0; --endStart) {
155
+ const ch = value[endStart - 1];
156
+ if (ch !== '\n' && ch !== '\t' && ch !== ' ')
157
+ break;
158
+ }
159
+ let end = value.substring(endStart);
160
+ const endNlPos = end.indexOf('\n');
161
+ if (endNlPos === -1) {
162
+ chomp = '-'; // strip
163
+ }
164
+ else if (value === end || endNlPos !== end.length - 1) {
165
+ chomp = '+'; // keep
166
+ if (onChompKeep)
167
+ onChompKeep();
168
+ }
169
+ else {
170
+ chomp = ''; // clip
171
+ }
172
+ if (end) {
173
+ value = value.slice(0, -end.length);
174
+ if (end[end.length - 1] === '\n')
175
+ end = end.slice(0, -1);
176
+ end = end.replace(/\n+(?!\n|$)/g, `$&${indent}`);
177
+ }
178
+ // determine indent indicator from whitespace at value start
179
+ let startWithSpace = false;
180
+ let startEnd;
181
+ let startNlPos = -1;
182
+ for (startEnd = 0; startEnd < value.length; ++startEnd) {
183
+ const ch = value[startEnd];
184
+ if (ch === ' ')
185
+ startWithSpace = true;
186
+ else if (ch === '\n')
187
+ startNlPos = startEnd;
188
+ else
189
+ break;
190
+ }
191
+ let start = value.substring(0, startNlPos < startEnd ? startNlPos + 1 : startEnd);
192
+ if (start) {
193
+ value = value.substring(start.length);
194
+ start = start.replace(/\n+/g, `$&${indent}`);
195
+ }
196
+ const indentSize = indent ? '2' : '1'; // root is at -1
197
+ let header = (literal ? '|' : '>') + (startWithSpace ? indentSize : '') + chomp;
187
198
  if (comment) {
188
199
  header += ' #' + comment.replace(/ ?[\r\n]+/g, ' ');
189
200
  if (onComment)
190
201
  onComment();
191
202
  }
192
- if (!value)
193
- return `${header}${indentSize}\n${indent}${wsEnd}`;
194
203
  if (literal) {
195
204
  value = value.replace(/\n+/g, `$&${indent}`);
196
- return `${header}\n${indent}${wsStart}${value}${wsEnd}`;
205
+ return `${header}\n${indent}${start}${value}${end}`;
197
206
  }
198
207
  value = value
199
208
  .replace(/\n+/g, '\n$&')
200
209
  .replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, '$1$2') // more-indented lines aren't folded
201
- // ^ ind.line ^ empty ^ capture next empty lines only at end of indent
210
+ // ^ more-ind. ^ empty ^ capture next empty lines only at end of indent
202
211
  .replace(/\n+/g, `$&${indent}`);
203
- const body = foldFlowLines(`${wsStart}${value}${wsEnd}`, indent, FOLD_BLOCK, getFoldOptions(ctx));
212
+ const body = foldFlowLines(`${start}${value}${end}`, indent, FOLD_BLOCK, getFoldOptions(ctx));
204
213
  return `${header}\n${indent}${body}`;
205
214
  }
206
215
  function plainString(item, ctx, onComment, onChompKeep) {
207
216
  var _a;
208
- const { comment, type, value } = item;
217
+ const { type, value } = item;
209
218
  const { actualString, implicitKey, indent, inFlow } = ctx;
210
219
  if ((implicitKey && /[\n[\]{},]/.test(value)) ||
211
220
  (inFlow && /[[\]{},]/.test(value))) {
@@ -261,17 +270,9 @@ function plainString(item, ctx, onComment, onChompKeep) {
261
270
  return doubleQuotedString(value, ctx);
262
271
  }
263
272
  }
264
- const body = implicitKey
273
+ return implicitKey
265
274
  ? str
266
275
  : foldFlowLines(str, indent, FOLD_FLOW, getFoldOptions(ctx));
267
- if (comment &&
268
- !inFlow &&
269
- (body.indexOf('\n') !== -1 || comment.indexOf('\n') !== -1)) {
270
- if (onComment)
271
- onComment();
272
- return addCommentBefore(body, indent, comment);
273
- }
274
- return body;
275
276
  }
276
277
  function stringifyString(item, ctx, onComment, onChompKeep) {
277
278
  const { implicitKey, inFlow } = ctx;
@@ -28,9 +28,28 @@ const REMOVE = Symbol('remove node');
28
28
  * If `visitor` is a single function, it will be called with all values
29
29
  * encountered in the tree, including e.g. `null` values. Alternatively,
30
30
  * separate visitor functions may be defined for each `Map`, `Pair`, `Seq`,
31
- * `Alias` and `Scalar` node.
31
+ * `Alias` and `Scalar` node. To define the same visitor function for more than
32
+ * one node type, use the `Collection` (map and seq), `Value` (map, seq & scalar)
33
+ * and `Node` (alias, map, seq & scalar) targets. Of all these, only the most
34
+ * specific defined one will be used for each node.
32
35
  */
33
36
  function visit(node, visitor) {
37
+ if (typeof visitor === 'object' &&
38
+ (visitor.Collection || visitor.Node || visitor.Value)) {
39
+ visitor = Object.assign({
40
+ Alias: visitor.Node,
41
+ Map: visitor.Node,
42
+ Scalar: visitor.Node,
43
+ Seq: visitor.Node
44
+ }, visitor.Value && {
45
+ Map: visitor.Value,
46
+ Scalar: visitor.Value,
47
+ Seq: visitor.Value
48
+ }, visitor.Collection && {
49
+ Map: visitor.Collection,
50
+ Seq: visitor.Collection
51
+ }, visitor);
52
+ }
34
53
  if (isDocument(node)) {
35
54
  const cd = _visit(null, node.contents, visitor, Object.freeze([node]));
36
55
  if (cd === REMOVE)
@@ -1,5 +1,5 @@
1
- import type { Document } from '../doc/Document.js';
2
1
  import { ParsedNode } from '../nodes/Node.js';
3
- import type { BlockMap, BlockSequence, FlowCollection } from '../parse/tokens.js';
4
- import type { ComposeNode } from './compose-node.js';
5
- export declare function composeCollection(CN: ComposeNode, doc: Document.Parsed, token: BlockMap | BlockSequence | FlowCollection, anchor: string | null, tagName: string | null, onError: (offset: number, message: string, warning?: boolean) => void): ParsedNode;
2
+ import type { BlockMap, BlockSequence, FlowCollection, SourceToken } from '../parse/cst.js';
3
+ import type { ComposeContext, ComposeNode } from './compose-node.js';
4
+ import type { ComposeErrorHandler } from './composer.js';
5
+ export declare function composeCollection(CN: ComposeNode, ctx: ComposeContext, token: BlockMap | BlockSequence | FlowCollection, tagToken: SourceToken | null, onError: ComposeErrorHandler): ParsedNode;
@@ -6,22 +6,25 @@ var resolveBlockMap = require('./resolve-block-map.js');
6
6
  var resolveBlockSeq = require('./resolve-block-seq.js');
7
7
  var resolveFlowCollection = require('./resolve-flow-collection.js');
8
8
 
9
- function composeCollection(CN, doc, token, anchor, tagName, onError) {
9
+ function composeCollection(CN, ctx, token, tagToken, onError) {
10
10
  let coll;
11
11
  switch (token.type) {
12
12
  case 'block-map': {
13
- coll = resolveBlockMap.resolveBlockMap(CN, doc, token, anchor, onError);
13
+ coll = resolveBlockMap.resolveBlockMap(CN, ctx, token, onError);
14
14
  break;
15
15
  }
16
16
  case 'block-seq': {
17
- coll = resolveBlockSeq.resolveBlockSeq(CN, doc, token, anchor, onError);
17
+ coll = resolveBlockSeq.resolveBlockSeq(CN, ctx, token, onError);
18
18
  break;
19
19
  }
20
20
  case 'flow-collection': {
21
- coll = resolveFlowCollection.resolveFlowCollection(CN, doc, token, anchor, onError);
21
+ coll = resolveFlowCollection.resolveFlowCollection(CN, ctx, token, onError);
22
22
  break;
23
23
  }
24
24
  }
25
+ if (!tagToken)
26
+ return coll;
27
+ const tagName = ctx.directives.tagName(tagToken.source, msg => onError(tagToken, 'TAG_RESOLVE_FAILED', msg));
25
28
  if (!tagName)
26
29
  return coll;
27
30
  // Cast needed due to: https://github.com/Microsoft/TypeScript/issues/3841
@@ -31,20 +34,20 @@ function composeCollection(CN, doc, token, anchor, tagName, onError) {
31
34
  return coll;
32
35
  }
33
36
  const expType = Node.isMap(coll) ? 'map' : 'seq';
34
- let tag = doc.schema.tags.find(t => t.collection === expType && t.tag === tagName);
37
+ let tag = ctx.schema.tags.find(t => t.collection === expType && t.tag === tagName);
35
38
  if (!tag) {
36
- const kt = doc.schema.knownTags[tagName];
39
+ const kt = ctx.schema.knownTags[tagName];
37
40
  if (kt && kt.collection === expType) {
38
- doc.schema.tags.push(Object.assign({}, kt, { default: false }));
41
+ ctx.schema.tags.push(Object.assign({}, kt, { default: false }));
39
42
  tag = kt;
40
43
  }
41
44
  else {
42
- onError(coll.range[0], `Unresolved tag: ${tagName}`, true);
45
+ onError(tagToken, 'TAG_RESOLVE_FAILED', `Unresolved tag: ${tagName}`, true);
43
46
  coll.tag = tagName;
44
47
  return coll;
45
48
  }
46
49
  }
47
- const res = tag.resolve(coll, msg => onError(coll.range[0], msg), doc.options);
50
+ const res = tag.resolve(coll, msg => onError(tagToken, 'TAG_RESOLVE_FAILED', msg), ctx.options);
48
51
  const node = Node.isNode(res)
49
52
  ? res
50
53
  : new Scalar.Scalar(res);
@@ -1,5 +1,6 @@
1
1
  import type { Directives } from '../doc/directives.js';
2
2
  import { Document } from '../doc/Document.js';
3
- import type { Options } from '../options.js';
4
- import type * as Tokens from '../parse/tokens.js';
5
- export declare function composeDoc(options: Options, directives: Directives, { offset, start, value, end }: Tokens.Document, onError: (offset: number, message: string, warning?: boolean) => void): Document.Parsed<import("../index.js").ParsedNode>;
3
+ import type { DocumentOptions, ParseOptions, SchemaOptions } from '../options.js';
4
+ import type * as CST from '../parse/cst.js';
5
+ import type { ComposeErrorHandler } from './composer.js';
6
+ export declare function composeDoc(options: ParseOptions & DocumentOptions & SchemaOptions, directives: Directives, { offset, start, value, end }: CST.Document, onError: ComposeErrorHandler): Document.Parsed<import("../index.js").ParsedNode>;
@@ -8,16 +8,33 @@ var resolveProps = require('./resolve-props.js');
8
8
  function composeDoc(options, directives, { offset, start, value, end }, onError) {
9
9
  const opts = Object.assign({ directives }, options);
10
10
  const doc = new Document.Document(undefined, opts);
11
- const props = resolveProps.resolveProps(doc, start, true, 'doc-start', offset, onError);
12
- if (props.found)
11
+ const ctx = {
12
+ directives: doc.directives,
13
+ options: doc.options,
14
+ schema: doc.schema
15
+ };
16
+ const props = resolveProps.resolveProps(start, {
17
+ ctx,
18
+ indicator: 'doc-start',
19
+ offset,
20
+ onError,
21
+ startOnNewline: true
22
+ });
23
+ if (props.found) {
13
24
  doc.directives.marker = true;
25
+ if (value &&
26
+ (value.type === 'block-map' || value.type === 'block-seq') &&
27
+ !props.hasNewline)
28
+ onError(props.end, 'MISSING_CHAR', 'Block collection cannot start on same line with directives-end marker');
29
+ }
14
30
  doc.contents = value
15
- ? composeNode.composeNode(doc, value, props, onError)
16
- : composeNode.composeEmptyNode(doc, offset + props.length, start, null, props, onError);
17
- const re = resolveEnd.resolveEnd(end, doc.contents.range[1], false, onError);
31
+ ? composeNode.composeNode(ctx, value, props, onError)
32
+ : composeNode.composeEmptyNode(ctx, props.end, start, null, props, onError);
33
+ const contentEnd = doc.contents.range[2];
34
+ const re = resolveEnd.resolveEnd(end, contentEnd, false, onError);
18
35
  if (re.comment)
19
36
  doc.comment = re.comment;
20
- doc.range = [offset, re.offset];
37
+ doc.range = [offset, contentEnd, re.offset];
21
38
  return doc;
22
39
  }
23
40
 
@@ -1,17 +1,25 @@
1
- import type { Document } from '../doc/Document.js';
1
+ import type { Directives } from '../doc/directives.js';
2
2
  import type { ParsedNode } from '../nodes/Node.js';
3
- import type { Token } from '../parse/tokens.js';
4
- export interface Props {
3
+ import type { ParseOptions } from '../options.js';
4
+ import type { SourceToken, Token } from '../parse/cst.js';
5
+ import type { Schema } from '../schema/Schema.js';
6
+ import type { ComposeErrorHandler } from './composer.js';
7
+ export interface ComposeContext {
8
+ directives: Directives;
9
+ options: Readonly<Required<Omit<ParseOptions, 'lineCounter'>>>;
10
+ schema: Readonly<Schema>;
11
+ }
12
+ interface Props {
5
13
  spaceBefore: boolean;
6
14
  comment: string;
7
- anchor: string;
8
- tagName: string;
15
+ anchor: SourceToken | null;
16
+ tag: SourceToken | null;
9
17
  }
10
18
  declare const CN: {
11
19
  composeNode: typeof composeNode;
12
20
  composeEmptyNode: typeof composeEmptyNode;
13
21
  };
14
22
  export declare type ComposeNode = typeof CN;
15
- export declare function composeNode(doc: Document.Parsed, token: Token, props: Props, onError: (offset: number, message: string, warning?: boolean) => void): ParsedNode;
16
- export declare function composeEmptyNode(doc: Document.Parsed, offset: number, before: Token[] | undefined, pos: number | null, { spaceBefore, comment, anchor, tagName }: Props, onError: (offset: number, message: string, warning?: boolean) => void): import("../index.js").Scalar.Parsed;
23
+ export declare function composeNode(ctx: ComposeContext, token: Token, props: Props, onError: ComposeErrorHandler): ParsedNode;
24
+ export declare function composeEmptyNode(ctx: ComposeContext, offset: number, before: Token[] | undefined, pos: number | null, { spaceBefore, comment, anchor, tag }: Props, onError: ComposeErrorHandler): import("../index.js").Scalar.Parsed;
17
25
  export {};
@@ -7,25 +7,29 @@ var resolveEnd = require('./resolve-end.js');
7
7
  var utilEmptyScalarPosition = require('./util-empty-scalar-position.js');
8
8
 
9
9
  const CN = { composeNode, composeEmptyNode };
10
- function composeNode(doc, token, props, onError) {
11
- const { spaceBefore, comment, anchor, tagName } = props;
10
+ function composeNode(ctx, token, props, onError) {
11
+ const { spaceBefore, comment, anchor, tag } = props;
12
12
  let node;
13
13
  switch (token.type) {
14
14
  case 'alias':
15
- node = composeAlias(doc, token, onError);
16
- if (anchor || tagName)
17
- onError(token.offset, 'An alias node must not specify any properties');
15
+ node = composeAlias(ctx, token, onError);
16
+ if (anchor || tag)
17
+ onError(token, 'ALIAS_PROPS', 'An alias node must not specify any properties');
18
18
  break;
19
19
  case 'scalar':
20
20
  case 'single-quoted-scalar':
21
21
  case 'double-quoted-scalar':
22
22
  case 'block-scalar':
23
- node = composeScalar.composeScalar(doc, token, anchor, tagName, onError);
23
+ node = composeScalar.composeScalar(ctx, token, tag, onError);
24
+ if (anchor)
25
+ node.anchor = anchor.source.substring(1);
24
26
  break;
25
27
  case 'block-map':
26
28
  case 'block-seq':
27
29
  case 'flow-collection':
28
- node = composeCollection.composeCollection(CN, doc, token, anchor, tagName, onError);
30
+ node = composeCollection.composeCollection(CN, ctx, token, tag, onError);
31
+ if (anchor)
32
+ node.anchor = anchor.source.substring(1);
29
33
  break;
30
34
  default:
31
35
  console.log(token);
@@ -41,28 +45,27 @@ function composeNode(doc, token, props, onError) {
41
45
  }
42
46
  return node;
43
47
  }
44
- function composeEmptyNode(doc, offset, before, pos, { spaceBefore, comment, anchor, tagName }, onError) {
48
+ function composeEmptyNode(ctx, offset, before, pos, { spaceBefore, comment, anchor, tag }, onError) {
45
49
  const token = {
46
50
  type: 'scalar',
47
51
  offset: utilEmptyScalarPosition.emptyScalarPosition(offset, before, pos),
48
52
  indent: -1,
49
53
  source: ''
50
54
  };
51
- const node = composeScalar.composeScalar(doc, token, anchor, tagName, onError);
55
+ const node = composeScalar.composeScalar(ctx, token, tag, onError);
56
+ if (anchor)
57
+ node.anchor = anchor.source.substring(1);
52
58
  if (spaceBefore)
53
59
  node.spaceBefore = true;
54
60
  if (comment)
55
61
  node.comment = comment;
56
62
  return node;
57
63
  }
58
- function composeAlias(doc, { offset, source, end }, onError) {
59
- const name = source.substring(1);
60
- const src = doc.anchors.getNode(name);
61
- if (!src)
62
- onError(offset, `Aliased anchor not found: ${name}`);
63
- const alias = new Alias.Alias(src);
64
- const re = resolveEnd.resolveEnd(end, offset + source.length, doc.options.strict, onError);
65
- alias.range = [offset, re.offset];
64
+ function composeAlias({ options }, { offset, source, end }, onError) {
65
+ const alias = new Alias.Alias(source.substring(1));
66
+ const valueEnd = offset + source.length;
67
+ const re = resolveEnd.resolveEnd(end, valueEnd, options.strict, onError);
68
+ alias.range = [offset, valueEnd, re.offset];
66
69
  if (re.comment)
67
70
  alias.comment = re.comment;
68
71
  return alias;
@@ -1,4 +1,5 @@
1
- import type { Document } from '../doc/Document.js';
2
1
  import { Scalar } from '../nodes/Scalar.js';
3
- import type { BlockScalar, FlowScalar } from '../parse/tokens.js';
4
- export declare function composeScalar(doc: Document.Parsed, token: FlowScalar | BlockScalar, anchor: string | null, tagName: string | null, onError: (offset: number, message: string) => void): Scalar.Parsed;
2
+ import type { BlockScalar, FlowScalar, SourceToken } from '../parse/cst.js';
3
+ import type { ComposeContext } from './compose-node.js';
4
+ import type { ComposeErrorHandler } from './composer.js';
5
+ export declare function composeScalar(ctx: ComposeContext, token: FlowScalar | BlockScalar, tagToken: SourceToken | null, onError: ComposeErrorHandler): Scalar.Parsed;