yaml 1.5.1 → 1.7.2

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 (62) hide show
  1. package/browser/dist/Document.js +25 -5
  2. package/browser/dist/cst/CollectionItem.js +27 -6
  3. package/browser/dist/cst/Document.js +9 -1
  4. package/browser/dist/cst/FlowCollection.js +9 -1
  5. package/browser/dist/cst/Node.js +7 -4
  6. package/browser/dist/cst/PlainValue.js +1 -1
  7. package/browser/dist/cst/source-utils.js +179 -0
  8. package/browser/dist/errors.js +36 -3
  9. package/browser/dist/index.js +5 -4
  10. package/browser/dist/schema/Alias.js +1 -1
  11. package/browser/dist/schema/Merge.js +1 -1
  12. package/browser/dist/schema/Pair.js +17 -2
  13. package/browser/dist/schema/index.js +4 -3
  14. package/browser/dist/schema/parseMap.js +17 -4
  15. package/browser/dist/schema/parseSeq.js +22 -6
  16. package/browser/dist/schema/parseUtils.js +49 -0
  17. package/browser/dist/stringify.js +4 -3
  18. package/browser/dist/tags/failsafe/map.js +2 -2
  19. package/browser/dist/{deprecation.js → warnings.js} +13 -7
  20. package/browser/map.js +1 -1
  21. package/browser/pair.js +1 -1
  22. package/browser/scalar.js +1 -1
  23. package/browser/schema.js +1 -1
  24. package/browser/seq.js +1 -1
  25. package/browser/types/binary.js +1 -1
  26. package/browser/types/omap.js +1 -1
  27. package/browser/types/pairs.js +1 -1
  28. package/browser/types/set.js +1 -1
  29. package/browser/types/timestamp.js +1 -1
  30. package/dist/Document.js +32 -12
  31. package/dist/cst/CollectionItem.js +27 -6
  32. package/dist/cst/Document.js +9 -1
  33. package/dist/cst/FlowCollection.js +9 -1
  34. package/dist/cst/Node.js +7 -4
  35. package/dist/cst/PlainValue.js +1 -1
  36. package/dist/cst/source-utils.js +178 -0
  37. package/dist/errors.js +37 -3
  38. package/dist/index.js +5 -4
  39. package/dist/schema/Alias.js +1 -1
  40. package/dist/schema/Merge.js +4 -5
  41. package/dist/schema/Pair.js +19 -2
  42. package/dist/schema/index.js +4 -3
  43. package/dist/schema/parseMap.js +20 -5
  44. package/dist/schema/parseSeq.js +19 -6
  45. package/dist/schema/parseUtils.js +54 -6
  46. package/dist/stringify.js +7 -4
  47. package/dist/tags/yaml-1.1/omap.js +3 -5
  48. package/dist/tags/yaml-1.1/set.js +3 -1
  49. package/dist/{deprecation.js → warnings.js} +12 -7
  50. package/map.js +1 -1
  51. package/package.json +18 -16
  52. package/pair.js +1 -1
  53. package/scalar.js +1 -1
  54. package/schema.js +1 -1
  55. package/seq.js +1 -1
  56. package/types/binary.js +1 -1
  57. package/types/omap.js +1 -1
  58. package/types/pairs.js +1 -1
  59. package/types/set.js +1 -1
  60. package/types/timestamp.js +1 -1
  61. package/browser/dist/cst/getLinePos.js +0 -79
  62. package/dist/cst/getLinePos.js +0 -79
@@ -52,6 +52,7 @@ function () {
52
52
  this.commentBefore = null;
53
53
  this.comment = null;
54
54
  this.contents = null;
55
+ this.directivesEndMarker = null;
55
56
  this.errors = [];
56
57
  this.options = options;
57
58
  this.schema = null;
@@ -139,8 +140,20 @@ function () {
139
140
  }
140
141
  }, {
141
142
  key: "setSchema",
142
- value: function setSchema() {
143
- if (!this.schema) this.schema = new _schema.default(Object.assign({}, this.getDefaults(), this.options));
143
+ value: function setSchema(id, customTags) {
144
+ if (!id && !customTags && this.schema) return;
145
+ if (typeof id === 'number') id = id.toFixed(1);
146
+
147
+ if (id === '1.0' || id === '1.1' || id === '1.2') {
148
+ if (this.version) this.version = id;else this.options.version = id;
149
+ delete this.options.schema;
150
+ } else if (id && typeof id === 'string') {
151
+ this.options.schema = id;
152
+ }
153
+
154
+ if (Array.isArray(customTags)) this.options.customTags = customTags;
155
+ var opt = Object.assign({}, this.getDefaults(), this.options);
156
+ this.schema = new _schema.default(opt);
144
157
  }
145
158
  }, {
146
159
  key: "parse",
@@ -151,6 +164,7 @@ function () {
151
164
  directives = _node$directives === void 0 ? [] : _node$directives,
152
165
  _node$contents = node.contents,
153
166
  contents = _node$contents === void 0 ? [] : _node$contents,
167
+ directivesEndMarker = node.directivesEndMarker,
154
168
  error = node.error,
155
169
  valueRange = node.valueRange;
156
170
 
@@ -160,6 +174,7 @@ function () {
160
174
  }
161
175
 
162
176
  this.parseDirectives(directives, prevDoc);
177
+ if (directivesEndMarker) this.directivesEndMarker = true;
163
178
  this.range = valueRange ? [valueRange.start, valueRange.end] : null;
164
179
  this.setSchema();
165
180
  this.anchors._cstAliases = [];
@@ -719,7 +734,6 @@ function () {
719
734
  if (this.errors.length > 0) throw new Error('Document with errors cannot be stringified');
720
735
  this.setSchema();
721
736
  var lines = [];
722
- if (this.commentBefore) lines.push(this.commentBefore.replace(/^/gm, '#'), '');
723
737
  var hasDirectives = false;
724
738
 
725
739
  if (this.version) {
@@ -745,7 +759,13 @@ function () {
745
759
  hasDirectives = true;
746
760
  }
747
761
  });
748
- if (hasDirectives) lines.push('---');
762
+ if (hasDirectives || this.directivesEndMarker) lines.push('---');
763
+
764
+ if (this.commentBefore) {
765
+ if (hasDirectives || !this.directivesEndMarker) lines.unshift('');
766
+ lines.unshift(this.commentBefore.replace(/^/gm, '#'));
767
+ }
768
+
749
769
  var ctx = {
750
770
  anchors: {},
751
771
  doc: this,
@@ -756,7 +776,7 @@ function () {
756
776
 
757
777
  if (this.contents) {
758
778
  if (this.contents instanceof _Node.default) {
759
- if (this.contents.spaceBefore && hasDirectives) lines.push('');
779
+ if (this.contents.spaceBefore && (hasDirectives || this.directivesEndMarker)) lines.push('');
760
780
  if (this.contents.commentBefore) lines.push(this.contents.commentBefore.replace(/^/gm, '#')); // top-level block scalars need to be indented if followed by a comment
761
781
 
762
782
  ctx.forceBlockIndent = !!this.comment;
@@ -63,12 +63,15 @@ function (_Node) {
63
63
  var offset = _Node2.default.endOfWhiteSpace(src, start + 1);
64
64
 
65
65
  var ch = src[offset];
66
+ var inlineComment = ch === '#';
67
+ var comments = [];
68
+ var blankLine = null;
66
69
 
67
70
  while (ch === '\n' || ch === '#') {
68
71
  if (ch === '#') {
69
72
  var _end = _Node2.default.endOfLine(src, offset + 1);
70
73
 
71
- this.props.push(new _Range.default(offset, _end));
74
+ comments.push(new _Range.default(offset, _end));
72
75
  offset = _end;
73
76
  } else {
74
77
  atLineStart = true;
@@ -76,13 +79,11 @@ function (_Node) {
76
79
 
77
80
  var wsEnd = _Node2.default.endOfWhiteSpace(src, lineStart);
78
81
 
79
- if (src[wsEnd] === '\n') {
80
- var blankLine = new _BlankLine.default();
82
+ if (src[wsEnd] === '\n' && comments.length === 0) {
83
+ blankLine = new _BlankLine.default();
81
84
  lineStart = blankLine.parse({
82
85
  src: src
83
86
  }, lineStart);
84
- var items = context.parent.items || context.parent.contents;
85
- items.push(blankLine);
86
87
  }
87
88
 
88
89
  offset = _Node2.default.endOfIndent(src, lineStart);
@@ -99,11 +100,31 @@ function (_Node) {
99
100
  lineStart: lineStart,
100
101
  parent: this
101
102
  }, offset);
102
- if (this.node) offset = this.node.range.end;
103
103
  } else if (ch && lineStart > start + 1) {
104
104
  offset = lineStart - 1;
105
105
  }
106
106
 
107
+ if (this.node) {
108
+ if (blankLine) {
109
+ // Only blank lines preceding non-empty nodes are captured. Note that
110
+ // this means that collection item range start indices do not always
111
+ // increase monotonically. -- eemeli/yaml#126
112
+ var items = context.parent.items || context.parent.contents;
113
+ if (items) items.push(blankLine);
114
+ }
115
+
116
+ if (comments.length) Array.prototype.push.apply(this.props, comments);
117
+ offset = this.node.range.end;
118
+ } else {
119
+ if (inlineComment) {
120
+ var c = comments[0];
121
+ this.props.push(c);
122
+ offset = c.end;
123
+ } else {
124
+ offset = _Node2.default.endOfLine(src, start + 1);
125
+ }
126
+ }
127
+
107
128
  var end = this.node ? this.node.valueRange.end : offset;
108
129
  this.valueRange = new _Range.default(start, end);
109
130
  return offset;
@@ -56,6 +56,8 @@ function (_Node) {
56
56
  _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Document).call(this, _constants.Type.DOCUMENT));
57
57
  _this.directives = null;
58
58
  _this.contents = null;
59
+ _this.directivesEndMarker = null;
60
+ _this.documentEndMarker = null;
59
61
  return _this;
60
62
  }
61
63
 
@@ -125,7 +127,10 @@ function (_Node) {
125
127
  }
126
128
  }
127
129
 
128
- if (src[offset]) return offset + 3;
130
+ if (src[offset]) {
131
+ this.directivesEndMarker = new _Range.default(offset, offset + 3);
132
+ return offset + 3;
133
+ }
129
134
 
130
135
  if (hasDirectives) {
131
136
  this.error = new _errors.YAMLSemanticError(this, 'Missing directives-end indicator line');
@@ -214,6 +219,7 @@ function (_Node) {
214
219
  this.valueRange.end = offset;
215
220
 
216
221
  if (src[offset]) {
222
+ this.documentEndMarker = new _Range.default(offset, offset + 3);
217
223
  offset += 3;
218
224
 
219
225
  if (src[offset]) {
@@ -269,9 +275,11 @@ function (_Node) {
269
275
  this.directives.forEach(function (node) {
270
276
  offset = node.setOrigRanges(cr, offset);
271
277
  });
278
+ if (this.directivesEndMarker) offset = this.directivesEndMarker.setOrigRange(cr, offset);
272
279
  this.contents.forEach(function (node) {
273
280
  offset = node.setOrigRanges(cr, offset);
274
281
  });
282
+ if (this.documentEndMarker) offset = this.documentEndMarker.setOrigRange(cr, offset);
275
283
  return offset;
276
284
  }
277
285
  }, {
@@ -94,7 +94,15 @@ function (_Node) {
94
94
  }
95
95
 
96
96
  offset = _Node2.default.endOfIndent(src, lineStart);
97
- if (offset - lineStart <= indent) this.error = new _errors.YAMLSemanticError(this, 'Insufficient indentation in flow collection');
97
+
98
+ if (offset <= lineStart + indent) {
99
+ char = src[offset];
100
+
101
+ if (offset < lineStart + indent || char !== ']' && char !== '}') {
102
+ var msg = 'Insufficient indentation in flow collection';
103
+ this.error = new _errors.YAMLSemanticError(this, msg);
104
+ }
105
+ }
98
106
  }
99
107
  break;
100
108
 
@@ -15,7 +15,7 @@ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/creat
15
15
 
16
16
  var _constants = require("../constants");
17
17
 
18
- var _getLinePos = _interopRequireDefault(require("./getLinePos"));
18
+ var _sourceUtils = require("./source-utils");
19
19
 
20
20
  var _Range = _interopRequireDefault(require("./Range"));
21
21
 
@@ -205,7 +205,10 @@ function () {
205
205
 
206
206
  function Node(type, props, context) {
207
207
  (0, _classCallCheck2.default)(this, Node);
208
- this.context = context || null;
208
+ Object.defineProperty(this, 'context', {
209
+ value: context || null,
210
+ writable: true
211
+ });
209
212
  this.error = null;
210
213
  this.range = null;
211
214
  this.valueRange = null;
@@ -337,9 +340,9 @@ function () {
337
340
  key: "rangeAsLinePos",
338
341
  get: function get() {
339
342
  if (!this.range || !this.context) return undefined;
340
- var start = (0, _getLinePos.default)(this.range.start, this.context.root);
343
+ var start = (0, _sourceUtils.getLinePos)(this.range.start, this.context.root);
341
344
  if (!start) return undefined;
342
- var end = (0, _getLinePos.default)(this.range.end, this.context.root);
345
+ var end = (0, _sourceUtils.getLinePos)(this.range.end, this.context.root);
343
346
  return {
344
347
  start: start,
345
348
  end: end
@@ -168,7 +168,7 @@ function (_Node) {
168
168
  while (ch && ch !== '\n') {
169
169
  if (inFlow && (ch === '[' || ch === ']' || ch === '{' || ch === '}' || ch === ',')) break;
170
170
  var next = src[offset + 1];
171
- if (ch === ':' && (next === '\n' || next === '\t' || next === ' ' || inFlow && next === ',')) break;
171
+ if (ch === ':' && (!next || next === '\n' || next === '\t' || next === ' ' || inFlow && next === ',')) break;
172
172
  if ((ch === ' ' || ch === '\t') && next === '#') break;
173
173
  offset += 1;
174
174
  ch = next;
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getLinePos = getLinePos;
7
+ exports.getLine = getLine;
8
+ exports.getPrettyContext = getPrettyContext;
9
+
10
+ function findLineStarts(src) {
11
+ var ls = [0];
12
+ var offset = src.indexOf('\n');
13
+
14
+ while (offset !== -1) {
15
+ offset += 1;
16
+ ls.push(offset);
17
+ offset = src.indexOf('\n', offset);
18
+ }
19
+
20
+ return ls;
21
+ }
22
+
23
+ function getSrcInfo(cst) {
24
+ var lineStarts, src;
25
+
26
+ if (typeof cst === 'string') {
27
+ lineStarts = findLineStarts(cst);
28
+ src = cst;
29
+ } else {
30
+ if (Array.isArray(cst)) cst = cst[0];
31
+
32
+ if (cst && cst.context) {
33
+ if (!cst.lineStarts) cst.lineStarts = findLineStarts(cst.context.src);
34
+ lineStarts = cst.lineStarts;
35
+ src = cst.context.src;
36
+ }
37
+ }
38
+
39
+ return {
40
+ lineStarts: lineStarts,
41
+ src: src
42
+ };
43
+ }
44
+ /**
45
+ * @typedef {Object} LinePos - One-indexed position in the source
46
+ * @property {number} line
47
+ * @property {number} col
48
+ */
49
+
50
+ /**
51
+ * Determine the line/col position matching a character offset.
52
+ *
53
+ * Accepts a source string or a CST document as the second parameter. With
54
+ * the latter, starting indices for lines are cached in the document as
55
+ * `lineStarts: number[]`.
56
+ *
57
+ * Returns a one-indexed `{ line, col }` location if found, or
58
+ * `undefined` otherwise.
59
+ *
60
+ * @param {number} offset
61
+ * @param {string|Document|Document[]} cst
62
+ * @returns {?LinePos}
63
+ */
64
+
65
+
66
+ function getLinePos(offset, cst) {
67
+ if (typeof offset !== 'number' || offset < 0) return null;
68
+
69
+ var _getSrcInfo = getSrcInfo(cst),
70
+ lineStarts = _getSrcInfo.lineStarts,
71
+ src = _getSrcInfo.src;
72
+
73
+ if (!lineStarts || !src || offset > src.length) return null;
74
+
75
+ for (var i = 0; i < lineStarts.length; ++i) {
76
+ var start = lineStarts[i];
77
+
78
+ if (offset < start) {
79
+ return {
80
+ line: i,
81
+ col: offset - lineStarts[i - 1] + 1
82
+ };
83
+ }
84
+
85
+ if (offset === start) return {
86
+ line: i + 1,
87
+ col: 1
88
+ };
89
+ }
90
+
91
+ var line = lineStarts.length;
92
+ return {
93
+ line: line,
94
+ col: offset - lineStarts[line - 1] + 1
95
+ };
96
+ }
97
+ /**
98
+ * Get a specified line from the source.
99
+ *
100
+ * Accepts a source string or a CST document as the second parameter. With
101
+ * the latter, starting indices for lines are cached in the document as
102
+ * `lineStarts: number[]`.
103
+ *
104
+ * Returns the line as a string if found, or `null` otherwise.
105
+ *
106
+ * @param {number} line One-indexed line number
107
+ * @param {string|Document|Document[]} cst
108
+ * @returns {?string}
109
+ */
110
+
111
+
112
+ function getLine(line, cst) {
113
+ var _getSrcInfo2 = getSrcInfo(cst),
114
+ lineStarts = _getSrcInfo2.lineStarts,
115
+ src = _getSrcInfo2.src;
116
+
117
+ if (!lineStarts || !(line >= 1) || line > lineStarts.length) return null;
118
+ var start = lineStarts[line - 1];
119
+ var end = lineStarts[line]; // undefined for last line; that's ok for slice()
120
+
121
+ while (end && end > start && src[end - 1] === '\n') {
122
+ --end;
123
+ }
124
+
125
+ return src.slice(start, end);
126
+ }
127
+ /**
128
+ * Pretty-print the starting line from the source indicated by the range `pos`
129
+ *
130
+ * Trims output to `maxWidth` chars while keeping the starting column visible,
131
+ * using `…` at either end to indicate dropped characters.
132
+ *
133
+ * Returns a two-line string (or `null`) with `\n` as separator; the second line
134
+ * will hold appropriately indented `^` marks indicating the column range.
135
+ *
136
+ * @param {Object} pos
137
+ * @param {LinePos} pos.start
138
+ * @param {LinePos} [pos.end]
139
+ * @param {string|Document|Document[]*} cst
140
+ * @param {number} [maxWidth=80]
141
+ * @returns {?string}
142
+ */
143
+
144
+
145
+ function getPrettyContext(_ref, cst) {
146
+ var start = _ref.start,
147
+ end = _ref.end;
148
+ var maxWidth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 80;
149
+ var src = getLine(start.line, cst);
150
+ if (!src) return null;
151
+ var col = start.col;
152
+
153
+ if (src.length > maxWidth) {
154
+ if (col <= maxWidth - 10) {
155
+ src = src.substr(0, maxWidth - 1) + '…';
156
+ } else {
157
+ var halfWidth = Math.round(maxWidth / 2);
158
+ if (src.length > col + halfWidth) src = src.substr(0, col + halfWidth - 1) + '…';
159
+ col -= src.length - maxWidth;
160
+ src = '…' + src.substr(1 - maxWidth);
161
+ }
162
+ }
163
+
164
+ var errLen = 1;
165
+ var errEnd = '';
166
+
167
+ if (end) {
168
+ if (end.line === start.line && col + (end.col - start.col) <= maxWidth + 1) {
169
+ errLen = end.col - start.col;
170
+ } else {
171
+ errLen = Math.min(src.length + 1, maxWidth) - col;
172
+ errEnd = '…';
173
+ }
174
+ }
175
+
176
+ var offset = col > 1 ? ' '.repeat(col - 1) : '';
177
+ var err = '^'.repeat(errLen);
178
+ return "".concat(src, "\n").concat(offset).concat(err).concat(errEnd);
179
+ }
@@ -21,6 +21,10 @@ var _wrapNativeSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/w
21
21
 
22
22
  var _Node = _interopRequireDefault(require("./cst/Node"));
23
23
 
24
+ var _sourceUtils = require("./cst/source-utils");
25
+
26
+ var _Range = _interopRequireDefault(require("./cst/Range"));
27
+
24
28
  var YAMLError =
25
29
  /*#__PURE__*/
26
30
  function (_Error) {
@@ -41,12 +45,41 @@ function (_Error) {
41
45
  (0, _createClass2.default)(YAMLError, [{
42
46
  key: "makePretty",
43
47
  value: function makePretty() {
44
- if (this.source) {
45
- this.nodeType = this.source.type;
48
+ if (!this.source) return;
49
+ this.nodeType = this.source.type;
50
+ var cst = this.source.context && this.source.context.root;
51
+
52
+ if (typeof this.offset === 'number') {
53
+ this.range = new _Range.default(this.offset, this.offset + 1);
54
+ var start = cst && (0, _sourceUtils.getLinePos)(this.offset, cst);
55
+
56
+ if (start) {
57
+ var end = {
58
+ line: start.line,
59
+ col: start.col + 1
60
+ };
61
+ this.linePos = {
62
+ start: start,
63
+ end: end
64
+ };
65
+ }
66
+
67
+ delete this.offset;
68
+ } else {
46
69
  this.range = this.source.range;
47
70
  this.linePos = this.source.rangeAsLinePos;
48
- delete this.source;
49
71
  }
72
+
73
+ if (this.linePos) {
74
+ var _this$linePos$start = this.linePos.start,
75
+ line = _this$linePos$start.line,
76
+ col = _this$linePos$start.col;
77
+ this.message += " at line ".concat(line, ", column ").concat(col);
78
+ var ctx = cst && (0, _sourceUtils.getPrettyContext)(this.linePos, cst);
79
+ if (ctx) this.message += ":\n\n".concat(ctx, "\n");
80
+ }
81
+
82
+ delete this.source;
50
83
  }
51
84
  }]);
52
85
  return YAMLError;
@@ -23,7 +23,8 @@ var _errors = require("./errors");
23
23
 
24
24
  var _schema = _interopRequireDefault(require("./schema"));
25
25
 
26
- /* global console */
26
+ var _warnings = require("./warnings");
27
+
27
28
  var defaultOptions = {
28
29
  anchorPrefix: 'a',
29
30
  customTags: null,
@@ -34,6 +35,7 @@ var defaultOptions = {
34
35
  maxAliasCount: 100,
35
36
  prettyErrors: false,
36
37
  // TODO Set true in v2
38
+ simpleKeys: false,
37
39
  version: '1.2'
38
40
  };
39
41
 
@@ -110,10 +112,9 @@ function parseDocument(src, options) {
110
112
  }
111
113
 
112
114
  function parse(src, options) {
113
- var doc = parseDocument(src, options); // eslint-disable-next-line no-console
114
-
115
+ var doc = parseDocument(src, options);
115
116
  doc.warnings.forEach(function (warning) {
116
- return console.warn(warning);
117
+ return (0, _warnings.warn)(warning);
117
118
  });
118
119
  if (doc.errors.length > 0) throw doc.errors[0];
119
120
  return doc.toJSON();
@@ -119,7 +119,7 @@ function (_Node) {
119
119
  return a.node === _this2.source;
120
120
  });
121
121
 
122
- if (!anchor || !anchor.res) {
122
+ if (!anchor || anchor.res === undefined) {
123
123
  var msg = 'This should not happen: Alias anchor was not resolved?';
124
124
  if (this.cstNode) throw new _errors.YAMLReferenceError(this.cstNode, msg);else throw new ReferenceError(msg);
125
125
  }
@@ -95,7 +95,7 @@ function (_Pair) {
95
95
  } else if (map instanceof Set) {
96
96
  map.add(key);
97
97
  } else {
98
- if (!map.hasOwnProperty(key)) map[key] = value;
98
+ if (!Object.prototype.hasOwnProperty.call(map, key)) map[key] = value;
99
99
  }
100
100
  }
101
101
  } catch (err) {
@@ -21,6 +21,8 @@ var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
21
21
 
22
22
  var _addComment = _interopRequireDefault(require("../addComment"));
23
23
 
24
+ var _constants = require("../constants");
25
+
24
26
  var _toJSON = _interopRequireDefault(require("../toJSON"));
25
27
 
26
28
  var _Collection = _interopRequireDefault(require("./Collection"));
@@ -87,10 +89,23 @@ function (_Node) {
87
89
  key: "toString",
88
90
  value: function toString(ctx, onComment, onChompKeep) {
89
91
  if (!ctx || !ctx.doc) return JSON.stringify(this);
92
+ var simpleKeys = ctx.doc.options.simpleKeys;
90
93
  var key = this.key,
91
94
  value = this.value;
92
95
  var keyComment = key instanceof _Node2.default && key.comment;
93
- var explicitKey = !key || keyComment || key instanceof _Collection.default;
96
+
97
+ if (simpleKeys) {
98
+ if (keyComment) {
99
+ throw new Error('With simple keys, key nodes cannot have comments');
100
+ }
101
+
102
+ if (key instanceof _Collection.default) {
103
+ var msg = 'With simple keys, collection cannot be used as a key value';
104
+ throw new Error(msg);
105
+ }
106
+ }
107
+
108
+ var explicitKey = !simpleKeys && (!key || keyComment || key instanceof _Collection.default || key.type === _constants.Type.BLOCK_FOLDED || key.type === _constants.Type.BLOCK_LITERAL);
94
109
  var _ctx = ctx,
95
110
  doc = _ctx.doc,
96
111
  indent = _ctx.indent;
@@ -106,7 +121,7 @@ function (_Node) {
106
121
  });
107
122
  str = (0, _addComment.default)(str, ctx.indent, keyComment);
108
123
 
109
- if (ctx.allNullValues) {
124
+ if (ctx.allNullValues && !simpleKeys) {
110
125
  if (this.comment) {
111
126
  str = (0, _addComment.default)(str, ctx.indent, this.comment);
112
127
  if (onComment) onComment();
@@ -15,7 +15,7 @@ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/creat
15
15
 
16
16
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
17
17
 
18
- var _deprecation = require("../deprecation");
18
+ var _warnings = require("../warnings");
19
19
 
20
20
  var _constants = require("../constants");
21
21
 
@@ -69,7 +69,7 @@ function () {
69
69
 
70
70
  if (!customTags && deprecatedCustomTags) {
71
71
  customTags = deprecatedCustomTags;
72
- (0, _deprecation.warnOptionDeprecation)('tags', 'customTags');
72
+ (0, _warnings.warnOptionDeprecation)('tags', 'customTags');
73
73
  }
74
74
 
75
75
  if (Array.isArray(customTags)) {
@@ -122,6 +122,7 @@ function () {
122
122
  (0, _createClass2.default)(Schema, [{
123
123
  key: "createNode",
124
124
  value: function createNode(value, wrapScalars, tag, ctx) {
125
+ if (value instanceof _Node.default) return value;
125
126
  var tagObj;
126
127
 
127
128
  if (tag) {
@@ -250,7 +251,7 @@ function () {
250
251
  key: "resolveNodeWithFallback",
251
252
  value: function resolveNodeWithFallback(doc, node, tagName) {
252
253
  var res = this.resolveNode(doc, node, tagName);
253
- if (node.hasOwnProperty('resolved')) return res;
254
+ if (Object.prototype.hasOwnProperty.call(node, 'resolved')) return res;
254
255
  var fallback = isMap(node) ? Schema.defaultTags.MAP : isSeq(node) ? Schema.defaultTags.SEQ : Schema.defaultTags.STR;
255
256
 
256
257
  if (fallback) {
@@ -25,6 +25,8 @@ var _parseUtils = require("./parseUtils");
25
25
 
26
26
  var _Alias = _interopRequireDefault(require("./Alias"));
27
27
 
28
+ var _Collection = _interopRequireDefault(require("./Collection"));
29
+
28
30
  function parseMap(doc, cst) {
29
31
  if (cst.type !== _constants.Type.MAP && cst.type !== _constants.Type.FLOW_MAP) {
30
32
  var msg = "A ".concat(cst.type, " node cannot be resolved as a mapping");
@@ -39,9 +41,11 @@ function parseMap(doc, cst) {
39
41
  var map = new _Map.default();
40
42
  map.items = items;
41
43
  (0, _parseUtils.resolveComments)(map, comments);
44
+ var hasCollectionKey = false;
42
45
 
43
46
  for (var i = 0; i < items.length; ++i) {
44
47
  var iKey = items[i].key;
48
+ if (iKey instanceof _Collection.default) hasCollectionKey = true;
45
49
 
46
50
  if (doc.schema.merge && iKey && iKey.value === _Merge.MERGE_KEY) {
47
51
  items[i] = new _Merge.default(items[i]);
@@ -63,7 +67,7 @@ function parseMap(doc, cst) {
63
67
  for (var j = i + 1; j < items.length; ++j) {
64
68
  var jKey = items[j].key;
65
69
 
66
- if (iKey === jKey || iKey && jKey && iKey.hasOwnProperty('value') && iKey.value === jKey.value) {
70
+ if (iKey === jKey || iKey && jKey && Object.prototype.hasOwnProperty.call(iKey, 'value') && iKey.value === jKey.value) {
67
71
  var _msg = "Map keys must be unique; \"".concat(iKey, "\" is repeated");
68
72
 
69
73
  doc.errors.push(new _errors.YAMLSemanticError(cst, _msg));
@@ -73,6 +77,11 @@ function parseMap(doc, cst) {
73
77
  }
74
78
  }
75
79
 
80
+ if (hasCollectionKey && !doc.options.mapAsMap) {
81
+ var warn = 'Keys with collection values will be stringified as YAML due to JS Object restrictions. Use mapAsMap: true to avoid this.';
82
+ doc.warnings.push(new _errors.YAMLWarning(cst, warn));
83
+ }
84
+
76
85
  cst.resolved = map;
77
86
  return map;
78
87
  }
@@ -246,7 +255,8 @@ function resolveFlowMapItems(doc, cst) {
246
255
  var item = cst.items[i];
247
256
 
248
257
  if (typeof item.char === 'string') {
249
- var char = item.char;
258
+ var char = item.char,
259
+ offset = item.offset;
250
260
 
251
261
  if (char === '?' && key === undefined && !explicitKey) {
252
262
  explicitKey = true;
@@ -286,7 +296,10 @@ function resolveFlowMapItems(doc, cst) {
286
296
  continue;
287
297
  }
288
298
 
289
- doc.errors.push(new _errors.YAMLSyntaxError(cst, "Flow map contains an unexpected ".concat(char)));
299
+ var msg = "Flow map contains an unexpected ".concat(char);
300
+ var err = new _errors.YAMLSyntaxError(cst, msg);
301
+ err.offset = offset;
302
+ doc.errors.push(err);
290
303
  } else if (item.type === _constants.Type.BLANK_LINE) {
291
304
  comments.push({
292
305
  afterKey: !!key,
@@ -310,7 +323,7 @@ function resolveFlowMapItems(doc, cst) {
310
323
  }
311
324
  }
312
325
 
313
- if (cst.items[cst.items.length - 1].char !== '}') doc.errors.push(new _errors.YAMLSemanticError(cst, 'Expected flow map to end with }'));
326
+ (0, _parseUtils.checkFlowCollectionEnd)(doc.errors, cst);
314
327
  if (key !== undefined) items.push(new _Pair.default(key));
315
328
  return {
316
329
  comments: comments,