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
@@ -0,0 +1,122 @@
1
+ import { Collection } from '../nodes/Collection.js';
2
+ import { isNode, isPair } from '../nodes/Node.js';
3
+ import { stringify } from './stringify.js';
4
+ import { addComment, stringifyComment } from './stringifyComment.js';
5
+
6
+ function stringifyCollection({ comment, flow, items }, ctx, { blockItem, flowChars, itemIndent, onChompKeep, onComment }) {
7
+ const { indent, indentStep } = ctx;
8
+ const inFlow = flow || ctx.inFlow;
9
+ if (inFlow)
10
+ itemIndent += indentStep;
11
+ ctx = Object.assign({}, ctx, { indent: itemIndent, inFlow, type: null });
12
+ let singleLineOutput = true;
13
+ let chompKeep = false; // flag for the preceding node's status
14
+ const nodes = items.reduce((nodes, item, i) => {
15
+ let comment = null;
16
+ if (isNode(item)) {
17
+ if (!chompKeep && item.spaceBefore)
18
+ nodes.push({ comment: true, str: '' });
19
+ let cb = item.commentBefore;
20
+ if (cb && chompKeep)
21
+ cb = cb.replace(/^\n+/, '');
22
+ if (cb) {
23
+ if (/^\n+$/.test(cb))
24
+ cb = cb.substring(1);
25
+ // This match will always succeed on a non-empty string
26
+ for (const line of cb.match(/^.*$/gm)) {
27
+ const str = line === ' ' ? '#' : line ? `#${line}` : '';
28
+ nodes.push({ comment: true, str });
29
+ }
30
+ }
31
+ if (item.comment) {
32
+ comment = item.comment;
33
+ singleLineOutput = false;
34
+ }
35
+ }
36
+ else if (isPair(item)) {
37
+ const ik = isNode(item.key) ? item.key : null;
38
+ if (ik) {
39
+ if (!chompKeep && ik.spaceBefore)
40
+ nodes.push({ comment: true, str: '' });
41
+ let cb = ik.commentBefore;
42
+ if (cb && chompKeep)
43
+ cb = cb.replace(/^\n+/, '');
44
+ if (cb) {
45
+ if (/^\n+$/.test(cb))
46
+ cb = cb.substring(1);
47
+ // This match will always succeed on a non-empty string
48
+ for (const line of cb.match(/^.*$/gm)) {
49
+ const str = line === ' ' ? '#' : line ? `#${line}` : '';
50
+ nodes.push({ comment: true, str });
51
+ }
52
+ }
53
+ if (ik.comment)
54
+ singleLineOutput = false;
55
+ }
56
+ if (inFlow) {
57
+ const iv = isNode(item.value) ? item.value : null;
58
+ if (iv) {
59
+ if (iv.comment)
60
+ comment = iv.comment;
61
+ if (iv.comment || iv.commentBefore)
62
+ singleLineOutput = false;
63
+ }
64
+ else if (item.value == null && ik && ik.comment) {
65
+ comment = ik.comment;
66
+ }
67
+ }
68
+ }
69
+ chompKeep = false;
70
+ let str = stringify(item, ctx, () => (comment = null), () => (chompKeep = true));
71
+ if (inFlow && i < items.length - 1)
72
+ str += ',';
73
+ str = addComment(str, itemIndent, comment);
74
+ if (chompKeep && (comment || inFlow))
75
+ chompKeep = false;
76
+ nodes.push({ comment: false, str });
77
+ return nodes;
78
+ }, []);
79
+ let str;
80
+ if (nodes.length === 0) {
81
+ str = flowChars.start + flowChars.end;
82
+ }
83
+ else if (inFlow) {
84
+ const { start, end } = flowChars;
85
+ const strings = nodes.map(n => n.str);
86
+ let singleLineLength = 2;
87
+ for (const node of nodes) {
88
+ if (node.comment || node.str.includes('\n')) {
89
+ singleLineOutput = false;
90
+ break;
91
+ }
92
+ singleLineLength += node.str.length + 2;
93
+ }
94
+ if (!singleLineOutput ||
95
+ singleLineLength > Collection.maxFlowStringSingleLineLength) {
96
+ str = start;
97
+ for (const s of strings) {
98
+ str += s ? `\n${indentStep}${indent}${s}` : '\n';
99
+ }
100
+ str += `\n${indent}${end}`;
101
+ }
102
+ else {
103
+ str = `${start} ${strings.join(' ')} ${end}`;
104
+ }
105
+ }
106
+ else {
107
+ const strings = nodes.map(blockItem);
108
+ str = strings.shift() || '';
109
+ for (const s of strings)
110
+ str += s ? `\n${indent}${s}` : '\n';
111
+ }
112
+ if (comment) {
113
+ str += '\n' + stringifyComment(comment, indent);
114
+ if (onComment)
115
+ onComment();
116
+ }
117
+ else if (chompKeep && onChompKeep)
118
+ onChompKeep();
119
+ return str;
120
+ }
121
+
122
+ export { stringifyCollection };
@@ -0,0 +1,14 @@
1
+ const stringifyComment = (comment, indent) => /^\n+$/.test(comment)
2
+ ? comment.substring(1)
3
+ : comment.replace(/^(?!$)(?: $)?/gm, `${indent}#`);
4
+ function addComment(str, indent, comment) {
5
+ return !comment
6
+ ? str
7
+ : comment.includes('\n')
8
+ ? `${str}\n` + stringifyComment(comment, indent)
9
+ : str.endsWith(' ')
10
+ ? `${str}#${comment}`
11
+ : `${str} #${comment}`;
12
+ }
13
+
14
+ export { addComment, stringifyComment };
@@ -0,0 +1,64 @@
1
+ import { isNode } from '../nodes/Node.js';
2
+ import { createStringifyContext, stringify } from './stringify.js';
3
+ import { stringifyComment, addComment } from './stringifyComment.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(stringifyComment(doc.commentBefore, ''));
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(stringifyComment(doc.contents.commentBefore, ''));
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
+ let dc = doc.comment;
54
+ if (dc && chompKeep)
55
+ dc = dc.replace(/^\n+/, '');
56
+ if (dc) {
57
+ if ((!chompKeep || contentComment) && lines[lines.length - 1] !== '')
58
+ lines.push('');
59
+ lines.push(stringifyComment(dc, ''));
60
+ }
61
+ return lines.join('\n') + '\n';
62
+ }
63
+
64
+ export { stringifyDocument };
@@ -0,0 +1,111 @@
1
+ import { isCollection, isNode, isScalar, isSeq } from '../nodes/Node.js';
2
+ import { Scalar } from '../nodes/Scalar.js';
3
+ import { stringify } from './stringify.js';
4
+ import { addComment, stringifyComment } from './stringifyComment.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
+ vcb += `\n${stringifyComment(value.commentBefore, ctx.indent)}`;
64
+ valueComment = value.comment;
65
+ }
66
+ else if (value && typeof value === 'object') {
67
+ value = doc.createNode(value);
68
+ }
69
+ ctx.implicitKey = false;
70
+ if (!explicitKey && !keyComment && isScalar(value))
71
+ ctx.indentAtStart = str.length + 1;
72
+ chompKeep = false;
73
+ if (!indentSeq &&
74
+ indentStep.length >= 2 &&
75
+ !ctx.inFlow &&
76
+ !explicitKey &&
77
+ isSeq(value) &&
78
+ !value.flow &&
79
+ !value.tag &&
80
+ !value.anchor) {
81
+ // If indentSeq === false, consider '- ' as part of indentation where possible
82
+ ctx.indent = ctx.indent.substr(2);
83
+ }
84
+ let valueCommentDone = false;
85
+ const valueStr = stringify(value, ctx, () => (valueCommentDone = true), () => (chompKeep = true));
86
+ let ws = ' ';
87
+ if (vcb || keyComment) {
88
+ ws = `${vcb}\n${ctx.indent}`;
89
+ }
90
+ else if (!explicitKey && isCollection(value)) {
91
+ const flow = valueStr[0] === '[' || valueStr[0] === '{';
92
+ if (!flow || valueStr.includes('\n'))
93
+ ws = `\n${ctx.indent}`;
94
+ }
95
+ else if (valueStr[0] === '\n')
96
+ ws = '';
97
+ if (ctx.inFlow) {
98
+ if (valueCommentDone && onComment)
99
+ onComment();
100
+ return str + ws + valueStr;
101
+ }
102
+ else {
103
+ if (valueCommentDone)
104
+ valueComment = null;
105
+ if (chompKeep && !valueComment && onChompKeep)
106
+ onChompKeep();
107
+ return addComment(str + ws + valueStr, ctx.indent, valueComment);
108
+ }
109
+ }
110
+
111
+ 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
+ indicator: 'doc-start',
18
+ next: value || (end === null || end === void 0 ? void 0 : end[0]),
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 {};