Socket
Socket
Sign inDemoInstall

yaml

Package Overview
Dependencies
0
Maintainers
1
Versions
85
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.10.0 to 2.0.0-0

browser/dist/parse-6e806192.js

171

browser/dist/index.js

@@ -1,6 +0,5 @@

import { d as defaultTagPrefix, _ as _createForOfIteratorHelper, a as _typeof, b as _createClass, c as _classCallCheck, e as _defineProperty, Y as YAMLSyntaxError, T as Type, f as YAMLWarning, g as YAMLSemanticError, h as _slicedToArray, i as YAMLError, j as _inherits, k as _createSuper } from './PlainValue-ff5147c6.js';
import { parse as parse$1 } from './parse-cst.js';
import { b as binaryOptions, a as boolOptions, i as intOptions, n as nullOptions, s as strOptions, N as Node, P as Pair, S as Scalar, c as stringifyString, A as Alias, Y as YAMLSeq, d as YAMLMap, M as Merge, C as Collection, r as resolveNode, e as isEmptyPath, t as toJSON, f as addComment } from './resolveSeq-04825f30.js';
import { S as Schema } from './Schema-2bf2c74e.js';
import { w as warn } from './warnings-0e4b70d3.js';
import { d as defaultTagPrefix, _ as _typeof, a as _createClass, b as _classCallCheck, c as _defineProperty, e as _createForOfIteratorHelper, Y as YAMLSyntaxError, T as Type, f as YAMLWarning, g as YAMLSemanticError, h as _slicedToArray, i as YAMLError, j as _inherits, k as _createSuper } from './PlainValue-6b68dc0e.js';
import { D as Document$2, p as parse$1 } from './parse-6e806192.js';
import { b as binaryOptions, a as boolOptions, i as intOptions, n as nullOptions, s as strOptions, N as Node, P as Pair, S as Scalar, c as stringifyString, A as Alias, Y as YAMLSeq, d as YAMLMap, M as Merge, C as Collection, r as resolveNode, e as createNode, f as isEmptyPath, g as collectionFromPath, t as toJSON, h as addComment } from './resolveSeq-3477c430.js';
import { S as Schema } from './Schema-d14032c2.js';

@@ -17,4 +16,3 @@ var defaultOptions = {

maxAliasCount: 100,
prettyErrors: false,
// TODO Set true in v2
prettyErrors: true,
simpleKeys: false,

@@ -91,2 +89,3 @@ version: '1.2'

merge: false,
resolveKnownTags: true,
tagPrefixes: [{

@@ -150,6 +149,6 @@ handle: '!',

if (item instanceof Scalar) {
obj = item.value; // TODO: deprecate/remove class check
obj = item.value;
var _match = tags.filter(function (t) {
return t.identify && t.identify(obj) || t.class && obj instanceof t.class;
return t.identify && t.identify(obj);
});

@@ -199,36 +198,12 @@

function stringify(item, ctx, onComment, onChompKeep) {
var _ctx$doc = ctx.doc,
anchors = _ctx$doc.anchors,
schema = _ctx$doc.schema;
var schema = ctx.doc.schema;
var tagObj;
if (!(item instanceof Node)) {
var createCtx = {
aliasNodes: [],
item = ctx.doc.createNode(item, {
onTagObj: function onTagObj(o) {
return tagObj = o;
},
prevObjects: new Map()
};
item = schema.createNode(item, true, null, createCtx);
var _iterator = _createForOfIteratorHelper(createCtx.aliasNodes),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var alias = _step.value;
alias.source = alias.source.node;
var name = anchors.getName(alias.source);
if (!name) {
name = anchors.newName();
anchors.map[name] = alias.source;
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
wrapScalars: true
});
}

@@ -589,3 +564,3 @@

var Document = /*#__PURE__*/function () {
function Document(options) {
function Document(value, options) {
_classCallCheck(this, Document);

@@ -596,3 +571,2 @@

this.comment = null;
this.contents = null;
this.directivesEndMarker = null;

@@ -605,2 +579,11 @@ this.errors = [];

this.warnings = [];
if (value === undefined) {
// note that this.schema is left as null here
this.contents = null;
} else if (value instanceof Document$2) {
this.parse(value);
} else {
this.contents = this.createNode(value);
}
}

@@ -621,2 +604,50 @@

}, {
key: "createNode",
value: function createNode$1(value) {
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
onTagObj = _ref.onTagObj,
tag = _ref.tag,
wrapScalars = _ref.wrapScalars;
this.setSchema();
var aliasNodes = [];
var ctx = {
onAlias: function onAlias(source) {
var alias = new Alias(source);
aliasNodes.push(alias);
return alias;
},
onTagObj: onTagObj,
prevObjects: new Map(),
schema: this.schema,
wrapScalars: wrapScalars !== false
};
var node = createNode(value, tag, ctx);
for (var _i = 0, _aliasNodes = aliasNodes; _i < _aliasNodes.length; _i++) {
var alias = _aliasNodes[_i];
// With circular references, the source node is only resolved after all of
// its child nodes are. This is why anchors are set only after all of the
// nodes have been created.
alias.source = alias.source.node;
var name = this.anchors.getName(alias.source);
if (!name) {
name = this.anchors.newName();
this.anchors.map[name] = alias.source;
}
}
return node;
}
}, {
key: "createPair",
value: function createPair(key, value) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var k = this.createNode(key, options);
var v = this.createNode(value, options);
return new Pair(k, v);
}
}, {
key: "delete",

@@ -669,4 +700,9 @@ value: function _delete(key) {

value: function set(key, value) {
assertCollection(this.contents);
this.contents.set(key, value);
if (this.contents == null) {
this.setSchema();
this.contents = collectionFromPath(this.schema, [key], value);
} else {
assertCollection(this.contents);
this.contents.set(key, value);
}
}

@@ -676,3 +712,6 @@ }, {

value: function setIn(path, value) {
if (isEmptyPath(path)) this.contents = value;else {
if (isEmptyPath(path)) this.contents = value;else if (this.contents == null) {
this.setSchema();
this.contents = collectionFromPath(this.schema, path, value);
} else {
assertCollection(this.contents);

@@ -761,3 +800,3 @@ this.contents.setIn(path, value);

return listTagNames(this.contents).filter(function (t) {
return t.indexOf(Schema.defaultPrefix) !== 0;
return t.indexOf(defaultTagPrefix) !== 0;
});

@@ -861,5 +900,5 @@ }

var tagNames = this.listNonDefaultTags();
this.tagPrefixes.forEach(function (_ref) {
var handle = _ref.handle,
prefix = _ref.prefix;
this.tagPrefixes.forEach(function (_ref2) {
var handle = _ref2.handle,
prefix = _ref2.prefix;

@@ -907,3 +946,3 @@ if (tagNames.some(function (t) {

lines.push(addComment(body, '', contentComment));
} else if (this.contents !== undefined) {
} else {
lines.push(stringify(this.contents, ctx));

@@ -926,14 +965,18 @@ }

function createNode(value) {
var wrapScalars = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var tag = arguments.length > 2 ? arguments[2] : undefined;
/* global console, process, YAML_SILENCE_WARNINGS */
function warn(warning, type) {
if (typeof YAML_SILENCE_WARNINGS !== 'undefined' && YAML_SILENCE_WARNINGS) return;
if (tag === undefined && typeof wrapScalars === 'string') {
tag = wrapScalars;
wrapScalars = true;
}
if (typeof process !== 'undefined') {
if (process.env.YAML_SILENCE_WARNINGS) return; // This will throw in Jest if `warning` is an Error instance due to
// https://github.com/facebook/jest/issues/2549
var options = Object.assign({}, Document.defaults[defaultOptions.version], defaultOptions);
var schema = new Schema(options);
return schema.createNode(value, wrapScalars, tag);
if (process.emitWarning) {
process.emitWarning(warning, type);
return;
}
} // eslint-disable-next-line no-console
console.warn(type ? "".concat(type, ": ").concat(warning) : warning);
}

@@ -946,6 +989,6 @@

function Document(options) {
function Document(contents, options) {
_classCallCheck(this, Document);
return _super.call(this, Object.assign({}, defaultOptions, options));
return _super.call(this, contents, Object.assign({}, defaultOptions, options));
}

@@ -966,3 +1009,3 @@

var cstDoc = _step.value;
var doc = new Document$1(options);
var doc = new Document$1(undefined, options);
doc.parse(cstDoc, prev);

@@ -983,3 +1026,3 @@ stream.push(doc);

var cst = parse$1(src);
var doc = new Document$1(options).parse(cst[0]);
var doc = new Document$1(cst[0], options);

@@ -1004,9 +1047,7 @@ if (cst.length > 1) {

function stringify$1(value, options) {
var doc = new Document$1(options);
doc.contents = value;
return String(doc);
if (value === undefined) return '\n';
return new Document$1(value, options).toString();
}
var YAML = {
createNode: createNode,
defaultOptions: defaultOptions,

@@ -1013,0 +1054,0 @@ Document: Document$1,

@@ -1,1904 +0,2 @@

import { j as _inherits, k as _createSuper, c as _classCallCheck, T as Type, b as _createClass, R as Range, N as Node, g as YAMLSemanticError, l as _get, m as _getPrototypeOf, Y as YAMLSyntaxError, C as Char, e as _defineProperty, P as PlainValue } from './PlainValue-ff5147c6.js';
var BlankLine = /*#__PURE__*/function (_Node) {
_inherits(BlankLine, _Node);
var _super = _createSuper(BlankLine);
function BlankLine() {
_classCallCheck(this, BlankLine);
return _super.call(this, Type.BLANK_LINE);
}
/* istanbul ignore next */
_createClass(BlankLine, [{
key: "parse",
/**
* Parses a blank line from the source
*
* @param {ParseContext} context
* @param {number} start - Index of first \n character
* @returns {number} - Index of the character after this
*/
value: function parse(context, start) {
this.context = context;
this.range = new Range(start, start + 1);
return start + 1;
}
}, {
key: "includesTrailingLines",
get: function get() {
// This is never called from anywhere, but if it were,
// this is the value it should return.
return true;
}
}]);
return BlankLine;
}(Node);
var CollectionItem = /*#__PURE__*/function (_Node) {
_inherits(CollectionItem, _Node);
var _super = _createSuper(CollectionItem);
function CollectionItem(type, props) {
var _this;
_classCallCheck(this, CollectionItem);
_this = _super.call(this, type, props);
_this.node = null;
return _this;
}
_createClass(CollectionItem, [{
key: "parse",
/**
* @param {ParseContext} context
* @param {number} start - Index of first character
* @returns {number} - Index of the character after this
*/
value: function parse(context, start) {
this.context = context;
var parseNode = context.parseNode,
src = context.src;
var atLineStart = context.atLineStart,
lineStart = context.lineStart;
if (!atLineStart && this.type === Type.SEQ_ITEM) this.error = new YAMLSemanticError(this, 'Sequence items must not have preceding content on the same line');
var indent = atLineStart ? start - lineStart : context.indent;
var offset = Node.endOfWhiteSpace(src, start + 1);
var ch = src[offset];
var inlineComment = ch === '#';
var comments = [];
var blankLine = null;
while (ch === '\n' || ch === '#') {
if (ch === '#') {
var _end = Node.endOfLine(src, offset + 1);
comments.push(new Range(offset, _end));
offset = _end;
} else {
atLineStart = true;
lineStart = offset + 1;
var wsEnd = Node.endOfWhiteSpace(src, lineStart);
if (src[wsEnd] === '\n' && comments.length === 0) {
blankLine = new BlankLine();
lineStart = blankLine.parse({
src: src
}, lineStart);
}
offset = Node.endOfIndent(src, lineStart);
}
ch = src[offset];
}
if (Node.nextNodeIsIndented(ch, offset - (lineStart + indent), this.type !== Type.SEQ_ITEM)) {
this.node = parseNode({
atLineStart: atLineStart,
inCollection: false,
indent: indent,
lineStart: lineStart,
parent: this
}, offset);
} else if (ch && lineStart > start + 1) {
offset = lineStart - 1;
}
if (this.node) {
if (blankLine) {
// Only blank lines preceding non-empty nodes are captured. Note that
// this means that collection item range start indices do not always
// increase monotonically. -- eemeli/yaml#126
var items = context.parent.items || context.parent.contents;
if (items) items.push(blankLine);
}
if (comments.length) Array.prototype.push.apply(this.props, comments);
offset = this.node.range.end;
} else {
if (inlineComment) {
var c = comments[0];
this.props.push(c);
offset = c.end;
} else {
offset = Node.endOfLine(src, start + 1);
}
}
var end = this.node ? this.node.valueRange.end : offset;
this.valueRange = new Range(start, end);
return offset;
}
}, {
key: "setOrigRanges",
value: function setOrigRanges(cr, offset) {
offset = _get(_getPrototypeOf(CollectionItem.prototype), "setOrigRanges", this).call(this, cr, offset);
return this.node ? this.node.setOrigRanges(cr, offset) : offset;
}
}, {
key: "toString",
value: function toString() {
var src = this.context.src,
node = this.node,
range = this.range,
value = this.value;
if (value != null) return value;
var str = node ? src.slice(range.start, node.range.start) + String(node) : src.slice(range.start, range.end);
return Node.addStringTerminator(src, range.end, str);
}
}, {
key: "includesTrailingLines",
get: function get() {
return !!this.node && this.node.includesTrailingLines;
}
}]);
return CollectionItem;
}(Node);
var Comment = /*#__PURE__*/function (_Node) {
_inherits(Comment, _Node);
var _super = _createSuper(Comment);
function Comment() {
_classCallCheck(this, Comment);
return _super.call(this, Type.COMMENT);
}
/**
* Parses a comment line from the source
*
* @param {ParseContext} context
* @param {number} start - Index of first character
* @returns {number} - Index of the character after this scalar
*/
_createClass(Comment, [{
key: "parse",
value: function parse(context, start) {
this.context = context;
var offset = this.parseComment(start);
this.range = new Range(start, offset);
return offset;
}
}]);
return Comment;
}(Node);
function grabCollectionEndComments(node) {
var cnode = node;
while (cnode instanceof CollectionItem) {
cnode = cnode.node;
}
if (!(cnode instanceof Collection)) return null;
var len = cnode.items.length;
var ci = -1;
for (var i = len - 1; i >= 0; --i) {
var n = cnode.items[i];
if (n.type === Type.COMMENT) {
// Keep sufficiently indented comments with preceding node
var _n$context = n.context,
indent = _n$context.indent,
lineStart = _n$context.lineStart;
if (indent > 0 && n.range.start >= lineStart + indent) break;
ci = i;
} else if (n.type === Type.BLANK_LINE) ci = i;else break;
}
if (ci === -1) return null;
var ca = cnode.items.splice(ci, len - ci);
var prevEnd = ca[0].range.start;
while (true) {
cnode.range.end = prevEnd;
if (cnode.valueRange && cnode.valueRange.end > prevEnd) cnode.valueRange.end = prevEnd;
if (cnode === node) break;
cnode = cnode.context.parent;
}
return ca;
}
var Collection = /*#__PURE__*/function (_Node) {
_inherits(Collection, _Node);
var _super = _createSuper(Collection);
_createClass(Collection, null, [{
key: "nextContentHasIndent",
value: function nextContentHasIndent(src, offset, indent) {
var lineStart = Node.endOfLine(src, offset) + 1;
offset = Node.endOfWhiteSpace(src, lineStart);
var ch = src[offset];
if (!ch) return false;
if (offset >= lineStart + indent) return true;
if (ch !== '#' && ch !== '\n') return false;
return Collection.nextContentHasIndent(src, offset, indent);
}
}]);
function Collection(firstItem) {
var _this;
_classCallCheck(this, Collection);
_this = _super.call(this, firstItem.type === Type.SEQ_ITEM ? Type.SEQ : Type.MAP);
for (var i = firstItem.props.length - 1; i >= 0; --i) {
if (firstItem.props[i].start < firstItem.context.lineStart) {
// props on previous line are assumed by the collection
_this.props = firstItem.props.slice(0, i + 1);
firstItem.props = firstItem.props.slice(i + 1);
var itemRange = firstItem.props[0] || firstItem.valueRange;
firstItem.range.start = itemRange.start;
break;
}
}
_this.items = [firstItem];
var ec = grabCollectionEndComments(firstItem);
if (ec) Array.prototype.push.apply(_this.items, ec);
return _this;
}
_createClass(Collection, [{
key: "parse",
/**
* @param {ParseContext} context
* @param {number} start - Index of first character
* @returns {number} - Index of the character after this
*/
value: function parse(context, start) {
this.context = context;
var parseNode = context.parseNode,
src = context.src; // It's easier to recalculate lineStart here rather than tracking down the
// last context from which to read it -- eemeli/yaml#2
var lineStart = Node.startOfLine(src, start);
var firstItem = this.items[0]; // First-item context needs to be correct for later comment handling
// -- eemeli/yaml#17
firstItem.context.parent = this;
this.valueRange = Range.copy(firstItem.valueRange);
var indent = firstItem.range.start - firstItem.context.lineStart;
var offset = start;
offset = Node.normalizeOffset(src, offset);
var ch = src[offset];
var atLineStart = Node.endOfWhiteSpace(src, lineStart) === offset;
var prevIncludesTrailingLines = false;
while (ch) {
while (ch === '\n' || ch === '#') {
if (atLineStart && ch === '\n' && !prevIncludesTrailingLines) {
var blankLine = new BlankLine();
offset = blankLine.parse({
src: src
}, offset);
this.valueRange.end = offset;
if (offset >= src.length) {
ch = null;
break;
}
this.items.push(blankLine);
offset -= 1; // blankLine.parse() consumes terminal newline
} else if (ch === '#') {
if (offset < lineStart + indent && !Collection.nextContentHasIndent(src, offset, indent)) {
return offset;
}
var comment = new Comment();
offset = comment.parse({
indent: indent,
lineStart: lineStart,
src: src
}, offset);
this.items.push(comment);
this.valueRange.end = offset;
if (offset >= src.length) {
ch = null;
break;
}
}
lineStart = offset + 1;
offset = Node.endOfIndent(src, lineStart);
if (Node.atBlank(src, offset)) {
var wsEnd = Node.endOfWhiteSpace(src, offset);
var next = src[wsEnd];
if (!next || next === '\n' || next === '#') {
offset = wsEnd;
}
}
ch = src[offset];
atLineStart = true;
}
if (!ch) {
break;
}
if (offset !== lineStart + indent && (atLineStart || ch !== ':')) {
if (offset < lineStart + indent) {
if (lineStart > start) offset = lineStart;
break;
} else if (!this.error) {
var msg = 'All collection items must start at the same column';
this.error = new YAMLSyntaxError(this, msg);
}
}
if (firstItem.type === Type.SEQ_ITEM) {
if (ch !== '-') {
if (lineStart > start) offset = lineStart;
break;
}
} else if (ch === '-' && !this.error) {
// map key may start with -, as long as it's followed by a non-whitespace char
var _next = src[offset + 1];
if (!_next || _next === '\n' || _next === '\t' || _next === ' ') {
var _msg = 'A collection cannot be both a mapping and a sequence';
this.error = new YAMLSyntaxError(this, _msg);
}
}
var node = parseNode({
atLineStart: atLineStart,
inCollection: true,
indent: indent,
lineStart: lineStart,
parent: this
}, offset);
if (!node) return offset; // at next document start
this.items.push(node);
this.valueRange.end = node.valueRange.end;
offset = Node.normalizeOffset(src, node.range.end);
ch = src[offset];
atLineStart = false;
prevIncludesTrailingLines = node.includesTrailingLines; // Need to reset lineStart and atLineStart here if preceding node's range
// has advanced to check the current line's indentation level
// -- eemeli/yaml#10 & eemeli/yaml#38
if (ch) {
var ls = offset - 1;
var prev = src[ls];
while (prev === ' ' || prev === '\t') {
prev = src[--ls];
}
if (prev === '\n') {
lineStart = ls + 1;
atLineStart = true;
}
}
var ec = grabCollectionEndComments(node);
if (ec) Array.prototype.push.apply(this.items, ec);
}
return offset;
}
}, {
key: "setOrigRanges",
value: function setOrigRanges(cr, offset) {
offset = _get(_getPrototypeOf(Collection.prototype), "setOrigRanges", this).call(this, cr, offset);
this.items.forEach(function (node) {
offset = node.setOrigRanges(cr, offset);
});
return offset;
}
}, {
key: "toString",
value: function toString() {
var src = this.context.src,
items = this.items,
range = this.range,
value = this.value;
if (value != null) return value;
var str = src.slice(range.start, items[0].range.start) + String(items[0]);
for (var i = 1; i < items.length; ++i) {
var item = items[i];
var _item$context = item.context,
atLineStart = _item$context.atLineStart,
indent = _item$context.indent;
if (atLineStart) for (var _i = 0; _i < indent; ++_i) {
str += ' ';
}
str += String(item);
}
return Node.addStringTerminator(src, range.end, str);
}
}, {
key: "includesTrailingLines",
get: function get() {
return this.items.length > 0;
}
}]);
return Collection;
}(Node);
var Directive = /*#__PURE__*/function (_Node) {
_inherits(Directive, _Node);
var _super = _createSuper(Directive);
function Directive() {
var _this;
_classCallCheck(this, Directive);
_this = _super.call(this, Type.DIRECTIVE);
_this.name = null;
return _this;
}
_createClass(Directive, [{
key: "parseName",
value: function parseName(start) {
var src = this.context.src;
var offset = start;
var ch = src[offset];
while (ch && ch !== '\n' && ch !== '\t' && ch !== ' ') {
ch = src[offset += 1];
}
this.name = src.slice(start, offset);
return offset;
}
}, {
key: "parseParameters",
value: function parseParameters(start) {
var src = this.context.src;
var offset = start;
var ch = src[offset];
while (ch && ch !== '\n' && ch !== '#') {
ch = src[offset += 1];
}
this.valueRange = new Range(start, offset);
return offset;
}
}, {
key: "parse",
value: function parse(context, start) {
this.context = context;
var offset = this.parseName(start + 1);
offset = this.parseParameters(offset);
offset = this.parseComment(offset);
this.range = new Range(start, offset);
return offset;
}
}, {
key: "parameters",
get: function get() {
var raw = this.rawValue;
return raw ? raw.trim().split(/[ \t]+/) : [];
}
}]);
return Directive;
}(Node);
var Document = /*#__PURE__*/function (_Node) {
_inherits(Document, _Node);
var _super = _createSuper(Document);
_createClass(Document, null, [{
key: "startCommentOrEndBlankLine",
value: function startCommentOrEndBlankLine(src, start) {
var offset = Node.endOfWhiteSpace(src, start);
var ch = src[offset];
return ch === '#' || ch === '\n' ? offset : start;
}
}]);
function Document() {
var _this;
_classCallCheck(this, Document);
_this = _super.call(this, Type.DOCUMENT);
_this.directives = null;
_this.contents = null;
_this.directivesEndMarker = null;
_this.documentEndMarker = null;
return _this;
}
_createClass(Document, [{
key: "parseDirectives",
value: function parseDirectives(start) {
var src = this.context.src;
this.directives = [];
var atLineStart = true;
var hasDirectives = false;
var offset = start;
while (!Node.atDocumentBoundary(src, offset, Char.DIRECTIVES_END)) {
offset = Document.startCommentOrEndBlankLine(src, offset);
switch (src[offset]) {
case '\n':
if (atLineStart) {
var blankLine = new BlankLine();
offset = blankLine.parse({
src: src
}, offset);
if (offset < src.length) {
this.directives.push(blankLine);
}
} else {
offset += 1;
atLineStart = true;
}
break;
case '#':
{
var comment = new Comment();
offset = comment.parse({
src: src
}, offset);
this.directives.push(comment);
atLineStart = false;
}
break;
case '%':
{
var directive = new Directive();
offset = directive.parse({
parent: this,
src: src
}, offset);
this.directives.push(directive);
hasDirectives = true;
atLineStart = false;
}
break;
default:
if (hasDirectives) {
this.error = new YAMLSemanticError(this, 'Missing directives-end indicator line');
} else if (this.directives.length > 0) {
this.contents = this.directives;
this.directives = [];
}
return offset;
}
}
if (src[offset]) {
this.directivesEndMarker = new Range(offset, offset + 3);
return offset + 3;
}
if (hasDirectives) {
this.error = new YAMLSemanticError(this, 'Missing directives-end indicator line');
} else if (this.directives.length > 0) {
this.contents = this.directives;
this.directives = [];
}
return offset;
}
}, {
key: "parseContents",
value: function parseContents(start) {
var _this$context = this.context,
parseNode = _this$context.parseNode,
src = _this$context.src;
if (!this.contents) this.contents = [];
var lineStart = start;
while (src[lineStart - 1] === '-') {
lineStart -= 1;
}
var offset = Node.endOfWhiteSpace(src, start);
var atLineStart = lineStart === start;
this.valueRange = new Range(offset);
while (!Node.atDocumentBoundary(src, offset, Char.DOCUMENT_END)) {
switch (src[offset]) {
case '\n':
if (atLineStart) {
var blankLine = new BlankLine();
offset = blankLine.parse({
src: src
}, offset);
if (offset < src.length) {
this.contents.push(blankLine);
}
} else {
offset += 1;
atLineStart = true;
}
lineStart = offset;
break;
case '#':
{
var comment = new Comment();
offset = comment.parse({
src: src
}, offset);
this.contents.push(comment);
atLineStart = false;
}
break;
default:
{
var iEnd = Node.endOfIndent(src, offset);
var context = {
atLineStart: atLineStart,
indent: -1,
inFlow: false,
inCollection: false,
lineStart: lineStart,
parent: this
};
var node = parseNode(context, iEnd);
if (!node) return this.valueRange.end = iEnd; // at next document start
this.contents.push(node);
offset = node.range.end;
atLineStart = false;
var ec = grabCollectionEndComments(node);
if (ec) Array.prototype.push.apply(this.contents, ec);
}
}
offset = Document.startCommentOrEndBlankLine(src, offset);
}
this.valueRange.end = offset;
if (src[offset]) {
this.documentEndMarker = new Range(offset, offset + 3);
offset += 3;
if (src[offset]) {
offset = Node.endOfWhiteSpace(src, offset);
if (src[offset] === '#') {
var _comment = new Comment();
offset = _comment.parse({
src: src
}, offset);
this.contents.push(_comment);
}
switch (src[offset]) {
case '\n':
offset += 1;
break;
case undefined:
break;
default:
this.error = new YAMLSyntaxError(this, 'Document end marker line cannot have a non-comment suffix');
}
}
}
return offset;
}
/**
* @param {ParseContext} context
* @param {number} start - Index of first character
* @returns {number} - Index of the character after this
*/
}, {
key: "parse",
value: function parse(context, start) {
context.root = this;
this.context = context;
var src = context.src;
var offset = src.charCodeAt(start) === 0xfeff ? start + 1 : start; // skip BOM
offset = this.parseDirectives(offset);
offset = this.parseContents(offset);
return offset;
}
}, {
key: "setOrigRanges",
value: function setOrigRanges(cr, offset) {
offset = _get(_getPrototypeOf(Document.prototype), "setOrigRanges", this).call(this, cr, offset);
this.directives.forEach(function (node) {
offset = node.setOrigRanges(cr, offset);
});
if (this.directivesEndMarker) offset = this.directivesEndMarker.setOrigRange(cr, offset);
this.contents.forEach(function (node) {
offset = node.setOrigRanges(cr, offset);
});
if (this.documentEndMarker) offset = this.documentEndMarker.setOrigRange(cr, offset);
return offset;
}
}, {
key: "toString",
value: function toString() {
var contents = this.contents,
directives = this.directives,
value = this.value;
if (value != null) return value;
var str = directives.join('');
if (contents.length > 0) {
if (directives.length > 0 || contents[0].type === Type.COMMENT) str += '---\n';
str += contents.join('');
}
if (str[str.length - 1] !== '\n') str += '\n';
return str;
}
}]);
return Document;
}(Node);
var Alias = /*#__PURE__*/function (_Node) {
_inherits(Alias, _Node);
var _super = _createSuper(Alias);
function Alias() {
_classCallCheck(this, Alias);
return _super.apply(this, arguments);
}
_createClass(Alias, [{
key: "parse",
/**
* Parses an *alias from the source
*
* @param {ParseContext} context
* @param {number} start - Index of first character
* @returns {number} - Index of the character after this scalar
*/
value: function parse(context, start) {
this.context = context;
var src = context.src;
var offset = Node.endOfIdentifier(src, start + 1);
this.valueRange = new Range(start + 1, offset);
offset = Node.endOfWhiteSpace(src, offset);
offset = this.parseComment(offset);
return offset;
}
}]);
return Alias;
}(Node);
var Chomp = {
CLIP: 'CLIP',
KEEP: 'KEEP',
STRIP: 'STRIP'
};
var BlockValue = /*#__PURE__*/function (_Node) {
_inherits(BlockValue, _Node);
var _super = _createSuper(BlockValue);
function BlockValue(type, props) {
var _this;
_classCallCheck(this, BlockValue);
_this = _super.call(this, type, props);
_this.blockIndent = null;
_this.chomping = Chomp.CLIP;
_this.header = null;
return _this;
}
_createClass(BlockValue, [{
key: "parseBlockHeader",
value: function parseBlockHeader(start) {
var src = this.context.src;
var offset = start + 1;
var bi = '';
while (true) {
var ch = src[offset];
switch (ch) {
case '-':
this.chomping = Chomp.STRIP;
break;
case '+':
this.chomping = Chomp.KEEP;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
bi += ch;
break;
default:
this.blockIndent = Number(bi) || null;
this.header = new Range(start, offset);
return offset;
}
offset += 1;
}
}
}, {
key: "parseBlockValue",
value: function parseBlockValue(start) {
var _this$context = this.context,
indent = _this$context.indent,
src = _this$context.src;
var explicit = !!this.blockIndent;
var offset = start;
var valueEnd = start;
var minBlockIndent = 1;
for (var ch = src[offset]; ch === '\n'; ch = src[offset]) {
offset += 1;
if (Node.atDocumentBoundary(src, offset)) break;
var end = Node.endOfBlockIndent(src, indent, offset); // should not include tab?
if (end === null) break;
var _ch = src[end];
var lineIndent = end - (offset + indent);
if (!this.blockIndent) {
// no explicit block indent, none yet detected
if (src[end] !== '\n') {
// first line with non-whitespace content
if (lineIndent < minBlockIndent) {
var msg = 'Block scalars with more-indented leading empty lines must use an explicit indentation indicator';
this.error = new YAMLSemanticError(this, msg);
}
this.blockIndent = lineIndent;
} else if (lineIndent > minBlockIndent) {
// empty line with more whitespace
minBlockIndent = lineIndent;
}
} else if (_ch && _ch !== '\n' && lineIndent < this.blockIndent) {
if (src[end] === '#') break;
if (!this.error) {
var _src = explicit ? 'explicit indentation indicator' : 'first line';
var _msg = "Block scalars must not be less indented than their ".concat(_src);
this.error = new YAMLSemanticError(this, _msg);
}
}
if (src[end] === '\n') {
offset = end;
} else {
offset = valueEnd = Node.endOfLine(src, end);
}
}
if (this.chomping !== Chomp.KEEP) {
offset = src[valueEnd] ? valueEnd + 1 : valueEnd;
}
this.valueRange = new Range(start + 1, offset);
return offset;
}
/**
* Parses a block value from the source
*
* Accepted forms are:
* ```
* BS
* block
* lines
*
* BS #comment
* block
* lines
* ```
* where the block style BS matches the regexp `[|>][-+1-9]*` and block lines
* are empty or have an indent level greater than `indent`.
*
* @param {ParseContext} context
* @param {number} start - Index of first character
* @returns {number} - Index of the character after this block
*/
}, {
key: "parse",
value: function parse(context, start) {
this.context = context;
var src = context.src;
var offset = this.parseBlockHeader(start);
offset = Node.endOfWhiteSpace(src, offset);
offset = this.parseComment(offset);
offset = this.parseBlockValue(offset);
return offset;
}
}, {
key: "setOrigRanges",
value: function setOrigRanges(cr, offset) {
offset = _get(_getPrototypeOf(BlockValue.prototype), "setOrigRanges", this).call(this, cr, offset);
return this.header ? this.header.setOrigRange(cr, offset) : offset;
}
}, {
key: "includesTrailingLines",
get: function get() {
return this.chomping === Chomp.KEEP;
}
}, {
key: "strValue",
get: function get() {
if (!this.valueRange || !this.context) return null;
var _this$valueRange = this.valueRange,
start = _this$valueRange.start,
end = _this$valueRange.end;
var _this$context2 = this.context,
indent = _this$context2.indent,
src = _this$context2.src;
if (this.valueRange.isEmpty()) return '';
var lastNewLine = null;
var ch = src[end - 1];
while (ch === '\n' || ch === '\t' || ch === ' ') {
end -= 1;
if (end <= start) {
if (this.chomping === Chomp.KEEP) break;else return ''; // probably never happens
}
if (ch === '\n') lastNewLine = end;
ch = src[end - 1];
}
var keepStart = end + 1;
if (lastNewLine) {
if (this.chomping === Chomp.KEEP) {
keepStart = lastNewLine;
end = this.valueRange.end;
} else {
end = lastNewLine;
}
}
var bi = indent + this.blockIndent;
var folded = this.type === Type.BLOCK_FOLDED;
var atStart = true;
var str = '';
var sep = '';
var prevMoreIndented = false;
for (var i = start; i < end; ++i) {
for (var j = 0; j < bi; ++j) {
if (src[i] !== ' ') break;
i += 1;
}
var _ch2 = src[i];
if (_ch2 === '\n') {
if (sep === '\n') str += '\n';else sep = '\n';
} else {
var lineEnd = Node.endOfLine(src, i);
var line = src.slice(i, lineEnd);
i = lineEnd;
if (folded && (_ch2 === ' ' || _ch2 === '\t') && i < keepStart) {
if (sep === ' ') sep = '\n';else if (!prevMoreIndented && !atStart && sep === '\n') sep = '\n\n';
str += sep + line; //+ ((lineEnd < end && src[lineEnd]) || '')
sep = lineEnd < end && src[lineEnd] || '';
prevMoreIndented = true;
} else {
str += sep + line;
sep = folded && i < keepStart ? ' ' : '\n';
prevMoreIndented = false;
}
if (atStart && line !== '') atStart = false;
}
}
return this.chomping === Chomp.STRIP ? str : str + '\n';
}
}]);
return BlockValue;
}(Node);
var FlowCollection = /*#__PURE__*/function (_Node) {
_inherits(FlowCollection, _Node);
var _super = _createSuper(FlowCollection);
function FlowCollection(type, props) {
var _this;
_classCallCheck(this, FlowCollection);
_this = _super.call(this, type, props);
_this.items = null;
return _this;
}
_createClass(FlowCollection, [{
key: "prevNodeIsJsonLike",
value: function prevNodeIsJsonLike() {
var idx = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.items.length;
var node = this.items[idx - 1];
return !!node && (node.jsonLike || node.type === Type.COMMENT && this.prevNodeIsJsonLike(idx - 1));
}
/**
* @param {ParseContext} context
* @param {number} start - Index of first character
* @returns {number} - Index of the character after this
*/
}, {
key: "parse",
value: function parse(context, start) {
this.context = context;
var parseNode = context.parseNode,
src = context.src;
var indent = context.indent,
lineStart = context.lineStart;
var char = src[start]; // { or [
this.items = [{
char: char,
offset: start
}];
var offset = Node.endOfWhiteSpace(src, start + 1);
char = src[offset];
while (char && char !== ']' && char !== '}') {
switch (char) {
case '\n':
{
lineStart = offset + 1;
var wsEnd = Node.endOfWhiteSpace(src, lineStart);
if (src[wsEnd] === '\n') {
var blankLine = new BlankLine();
lineStart = blankLine.parse({
src: src
}, lineStart);
this.items.push(blankLine);
}
offset = Node.endOfIndent(src, lineStart);
if (offset <= lineStart + indent) {
char = src[offset];
if (offset < lineStart + indent || char !== ']' && char !== '}') {
var msg = 'Insufficient indentation in flow collection';
this.error = new YAMLSemanticError(this, msg);
}
}
}
break;
case ',':
{
this.items.push({
char: char,
offset: offset
});
offset += 1;
}
break;
case '#':
{
var comment = new Comment();
offset = comment.parse({
src: src
}, offset);
this.items.push(comment);
}
break;
case '?':
case ':':
{
var next = src[offset + 1];
if (next === '\n' || next === '\t' || next === ' ' || next === ',' || // in-flow : after JSON-like key does not need to be followed by whitespace
char === ':' && this.prevNodeIsJsonLike()) {
this.items.push({
char: char,
offset: offset
});
offset += 1;
break;
}
}
// fallthrough
default:
{
var node = parseNode({
atLineStart: false,
inCollection: false,
inFlow: true,
indent: -1,
lineStart: lineStart,
parent: this
}, offset);
if (!node) {
// at next document start
this.valueRange = new Range(start, offset);
return offset;
}
this.items.push(node);
offset = Node.normalizeOffset(src, node.range.end);
}
}
offset = Node.endOfWhiteSpace(src, offset);
char = src[offset];
}
this.valueRange = new Range(start, offset + 1);
if (char) {
this.items.push({
char: char,
offset: offset
});
offset = Node.endOfWhiteSpace(src, offset + 1);
offset = this.parseComment(offset);
}
return offset;
}
}, {
key: "setOrigRanges",
value: function setOrigRanges(cr, offset) {
offset = _get(_getPrototypeOf(FlowCollection.prototype), "setOrigRanges", this).call(this, cr, offset);
this.items.forEach(function (node) {
if (node instanceof Node) {
offset = node.setOrigRanges(cr, offset);
} else if (cr.length === 0) {
node.origOffset = node.offset;
} else {
var i = offset;
while (i < cr.length) {
if (cr[i] > node.offset) break;else ++i;
}
node.origOffset = node.offset + i;
offset = i;
}
});
return offset;
}
}, {
key: "toString",
value: function toString() {
var src = this.context.src,
items = this.items,
range = this.range,
value = this.value;
if (value != null) return value;
var nodes = items.filter(function (item) {
return item instanceof Node;
});
var str = '';
var prevEnd = range.start;
nodes.forEach(function (node) {
var prefix = src.slice(prevEnd, node.range.start);
prevEnd = node.range.end;
str += prefix + String(node);
if (str[str.length - 1] === '\n' && src[prevEnd - 1] !== '\n' && src[prevEnd] === '\n') {
// Comment range does not include the terminal newline, but its
// stringified value does. Without this fix, newlines at comment ends
// get duplicated.
prevEnd += 1;
}
});
str += src.slice(prevEnd, range.end);
return Node.addStringTerminator(src, range.end, str);
}
}]);
return FlowCollection;
}(Node);
var QuoteDouble = /*#__PURE__*/function (_Node) {
_inherits(QuoteDouble, _Node);
var _super = _createSuper(QuoteDouble);
function QuoteDouble() {
_classCallCheck(this, QuoteDouble);
return _super.apply(this, arguments);
}
_createClass(QuoteDouble, [{
key: "parseCharCode",
value: function parseCharCode(offset, length, errors) {
var src = this.context.src;
var cc = src.substr(offset, length);
var ok = cc.length === length && /^[0-9a-fA-F]+$/.test(cc);
var code = ok ? parseInt(cc, 16) : NaN;
if (isNaN(code)) {
errors.push(new YAMLSyntaxError(this, "Invalid escape sequence ".concat(src.substr(offset - 2, length + 2))));
return src.substr(offset - 2, length + 2);
}
return String.fromCodePoint(code);
}
/**
* Parses a "double quoted" value from the source
*
* @param {ParseContext} context
* @param {number} start - Index of first character
* @returns {number} - Index of the character after this scalar
*/
}, {
key: "parse",
value: function parse(context, start) {
this.context = context;
var src = context.src;
var offset = QuoteDouble.endOfQuote(src, start + 1);
this.valueRange = new Range(start, offset);
offset = Node.endOfWhiteSpace(src, offset);
offset = this.parseComment(offset);
return offset;
}
}, {
key: "strValue",
/**
* @returns {string | { str: string, errors: YAMLSyntaxError[] }}
*/
get: function get() {
if (!this.valueRange || !this.context) return null;
var errors = [];
var _this$valueRange = this.valueRange,
start = _this$valueRange.start,
end = _this$valueRange.end;
var _this$context = this.context,
indent = _this$context.indent,
src = _this$context.src;
if (src[end - 1] !== '"') errors.push(new YAMLSyntaxError(this, 'Missing closing "quote')); // Using String#replace is too painful with escaped newlines preceded by
// escaped backslashes; also, this should be faster.
var str = '';
for (var i = start + 1; i < end - 1; ++i) {
var ch = src[i];
if (ch === '\n') {
if (Node.atDocumentBoundary(src, i + 1)) errors.push(new YAMLSemanticError(this, 'Document boundary indicators are not allowed within string values'));
var _Node$foldNewline = Node.foldNewline(src, i, indent),
fold = _Node$foldNewline.fold,
offset = _Node$foldNewline.offset,
error = _Node$foldNewline.error;
str += fold;
i = offset;
if (error) errors.push(new YAMLSemanticError(this, 'Multi-line double-quoted string needs to be sufficiently indented'));
} else if (ch === '\\') {
i += 1;
switch (src[i]) {
case '0':
str += '\0';
break;
// null character
case 'a':
str += '\x07';
break;
// bell character
case 'b':
str += '\b';
break;
// backspace
case 'e':
str += '\x1b';
break;
// escape character
case 'f':
str += '\f';
break;
// form feed
case 'n':
str += '\n';
break;
// line feed
case 'r':
str += '\r';
break;
// carriage return
case 't':
str += '\t';
break;
// horizontal tab
case 'v':
str += '\v';
break;
// vertical tab
case 'N':
str += "\x85";
break;
// Unicode next line
case '_':
str += "\xA0";
break;
// Unicode non-breaking space
case 'L':
str += "\u2028";
break;
// Unicode line separator
case 'P':
str += "\u2029";
break;
// Unicode paragraph separator
case ' ':
str += ' ';
break;
case '"':
str += '"';
break;
case '/':
str += '/';
break;
case '\\':
str += '\\';
break;
case '\t':
str += '\t';
break;
case 'x':
str += this.parseCharCode(i + 1, 2, errors);
i += 2;
break;
case 'u':
str += this.parseCharCode(i + 1, 4, errors);
i += 4;
break;
case 'U':
str += this.parseCharCode(i + 1, 8, errors);
i += 8;
break;
case '\n':
// skip escaped newlines, but still trim the following line
while (src[i + 1] === ' ' || src[i + 1] === '\t') {
i += 1;
}
break;
default:
errors.push(new YAMLSyntaxError(this, "Invalid escape sequence ".concat(src.substr(i - 1, 2))));
str += '\\' + src[i];
}
} else if (ch === ' ' || ch === '\t') {
// trim trailing whitespace
var wsStart = i;
var next = src[i + 1];
while (next === ' ' || next === '\t') {
i += 1;
next = src[i + 1];
}
if (next !== '\n') str += i > wsStart ? src.slice(wsStart, i + 1) : ch;
} else {
str += ch;
}
}
return errors.length > 0 ? {
errors: errors,
str: str
} : str;
}
}], [{
key: "endOfQuote",
value: function endOfQuote(src, offset) {
var ch = src[offset];
while (ch && ch !== '"') {
offset += ch === '\\' ? 2 : 1;
ch = src[offset];
}
return offset + 1;
}
}]);
return QuoteDouble;
}(Node);
var QuoteSingle = /*#__PURE__*/function (_Node) {
_inherits(QuoteSingle, _Node);
var _super = _createSuper(QuoteSingle);
function QuoteSingle() {
_classCallCheck(this, QuoteSingle);
return _super.apply(this, arguments);
}
_createClass(QuoteSingle, [{
key: "parse",
/**
* Parses a 'single quoted' value from the source
*
* @param {ParseContext} context
* @param {number} start - Index of first character
* @returns {number} - Index of the character after this scalar
*/
value: function parse(context, start) {
this.context = context;
var src = context.src;
var offset = QuoteSingle.endOfQuote(src, start + 1);
this.valueRange = new Range(start, offset);
offset = Node.endOfWhiteSpace(src, offset);
offset = this.parseComment(offset);
return offset;
}
}, {
key: "strValue",
/**
* @returns {string | { str: string, errors: YAMLSyntaxError[] }}
*/
get: function get() {
if (!this.valueRange || !this.context) return null;
var errors = [];
var _this$valueRange = this.valueRange,
start = _this$valueRange.start,
end = _this$valueRange.end;
var _this$context = this.context,
indent = _this$context.indent,
src = _this$context.src;
if (src[end - 1] !== "'") errors.push(new YAMLSyntaxError(this, "Missing closing 'quote"));
var str = '';
for (var i = start + 1; i < end - 1; ++i) {
var ch = src[i];
if (ch === '\n') {
if (Node.atDocumentBoundary(src, i + 1)) errors.push(new YAMLSemanticError(this, 'Document boundary indicators are not allowed within string values'));
var _Node$foldNewline = Node.foldNewline(src, i, indent),
fold = _Node$foldNewline.fold,
offset = _Node$foldNewline.offset,
error = _Node$foldNewline.error;
str += fold;
i = offset;
if (error) errors.push(new YAMLSemanticError(this, 'Multi-line single-quoted string needs to be sufficiently indented'));
} else if (ch === "'") {
str += ch;
i += 1;
if (src[i] !== "'") errors.push(new YAMLSyntaxError(this, 'Unescaped single quote? This should not happen.'));
} else if (ch === ' ' || ch === '\t') {
// trim trailing whitespace
var wsStart = i;
var next = src[i + 1];
while (next === ' ' || next === '\t') {
i += 1;
next = src[i + 1];
}
if (next !== '\n') str += i > wsStart ? src.slice(wsStart, i + 1) : ch;
} else {
str += ch;
}
}
return errors.length > 0 ? {
errors: errors,
str: str
} : str;
}
}], [{
key: "endOfQuote",
value: function endOfQuote(src, offset) {
var ch = src[offset];
while (ch) {
if (ch === "'") {
if (src[offset + 1] !== "'") break;
ch = src[offset += 2];
} else {
ch = src[offset += 1];
}
}
return offset + 1;
}
}]);
return QuoteSingle;
}(Node);
function createNewNode(type, props) {
switch (type) {
case Type.ALIAS:
return new Alias(type, props);
case Type.BLOCK_FOLDED:
case Type.BLOCK_LITERAL:
return new BlockValue(type, props);
case Type.FLOW_MAP:
case Type.FLOW_SEQ:
return new FlowCollection(type, props);
case Type.MAP_KEY:
case Type.MAP_VALUE:
case Type.SEQ_ITEM:
return new CollectionItem(type, props);
case Type.COMMENT:
case Type.PLAIN:
return new PlainValue(type, props);
case Type.QUOTE_DOUBLE:
return new QuoteDouble(type, props);
case Type.QUOTE_SINGLE:
return new QuoteSingle(type, props);
/* istanbul ignore next */
default:
return null;
// should never happen
}
}
/**
* @param {boolean} atLineStart - Node starts at beginning of line
* @param {boolean} inFlow - true if currently in a flow context
* @param {boolean} inCollection - true if currently in a collection context
* @param {number} indent - Current level of indentation
* @param {number} lineStart - Start of the current line
* @param {Node} parent - The parent of the node
* @param {string} src - Source of the YAML document
*/
var ParseContext = /*#__PURE__*/function () {
_createClass(ParseContext, null, [{
key: "parseType",
value: function parseType(src, offset, inFlow) {
switch (src[offset]) {
case '*':
return Type.ALIAS;
case '>':
return Type.BLOCK_FOLDED;
case '|':
return Type.BLOCK_LITERAL;
case '{':
return Type.FLOW_MAP;
case '[':
return Type.FLOW_SEQ;
case '?':
return !inFlow && Node.atBlank(src, offset + 1, true) ? Type.MAP_KEY : Type.PLAIN;
case ':':
return !inFlow && Node.atBlank(src, offset + 1, true) ? Type.MAP_VALUE : Type.PLAIN;
case '-':
return !inFlow && Node.atBlank(src, offset + 1, true) ? Type.SEQ_ITEM : Type.PLAIN;
case '"':
return Type.QUOTE_DOUBLE;
case "'":
return Type.QUOTE_SINGLE;
default:
return Type.PLAIN;
}
}
}]);
function ParseContext() {
var _this = this;
var orig = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
atLineStart = _ref.atLineStart,
inCollection = _ref.inCollection,
inFlow = _ref.inFlow,
indent = _ref.indent,
lineStart = _ref.lineStart,
parent = _ref.parent;
_classCallCheck(this, ParseContext);
_defineProperty(this, "parseNode", function (overlay, start) {
if (Node.atDocumentBoundary(_this.src, start)) return null;
var context = new ParseContext(_this, overlay);
var _context$parseProps = context.parseProps(start),
props = _context$parseProps.props,
type = _context$parseProps.type,
valueStart = _context$parseProps.valueStart;
var node = createNewNode(type, props);
var offset = node.parse(context, valueStart);
node.range = new Range(start, offset);
/* istanbul ignore if */
if (offset <= start) {
// This should never happen, but if it does, let's make sure to at least
// step one character forward to avoid a busy loop.
node.error = new Error("Node#parse consumed no characters");
node.error.parseEnd = offset;
node.error.source = node;
node.range.end = start + 1;
}
if (context.nodeStartsCollection(node)) {
if (!node.error && !context.atLineStart && context.parent.type === Type.DOCUMENT) {
node.error = new YAMLSyntaxError(node, 'Block collection must not have preceding content here (e.g. directives-end indicator)');
}
var collection = new Collection(node);
offset = collection.parse(new ParseContext(context), offset);
collection.range = new Range(start, offset);
return collection;
}
return node;
});
this.atLineStart = atLineStart != null ? atLineStart : orig.atLineStart || false;
this.inCollection = inCollection != null ? inCollection : orig.inCollection || false;
this.inFlow = inFlow != null ? inFlow : orig.inFlow || false;
this.indent = indent != null ? indent : orig.indent;
this.lineStart = lineStart != null ? lineStart : orig.lineStart;
this.parent = parent != null ? parent : orig.parent || {};
this.root = orig.root;
this.src = orig.src;
}
_createClass(ParseContext, [{
key: "nodeStartsCollection",
value: function nodeStartsCollection(node) {
var inCollection = this.inCollection,
inFlow = this.inFlow,
src = this.src;
if (inCollection || inFlow) return false;
if (node instanceof CollectionItem) return true; // check for implicit key
var offset = node.range.end;
if (src[offset] === '\n' || src[offset - 1] === '\n') return false;
offset = Node.endOfWhiteSpace(src, offset);
return src[offset] === ':';
} // Anchor and tag are before type, which determines the node implementation
// class; hence this intermediate step.
}, {
key: "parseProps",
value: function parseProps(offset) {
var inFlow = this.inFlow,
parent = this.parent,
src = this.src;
var props = [];
var lineHasProps = false;
offset = this.atLineStart ? Node.endOfIndent(src, offset) : Node.endOfWhiteSpace(src, offset);
var ch = src[offset];
while (ch === Char.ANCHOR || ch === Char.COMMENT || ch === Char.TAG || ch === '\n') {
if (ch === '\n') {
var lineStart = offset + 1;
var inEnd = Node.endOfIndent(src, lineStart);
var indentDiff = inEnd - (lineStart + this.indent);
var noIndicatorAsIndent = parent.type === Type.SEQ_ITEM && parent.context.atLineStart;
if (!Node.nextNodeIsIndented(src[inEnd], indentDiff, !noIndicatorAsIndent)) break;
this.atLineStart = true;
this.lineStart = lineStart;
lineHasProps = false;
offset = inEnd;
} else if (ch === Char.COMMENT) {
var end = Node.endOfLine(src, offset + 1);
props.push(new Range(offset, end));
offset = end;
} else {
var _end = Node.endOfIdentifier(src, offset + 1);
if (ch === Char.TAG && src[_end] === ',' && /^[a-zA-Z0-9-]+\.[a-zA-Z0-9-]+,\d\d\d\d(-\d\d){0,2}\/\S/.test(src.slice(offset + 1, _end + 13))) {
// Let's presume we're dealing with a YAML 1.0 domain tag here, rather
// than an empty but 'foo.bar' private-tagged node in a flow collection
// followed without whitespace by a plain string starting with a year
// or date divided by something.
_end = Node.endOfIdentifier(src, _end + 5);
}
props.push(new Range(offset, _end));
lineHasProps = true;
offset = Node.endOfWhiteSpace(src, _end);
}
ch = src[offset];
} // '- &a : b' has an anchor on an empty node
if (lineHasProps && ch === ':' && Node.atBlank(src, offset + 1, true)) offset -= 1;
var type = ParseContext.parseType(src, offset, inFlow);
return {
props: props,
type: type,
valueStart: offset
};
}
/**
* Parses a node from the source
* @param {ParseContext} overlay
* @param {number} start - Index of first non-whitespace character for the node
* @returns {?Node} - null if at a document boundary
*/
}]);
return ParseContext;
}();
// Published as 'yaml/parse-cst'
function parse(src) {
var cr = [];
if (src.indexOf('\r') !== -1) {
src = src.replace(/\r\n?/g, function (match, offset) {
if (match.length > 1) cr.push(offset);
return '\n';
});
}
var documents = [];
var offset = 0;
do {
var doc = new Document();
var context = new ParseContext({
src: src
});
offset = doc.parse(context, offset);
documents.push(doc);
} while (offset < src.length);
documents.setOrigRanges = function () {
if (cr.length === 0) return false;
for (var i = 1; i < cr.length; ++i) {
cr[i] -= i;
}
var crOffset = 0;
for (var _i = 0; _i < documents.length; ++_i) {
crOffset = documents[_i].setOrigRanges(cr, crOffset);
}
cr.splice(0, cr.length);
return true;
};
documents.toString = function () {
return documents.join('...\n');
};
return documents;
}
export { parse };
import './PlainValue-6b68dc0e.js';
export { p as parse } from './parse-6e806192.js';

@@ -1,4 +0,3 @@

import './PlainValue-ff5147c6.js';
export { A as Alias, C as Collection, M as Merge, N as Node, P as Pair, S as Scalar, d as YAMLMap, Y as YAMLSeq, b as binaryOptions, a as boolOptions, i as intOptions, n as nullOptions, s as strOptions } from './resolveSeq-04825f30.js';
export { S as Schema } from './Schema-2bf2c74e.js';
import './warnings-0e4b70d3.js';
import './PlainValue-6b68dc0e.js';
export { A as Alias, C as Collection, M as Merge, N as Node, P as Pair, S as Scalar, d as YAMLMap, Y as YAMLSeq, b as binaryOptions, a as boolOptions, i as intOptions, n as nullOptions, s as strOptions } from './resolveSeq-3477c430.js';
export { S as Schema } from './Schema-d14032c2.js';

@@ -1,2 +0,2 @@

export { T as Type, i as YAMLError, o as YAMLReferenceError, g as YAMLSemanticError, Y as YAMLSyntaxError, f as YAMLWarning } from './PlainValue-ff5147c6.js';
export { l as findPair, g as parseMap, h as parseSeq, k as stringifyNumber, c as stringifyString, t as toJSON } from './resolveSeq-04825f30.js';
export { T as Type, i as YAMLError, p as YAMLReferenceError, g as YAMLSemanticError, Y as YAMLSyntaxError, f as YAMLWarning } from './PlainValue-6b68dc0e.js';
export { p as findPair, j as parseMap, l as parseSeq, o as stringifyNumber, c as stringifyString, t as toJSON } from './resolveSeq-3477c430.js';
'use strict';
var PlainValue = require('./PlainValue-ec8e588e.js');
var parseCst = require('./parse-cst.js');
require('./resolveSeq-4a68b39b.js');
var Document$1 = require('./Document-2cf6b08c.js');
var Schema = require('./Schema-42e9705c.js');
var warnings = require('./warnings-39684f17.js');
var parseCst = require('./parse-ab8de154.js');
require('./resolveSeq-6b2dc4ac.js');
var Document$1 = require('./Document-59bd9290.js');
require('./Schema-fe1471c4.js');
function createNode(value, wrapScalars = true, tag) {
if (tag === undefined && typeof wrapScalars === 'string') {
tag = wrapScalars;
wrapScalars = true;
}
/* global console, process, YAML_SILENCE_WARNINGS */
function warn(warning, type) {
if (typeof YAML_SILENCE_WARNINGS !== 'undefined' && YAML_SILENCE_WARNINGS) return;
const options = Object.assign({}, Document$1.Document.defaults[Document$1.defaultOptions.version], Document$1.defaultOptions);
const schema = new Schema.Schema(options);
return schema.createNode(value, wrapScalars, tag);
if (typeof process !== 'undefined') {
if (process.env.YAML_SILENCE_WARNINGS) return; // This will throw in Jest if `warning` is an Error instance due to
// https://github.com/facebook/jest/issues/2549
if (process.emitWarning) {
process.emitWarning(warning, type);
return;
}
} // eslint-disable-next-line no-console
console.warn(type ? `${type}: ${warning}` : warning);
}
class Document extends Document$1.Document {
constructor(options) {
super(Object.assign({}, Document$1.defaultOptions, options));
constructor(contents, options) {
super(contents, Object.assign({}, Document$1.defaultOptions, options));
}

@@ -33,3 +39,3 @@

for (const cstDoc of parseCst.parse(src)) {
const doc = new Document(options);
const doc = new Document(undefined, options);
doc.parse(cstDoc, prev);

@@ -45,3 +51,3 @@ stream.push(doc);

const cst = parseCst.parse(src);
const doc = new Document(options).parse(cst[0]);
const doc = new Document(cst[0], options);

@@ -58,3 +64,3 @@ if (cst.length > 1) {

const doc = parseDocument(src, options);
doc.warnings.forEach(warning => warnings.warn(warning));
doc.warnings.forEach(warning => warn(warning));
if (doc.errors.length > 0) throw doc.errors[0];

@@ -65,9 +71,7 @@ return doc.toJSON();

function stringify(value, options) {
const doc = new Document(options);
doc.contents = value;
return String(doc);
if (value === undefined) return '\n';
return new Document(value, options).toString();
}
const YAML = {
createNode,
defaultOptions: Document$1.defaultOptions,

@@ -74,0 +78,0 @@ Document,

'use strict';
var PlainValue = require('./PlainValue-ec8e588e.js');
require('./PlainValue-ec8e588e.js');
var parseCst = require('./parse-ab8de154.js');
class BlankLine extends PlainValue.Node {
constructor() {
super(PlainValue.Type.BLANK_LINE);
}
/* istanbul ignore next */
get includesTrailingLines() {
// This is never called from anywhere, but if it were,
// this is the value it should return.
return true;
}
/**
* Parses a blank line from the source
*
* @param {ParseContext} context
* @param {number} start - Index of first \n character
* @returns {number} - Index of the character after this
*/
parse(context, start) {
this.context = context;
this.range = new PlainValue.Range(start, start + 1);
return start + 1;
}
}
class CollectionItem extends PlainValue.Node {
constructor(type, props) {
super(type, props);
this.node = null;
}
get includesTrailingLines() {
return !!this.node && this.node.includesTrailingLines;
}
/**
* @param {ParseContext} context
* @param {number} start - Index of first character
* @returns {number} - Index of the character after this
*/
parse(context, start) {
this.context = context;
const {
parseNode,
src
} = context;
let {
atLineStart,
lineStart
} = context;
if (!atLineStart && this.type === PlainValue.Type.SEQ_ITEM) this.error = new PlainValue.YAMLSemanticError(this, 'Sequence items must not have preceding content on the same line');
const indent = atLineStart ? start - lineStart : context.indent;
let offset = PlainValue.Node.endOfWhiteSpace(src, start + 1);
let ch = src[offset];
const inlineComment = ch === '#';
const comments = [];
let blankLine = null;
while (ch === '\n' || ch === '#') {
if (ch === '#') {
const end = PlainValue.Node.endOfLine(src, offset + 1);
comments.push(new PlainValue.Range(offset, end));
offset = end;
} else {
atLineStart = true;
lineStart = offset + 1;
const wsEnd = PlainValue.Node.endOfWhiteSpace(src, lineStart);
if (src[wsEnd] === '\n' && comments.length === 0) {
blankLine = new BlankLine();
lineStart = blankLine.parse({
src
}, lineStart);
}
offset = PlainValue.Node.endOfIndent(src, lineStart);
}
ch = src[offset];
}
if (PlainValue.Node.nextNodeIsIndented(ch, offset - (lineStart + indent), this.type !== PlainValue.Type.SEQ_ITEM)) {
this.node = parseNode({
atLineStart,
inCollection: false,
indent,
lineStart,
parent: this
}, offset);
} else if (ch && lineStart > start + 1) {
offset = lineStart - 1;
}
if (this.node) {
if (blankLine) {
// Only blank lines preceding non-empty nodes are captured. Note that
// this means that collection item range start indices do not always
// increase monotonically. -- eemeli/yaml#126
const items = context.parent.items || context.parent.contents;
if (items) items.push(blankLine);
}
if (comments.length) Array.prototype.push.apply(this.props, comments);
offset = this.node.range.end;
} else {
if (inlineComment) {
const c = comments[0];
this.props.push(c);
offset = c.end;
} else {
offset = PlainValue.Node.endOfLine(src, start + 1);
}
}
const end = this.node ? this.node.valueRange.end : offset;
this.valueRange = new PlainValue.Range(start, end);
return offset;
}
setOrigRanges(cr, offset) {
offset = super.setOrigRanges(cr, offset);
return this.node ? this.node.setOrigRanges(cr, offset) : offset;
}
toString() {
const {
context: {
src
},
node,
range,
value
} = this;
if (value != null) return value;
const str = node ? src.slice(range.start, node.range.start) + String(node) : src.slice(range.start, range.end);
return PlainValue.Node.addStringTerminator(src, range.end, str);
}
}
class Comment extends PlainValue.Node {
constructor() {
super(PlainValue.Type.COMMENT);
}
/**
* Parses a comment line from the source
*
* @param {ParseContext} context
* @param {number} start - Index of first character
* @returns {number} - Index of the character after this scalar
*/
parse(context, start) {
this.context = context;
const offset = this.parseComment(start);
this.range = new PlainValue.Range(start, offset);
return offset;
}
}
function grabCollectionEndComments(node) {
let cnode = node;
while (cnode instanceof CollectionItem) cnode = cnode.node;
if (!(cnode instanceof Collection)) return null;
const len = cnode.items.length;
let ci = -1;
for (let i = len - 1; i >= 0; --i) {
const n = cnode.items[i];
if (n.type === PlainValue.Type.COMMENT) {
// Keep sufficiently indented comments with preceding node
const {
indent,
lineStart
} = n.context;
if (indent > 0 && n.range.start >= lineStart + indent) break;
ci = i;
} else if (n.type === PlainValue.Type.BLANK_LINE) ci = i;else break;
}
if (ci === -1) return null;
const ca = cnode.items.splice(ci, len - ci);
const prevEnd = ca[0].range.start;
while (true) {
cnode.range.end = prevEnd;
if (cnode.valueRange && cnode.valueRange.end > prevEnd) cnode.valueRange.end = prevEnd;
if (cnode === node) break;
cnode = cnode.context.parent;
}
return ca;
}
class Collection extends PlainValue.Node {
static nextContentHasIndent(src, offset, indent) {
const lineStart = PlainValue.Node.endOfLine(src, offset) + 1;
offset = PlainValue.Node.endOfWhiteSpace(src, lineStart);
const ch = src[offset];
if (!ch) return false;
if (offset >= lineStart + indent) return true;
if (ch !== '#' && ch !== '\n') return false;
return Collection.nextContentHasIndent(src, offset, indent);
}
constructor(firstItem) {
super(firstItem.type === PlainValue.Type.SEQ_ITEM ? PlainValue.Type.SEQ : PlainValue.Type.MAP);
for (let i = firstItem.props.length - 1; i >= 0; --i) {
if (firstItem.props[i].start < firstItem.context.lineStart) {
// props on previous line are assumed by the collection
this.props = firstItem.props.slice(0, i + 1);
firstItem.props = firstItem.props.slice(i + 1);
const itemRange = firstItem.props[0] || firstItem.valueRange;
firstItem.range.start = itemRange.start;
break;
}
}
this.items = [firstItem];
const ec = grabCollectionEndComments(firstItem);
if (ec) Array.prototype.push.apply(this.items, ec);
}
get includesTrailingLines() {
return this.items.length > 0;
}
/**
* @param {ParseContext} context
* @param {number} start - Index of first character
* @returns {number} - Index of the character after this
*/
parse(context, start) {
this.context = context;
const {
parseNode,
src
} = context; // It's easier to recalculate lineStart here rather than tracking down the
// last context from which to read it -- eemeli/yaml#2
let lineStart = PlainValue.Node.startOfLine(src, start);
const firstItem = this.items[0]; // First-item context needs to be correct for later comment handling
// -- eemeli/yaml#17
firstItem.context.parent = this;
this.valueRange = PlainValue.Range.copy(firstItem.valueRange);
const indent = firstItem.range.start - firstItem.context.lineStart;
let offset = start;
offset = PlainValue.Node.normalizeOffset(src, offset);
let ch = src[offset];
let atLineStart = PlainValue.Node.endOfWhiteSpace(src, lineStart) === offset;
let prevIncludesTrailingLines = false;
while (ch) {
while (ch === '\n' || ch === '#') {
if (atLineStart && ch === '\n' && !prevIncludesTrailingLines) {
const blankLine = new BlankLine();
offset = blankLine.parse({
src
}, offset);
this.valueRange.end = offset;
if (offset >= src.length) {
ch = null;
break;
}
this.items.push(blankLine);
offset -= 1; // blankLine.parse() consumes terminal newline
} else if (ch === '#') {
if (offset < lineStart + indent && !Collection.nextContentHasIndent(src, offset, indent)) {
return offset;
}
const comment = new Comment();
offset = comment.parse({
indent,
lineStart,
src
}, offset);
this.items.push(comment);
this.valueRange.end = offset;
if (offset >= src.length) {
ch = null;
break;
}
}
lineStart = offset + 1;
offset = PlainValue.Node.endOfIndent(src, lineStart);
if (PlainValue.Node.atBlank(src, offset)) {
const wsEnd = PlainValue.Node.endOfWhiteSpace(src, offset);
const next = src[wsEnd];
if (!next || next === '\n' || next === '#') {
offset = wsEnd;
}
}
ch = src[offset];
atLineStart = true;
}
if (!ch) {
break;
}
if (offset !== lineStart + indent && (atLineStart || ch !== ':')) {
if (offset < lineStart + indent) {
if (lineStart > start) offset = lineStart;
break;
} else if (!this.error) {
const msg = 'All collection items must start at the same column';
this.error = new PlainValue.YAMLSyntaxError(this, msg);
}
}
if (firstItem.type === PlainValue.Type.SEQ_ITEM) {
if (ch !== '-') {
if (lineStart > start) offset = lineStart;
break;
}
} else if (ch === '-' && !this.error) {
// map key may start with -, as long as it's followed by a non-whitespace char
const next = src[offset + 1];
if (!next || next === '\n' || next === '\t' || next === ' ') {
const msg = 'A collection cannot be both a mapping and a sequence';
this.error = new PlainValue.YAMLSyntaxError(this, msg);
}
}
const node = parseNode({
atLineStart,
inCollection: true,
indent,
lineStart,
parent: this
}, offset);
if (!node) return offset; // at next document start
this.items.push(node);
this.valueRange.end = node.valueRange.end;
offset = PlainValue.Node.normalizeOffset(src, node.range.end);
ch = src[offset];
atLineStart = false;
prevIncludesTrailingLines = node.includesTrailingLines; // Need to reset lineStart and atLineStart here if preceding node's range
// has advanced to check the current line's indentation level
// -- eemeli/yaml#10 & eemeli/yaml#38
if (ch) {
let ls = offset - 1;
let prev = src[ls];
while (prev === ' ' || prev === '\t') prev = src[--ls];
if (prev === '\n') {
lineStart = ls + 1;
atLineStart = true;
}
}
const ec = grabCollectionEndComments(node);
if (ec) Array.prototype.push.apply(this.items, ec);
}
return offset;
}
setOrigRanges(cr, offset) {
offset = super.setOrigRanges(cr, offset);
this.items.forEach(node => {
offset = node.setOrigRanges(cr, offset);
});
return offset;
}
toString() {
const {
context: {
src
},
items,
range,
value
} = this;
if (value != null) return value;
let str = src.slice(range.start, items[0].range.start) + String(items[0]);
for (let i = 1; i < items.length; ++i) {
const item = items[i];
const {
atLineStart,
indent
} = item.context;
if (atLineStart) for (let i = 0; i < indent; ++i) str += ' ';
str += String(item);
}
return PlainValue.Node.addStringTerminator(src, range.end, str);
}
}
class Directive extends PlainValue.Node {
constructor() {
super(PlainValue.Type.DIRECTIVE);
this.name = null;
}
get parameters() {
const raw = this.rawValue;
return raw ? raw.trim().split(/[ \t]+/) : [];
}
parseName(start) {
const {
src
} = this.context;
let offset = start;
let ch = src[offset];
while (ch && ch !== '\n' && ch !== '\t' && ch !== ' ') ch = src[offset += 1];
this.name = src.slice(start, offset);
return offset;
}
parseParameters(start) {
const {
src
} = this.context;
let offset = start;
let ch = src[offset];
while (ch && ch !== '\n' && ch !== '#') ch = src[offset += 1];
this.valueRange = new PlainValue.Range(start, offset);
return offset;
}
parse(context, start) {
this.context = context;
let offset = this.parseName(start + 1);
offset = this.parseParameters(offset);
offset = this.parseComment(offset);
this.range = new PlainValue.Range(start, offset);
return offset;
}
}
class Document extends PlainValue.Node {
static startCommentOrEndBlankLine(src, start) {
const offset = PlainValue.Node.endOfWhiteSpace(src, start);
const ch = src[offset];
return ch === '#' || ch === '\n' ? offset : start;
}
constructor() {
super(PlainValue.Type.DOCUMENT);
this.directives = null;
this.contents = null;
this.directivesEndMarker = null;
this.documentEndMarker = null;
}
parseDirectives(start) {
const {
src
} = this.context;
this.directives = [];
let atLineStart = true;
let hasDirectives = false;
let offset = start;
while (!PlainValue.Node.atDocumentBoundary(src, offset, PlainValue.Char.DIRECTIVES_END)) {
offset = Document.startCommentOrEndBlankLine(src, offset);
switch (src[offset]) {
case '\n':
if (atLineStart) {
const blankLine = new BlankLine();
offset = blankLine.parse({
src
}, offset);
if (offset < src.length) {
this.directives.push(blankLine);
}
} else {
offset += 1;
atLineStart = true;
}
break;
case '#':
{
const comment = new Comment();
offset = comment.parse({
src
}, offset);
this.directives.push(comment);
atLineStart = false;
}
break;
case '%':
{
const directive = new Directive();
offset = directive.parse({
parent: this,
src
}, offset);
this.directives.push(directive);
hasDirectives = true;
atLineStart = false;
}
break;
default:
if (hasDirectives) {
this.error = new PlainValue.YAMLSemanticError(this, 'Missing directives-end indicator line');
} else if (this.directives.length > 0) {
this.contents = this.directives;
this.directives = [];
}
return offset;
}
}
if (src[offset]) {
this.directivesEndMarker = new PlainValue.Range(offset, offset + 3);
return offset + 3;
}
if (hasDirectives) {
this.error = new PlainValue.YAMLSemanticError(this, 'Missing directives-end indicator line');
} else if (this.directives.length > 0) {
this.contents = this.directives;
this.directives = [];
}
return offset;
}
parseContents(start) {
const {
parseNode,
src
} = this.context;
if (!this.contents) this.contents = [];
let lineStart = start;
while (src[lineStart - 1] === '-') lineStart -= 1;
let offset = PlainValue.Node.endOfWhiteSpace(src, start);
let atLineStart = lineStart === start;
this.valueRange = new PlainValue.Range(offset);
while (!PlainValue.Node.atDocumentBoundary(src, offset, PlainValue.Char.DOCUMENT_END)) {
switch (src[offset]) {
case '\n':
if (atLineStart) {
const blankLine = new BlankLine();
offset = blankLine.parse({
src
}, offset);
if (offset < src.length) {
this.contents.push(blankLine);
}
} else {
offset += 1;
atLineStart = true;
}
lineStart = offset;
break;
case '#':
{
const comment = new Comment();
offset = comment.parse({
src
}, offset);
this.contents.push(comment);
atLineStart = false;
}
break;
default:
{
const iEnd = PlainValue.Node.endOfIndent(src, offset);
const context = {
atLineStart,
indent: -1,
inFlow: false,
inCollection: false,
lineStart,
parent: this
};
const node = parseNode(context, iEnd);
if (!node) return this.valueRange.end = iEnd; // at next document start
this.contents.push(node);
offset = node.range.end;
atLineStart = false;
const ec = grabCollectionEndComments(node);
if (ec) Array.prototype.push.apply(this.contents, ec);
}
}
offset = Document.startCommentOrEndBlankLine(src, offset);
}
this.valueRange.end = offset;
if (src[offset]) {
this.documentEndMarker = new PlainValue.Range(offset, offset + 3);
offset += 3;
if (src[offset]) {
offset = PlainValue.Node.endOfWhiteSpace(src, offset);
if (src[offset] === '#') {
const comment = new Comment();
offset = comment.parse({
src
}, offset);
this.contents.push(comment);
}
switch (src[offset]) {
case '\n':
offset += 1;
break;
case undefined:
break;
default:
this.error = new PlainValue.YAMLSyntaxError(this, 'Document end marker line cannot have a non-comment suffix');
}
}
}
return offset;
}
/**
* @param {ParseContext} context
* @param {number} start - Index of first character
* @returns {number} - Index of the character after this
*/
parse(context, start) {
context.root = this;
this.context = context;
const {
src
} = context;
let offset = src.charCodeAt(start) === 0xfeff ? start + 1 : start; // skip BOM
offset = this.parseDirectives(offset);
offset = this.parseContents(offset);
return offset;
}
setOrigRanges(cr, offset) {
offset = super.setOrigRanges(cr, offset);
this.directives.forEach(node => {
offset = node.setOrigRanges(cr, offset);
});
if (this.directivesEndMarker) offset = this.directivesEndMarker.setOrigRange(cr, offset);
this.contents.forEach(node => {
offset = node.setOrigRanges(cr, offset);
});
if (this.documentEndMarker) offset = this.documentEndMarker.setOrigRange(cr, offset);
return offset;
}
toString() {
const {
contents,
directives,
value
} = this;
if (value != null) return value;
let str = directives.join('');
if (contents.length > 0) {
if (directives.length > 0 || contents[0].type === PlainValue.Type.COMMENT) str += '---\n';
str += contents.join('');
}
if (str[str.length - 1] !== '\n') str += '\n';
return str;
}
}
class Alias extends PlainValue.Node {
/**
* Parses an *alias from the source
*
* @param {ParseContext} context
* @param {number} start - Index of first character
* @returns {number} - Index of the character after this scalar
*/
parse(context, start) {
this.context = context;
const {
src
} = context;
let offset = PlainValue.Node.endOfIdentifier(src, start + 1);
this.valueRange = new PlainValue.Range(start + 1, offset);
offset = PlainValue.Node.endOfWhiteSpace(src, offset);
offset = this.parseComment(offset);
return offset;
}
}
const Chomp = {
CLIP: 'CLIP',
KEEP: 'KEEP',
STRIP: 'STRIP'
};
class BlockValue extends PlainValue.Node {
constructor(type, props) {
super(type, props);
this.blockIndent = null;
this.chomping = Chomp.CLIP;
this.header = null;
}
get includesTrailingLines() {
return this.chomping === Chomp.KEEP;
}
get strValue() {
if (!this.valueRange || !this.context) return null;
let {
start,
end
} = this.valueRange;
const {
indent,
src
} = this.context;
if (this.valueRange.isEmpty()) return '';
let lastNewLine = null;
let ch = src[end - 1];
while (ch === '\n' || ch === '\t' || ch === ' ') {
end -= 1;
if (end <= start) {
if (this.chomping === Chomp.KEEP) break;else return ''; // probably never happens
}
if (ch === '\n') lastNewLine = end;
ch = src[end - 1];
}
let keepStart = end + 1;
if (lastNewLine) {
if (this.chomping === Chomp.KEEP) {
keepStart = lastNewLine;
end = this.valueRange.end;
} else {
end = lastNewLine;
}
}
const bi = indent + this.blockIndent;
const folded = this.type === PlainValue.Type.BLOCK_FOLDED;
let atStart = true;
let str = '';
let sep = '';
let prevMoreIndented = false;
for (let i = start; i < end; ++i) {
for (let j = 0; j < bi; ++j) {
if (src[i] !== ' ') break;
i += 1;
}
const ch = src[i];
if (ch === '\n') {
if (sep === '\n') str += '\n';else sep = '\n';
} else {
const lineEnd = PlainValue.Node.endOfLine(src, i);
const line = src.slice(i, lineEnd);
i = lineEnd;
if (folded && (ch === ' ' || ch === '\t') && i < keepStart) {
if (sep === ' ') sep = '\n';else if (!prevMoreIndented && !atStart && sep === '\n') sep = '\n\n';
str += sep + line; //+ ((lineEnd < end && src[lineEnd]) || '')
sep = lineEnd < end && src[lineEnd] || '';
prevMoreIndented = true;
} else {
str += sep + line;
sep = folded && i < keepStart ? ' ' : '\n';
prevMoreIndented = false;
}
if (atStart && line !== '') atStart = false;
}
}
return this.chomping === Chomp.STRIP ? str : str + '\n';
}
parseBlockHeader(start) {
const {
src
} = this.context;
let offset = start + 1;
let bi = '';
while (true) {
const ch = src[offset];
switch (ch) {
case '-':
this.chomping = Chomp.STRIP;
break;
case '+':
this.chomping = Chomp.KEEP;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
bi += ch;
break;
default:
this.blockIndent = Number(bi) || null;
this.header = new PlainValue.Range(start, offset);
return offset;
}
offset += 1;
}
}
parseBlockValue(start) {
const {
indent,
src
} = this.context;
const explicit = !!this.blockIndent;
let offset = start;
let valueEnd = start;
let minBlockIndent = 1;
for (let ch = src[offset]; ch === '\n'; ch = src[offset]) {
offset += 1;
if (PlainValue.Node.atDocumentBoundary(src, offset)) break;
const end = PlainValue.Node.endOfBlockIndent(src, indent, offset); // should not include tab?
if (end === null) break;
const ch = src[end];
const lineIndent = end - (offset + indent);
if (!this.blockIndent) {
// no explicit block indent, none yet detected
if (src[end] !== '\n') {
// first line with non-whitespace content
if (lineIndent < minBlockIndent) {
const msg = 'Block scalars with more-indented leading empty lines must use an explicit indentation indicator';
this.error = new PlainValue.YAMLSemanticError(this, msg);
}
this.blockIndent = lineIndent;
} else if (lineIndent > minBlockIndent) {
// empty line with more whitespace
minBlockIndent = lineIndent;
}
} else if (ch && ch !== '\n' && lineIndent < this.blockIndent) {
if (src[end] === '#') break;
if (!this.error) {
const src = explicit ? 'explicit indentation indicator' : 'first line';
const msg = `Block scalars must not be less indented than their ${src}`;
this.error = new PlainValue.YAMLSemanticError(this, msg);
}
}
if (src[end] === '\n') {
offset = end;
} else {
offset = valueEnd = PlainValue.Node.endOfLine(src, end);
}
}
if (this.chomping !== Chomp.KEEP) {
offset = src[valueEnd] ? valueEnd + 1 : valueEnd;
}
this.valueRange = new PlainValue.Range(start + 1, offset);
return offset;
}
/**
* Parses a block value from the source
*
* Accepted forms are:
* ```
* BS
* block
* lines
*
* BS #comment
* block
* lines
* ```
* where the block style BS matches the regexp `[|>][-+1-9]*` and block lines
* are empty or have an indent level greater than `indent`.
*
* @param {ParseContext} context
* @param {number} start - Index of first character
* @returns {number} - Index of the character after this block
*/
parse(context, start) {
this.context = context;
const {
src
} = context;
let offset = this.parseBlockHeader(start);
offset = PlainValue.Node.endOfWhiteSpace(src, offset);
offset = this.parseComment(offset);
offset = this.parseBlockValue(offset);
return offset;
}
setOrigRanges(cr, offset) {
offset = super.setOrigRanges(cr, offset);
return this.header ? this.header.setOrigRange(cr, offset) : offset;
}
}
class FlowCollection extends PlainValue.Node {
constructor(type, props) {
super(type, props);
this.items = null;
}
prevNodeIsJsonLike(idx = this.items.length) {
const node = this.items[idx - 1];
return !!node && (node.jsonLike || node.type === PlainValue.Type.COMMENT && this.prevNodeIsJsonLike(idx - 1));
}
/**
* @param {ParseContext} context
* @param {number} start - Index of first character
* @returns {number} - Index of the character after this
*/
parse(context, start) {
this.context = context;
const {
parseNode,
src
} = context;
let {
indent,
lineStart
} = context;
let char = src[start]; // { or [
this.items = [{
char,
offset: start
}];
let offset = PlainValue.Node.endOfWhiteSpace(src, start + 1);
char = src[offset];
while (char && char !== ']' && char !== '}') {
switch (char) {
case '\n':
{
lineStart = offset + 1;
const wsEnd = PlainValue.Node.endOfWhiteSpace(src, lineStart);
if (src[wsEnd] === '\n') {
const blankLine = new BlankLine();
lineStart = blankLine.parse({
src
}, lineStart);
this.items.push(blankLine);
}
offset = PlainValue.Node.endOfIndent(src, lineStart);
if (offset <= lineStart + indent) {
char = src[offset];
if (offset < lineStart + indent || char !== ']' && char !== '}') {
const msg = 'Insufficient indentation in flow collection';
this.error = new PlainValue.YAMLSemanticError(this, msg);
}
}
}
break;
case ',':
{
this.items.push({
char,
offset
});
offset += 1;
}
break;
case '#':
{
const comment = new Comment();
offset = comment.parse({
src
}, offset);
this.items.push(comment);
}
break;
case '?':
case ':':
{
const next = src[offset + 1];
if (next === '\n' || next === '\t' || next === ' ' || next === ',' || // in-flow : after JSON-like key does not need to be followed by whitespace
char === ':' && this.prevNodeIsJsonLike()) {
this.items.push({
char,
offset
});
offset += 1;
break;
}
}
// fallthrough
default:
{
const node = parseNode({
atLineStart: false,
inCollection: false,
inFlow: true,
indent: -1,
lineStart,
parent: this
}, offset);
if (!node) {
// at next document start
this.valueRange = new PlainValue.Range(start, offset);
return offset;
}
this.items.push(node);
offset = PlainValue.Node.normalizeOffset(src, node.range.end);
}
}
offset = PlainValue.Node.endOfWhiteSpace(src, offset);
char = src[offset];
}
this.valueRange = new PlainValue.Range(start, offset + 1);
if (char) {
this.items.push({
char,
offset
});
offset = PlainValue.Node.endOfWhiteSpace(src, offset + 1);
offset = this.parseComment(offset);
}
return offset;
}
setOrigRanges(cr, offset) {
offset = super.setOrigRanges(cr, offset);
this.items.forEach(node => {
if (node instanceof PlainValue.Node) {
offset = node.setOrigRanges(cr, offset);
} else if (cr.length === 0) {
node.origOffset = node.offset;
} else {
let i = offset;
while (i < cr.length) {
if (cr[i] > node.offset) break;else ++i;
}
node.origOffset = node.offset + i;
offset = i;
}
});
return offset;
}
toString() {
const {
context: {
src
},
items,
range,
value
} = this;
if (value != null) return value;
const nodes = items.filter(item => item instanceof PlainValue.Node);
let str = '';
let prevEnd = range.start;
nodes.forEach(node => {
const prefix = src.slice(prevEnd, node.range.start);
prevEnd = node.range.end;
str += prefix + String(node);
if (str[str.length - 1] === '\n' && src[prevEnd - 1] !== '\n' && src[prevEnd] === '\n') {
// Comment range does not include the terminal newline, but its
// stringified value does. Without this fix, newlines at comment ends
// get duplicated.
prevEnd += 1;
}
});
str += src.slice(prevEnd, range.end);
return PlainValue.Node.addStringTerminator(src, range.end, str);
}
}
class QuoteDouble extends PlainValue.Node {
static endOfQuote(src, offset) {
let ch = src[offset];
while (ch && ch !== '"') {
offset += ch === '\\' ? 2 : 1;
ch = src[offset];
}
return offset + 1;
}
/**
* @returns {string | { str: string, errors: YAMLSyntaxError[] }}
*/
get strValue() {
if (!this.valueRange || !this.context) return null;
const errors = [];
const {
start,
end
} = this.valueRange;
const {
indent,
src
} = this.context;
if (src[end - 1] !== '"') errors.push(new PlainValue.YAMLSyntaxError(this, 'Missing closing "quote')); // Using String#replace is too painful with escaped newlines preceded by
// escaped backslashes; also, this should be faster.
let str = '';
for (let i = start + 1; i < end - 1; ++i) {
const ch = src[i];
if (ch === '\n') {
if (PlainValue.Node.atDocumentBoundary(src, i + 1)) errors.push(new PlainValue.YAMLSemanticError(this, 'Document boundary indicators are not allowed within string values'));
const {
fold,
offset,
error
} = PlainValue.Node.foldNewline(src, i, indent);
str += fold;
i = offset;
if (error) errors.push(new PlainValue.YAMLSemanticError(this, 'Multi-line double-quoted string needs to be sufficiently indented'));
} else if (ch === '\\') {
i += 1;
switch (src[i]) {
case '0':
str += '\0';
break;
// null character
case 'a':
str += '\x07';
break;
// bell character
case 'b':
str += '\b';
break;
// backspace
case 'e':
str += '\x1b';
break;
// escape character
case 'f':
str += '\f';
break;
// form feed
case 'n':
str += '\n';
break;
// line feed
case 'r':
str += '\r';
break;
// carriage return
case 't':
str += '\t';
break;
// horizontal tab
case 'v':
str += '\v';
break;
// vertical tab
case 'N':
str += '\u0085';
break;
// Unicode next line
case '_':
str += '\u00a0';
break;
// Unicode non-breaking space
case 'L':
str += '\u2028';
break;
// Unicode line separator
case 'P':
str += '\u2029';
break;
// Unicode paragraph separator
case ' ':
str += ' ';
break;
case '"':
str += '"';
break;
case '/':
str += '/';
break;
case '\\':
str += '\\';
break;
case '\t':
str += '\t';
break;
case 'x':
str += this.parseCharCode(i + 1, 2, errors);
i += 2;
break;
case 'u':
str += this.parseCharCode(i + 1, 4, errors);
i += 4;
break;
case 'U':
str += this.parseCharCode(i + 1, 8, errors);
i += 8;
break;
case '\n':
// skip escaped newlines, but still trim the following line
while (src[i + 1] === ' ' || src[i + 1] === '\t') i += 1;
break;
default:
errors.push(new PlainValue.YAMLSyntaxError(this, `Invalid escape sequence ${src.substr(i - 1, 2)}`));
str += '\\' + src[i];
}
} else if (ch === ' ' || ch === '\t') {
// trim trailing whitespace
const wsStart = i;
let next = src[i + 1];
while (next === ' ' || next === '\t') {
i += 1;
next = src[i + 1];
}
if (next !== '\n') str += i > wsStart ? src.slice(wsStart, i + 1) : ch;
} else {
str += ch;
}
}
return errors.length > 0 ? {
errors,
str
} : str;
}
parseCharCode(offset, length, errors) {
const {
src
} = this.context;
const cc = src.substr(offset, length);
const ok = cc.length === length && /^[0-9a-fA-F]+$/.test(cc);
const code = ok ? parseInt(cc, 16) : NaN;
if (isNaN(code)) {
errors.push(new PlainValue.YAMLSyntaxError(this, `Invalid escape sequence ${src.substr(offset - 2, length + 2)}`));
return src.substr(offset - 2, length + 2);
}
return String.fromCodePoint(code);
}
/**
* Parses a "double quoted" value from the source
*
* @param {ParseContext} context
* @param {number} start - Index of first character
* @returns {number} - Index of the character after this scalar
*/
parse(context, start) {
this.context = context;
const {
src
} = context;
let offset = QuoteDouble.endOfQuote(src, start + 1);
this.valueRange = new PlainValue.Range(start, offset);
offset = PlainValue.Node.endOfWhiteSpace(src, offset);
offset = this.parseComment(offset);
return offset;
}
}
class QuoteSingle extends PlainValue.Node {
static endOfQuote(src, offset) {
let ch = src[offset];
while (ch) {
if (ch === "'") {
if (src[offset + 1] !== "'") break;
ch = src[offset += 2];
} else {
ch = src[offset += 1];
}
}
return offset + 1;
}
/**
* @returns {string | { str: string, errors: YAMLSyntaxError[] }}
*/
get strValue() {
if (!this.valueRange || !this.context) return null;
const errors = [];
const {
start,
end
} = this.valueRange;
const {
indent,
src
} = this.context;
if (src[end - 1] !== "'") errors.push(new PlainValue.YAMLSyntaxError(this, "Missing closing 'quote"));
let str = '';
for (let i = start + 1; i < end - 1; ++i) {
const ch = src[i];
if (ch === '\n') {
if (PlainValue.Node.atDocumentBoundary(src, i + 1)) errors.push(new PlainValue.YAMLSemanticError(this, 'Document boundary indicators are not allowed within string values'));
const {
fold,
offset,
error
} = PlainValue.Node.foldNewline(src, i, indent);
str += fold;
i = offset;
if (error) errors.push(new PlainValue.YAMLSemanticError(this, 'Multi-line single-quoted string needs to be sufficiently indented'));
} else if (ch === "'") {
str += ch;
i += 1;
if (src[i] !== "'") errors.push(new PlainValue.YAMLSyntaxError(this, 'Unescaped single quote? This should not happen.'));
} else if (ch === ' ' || ch === '\t') {
// trim trailing whitespace
const wsStart = i;
let next = src[i + 1];
while (next === ' ' || next === '\t') {
i += 1;
next = src[i + 1];
}
if (next !== '\n') str += i > wsStart ? src.slice(wsStart, i + 1) : ch;
} else {
str += ch;
}
}
return errors.length > 0 ? {
errors,
str
} : str;
}
/**
* Parses a 'single quoted' value from the source
*
* @param {ParseContext} context
* @param {number} start - Index of first character
* @returns {number} - Index of the character after this scalar
*/
parse(context, start) {
this.context = context;
const {
src
} = context;
let offset = QuoteSingle.endOfQuote(src, start + 1);
this.valueRange = new PlainValue.Range(start, offset);
offset = PlainValue.Node.endOfWhiteSpace(src, offset);
offset = this.parseComment(offset);
return offset;
}
}
function createNewNode(type, props) {
switch (type) {
case PlainValue.Type.ALIAS:
return new Alias(type, props);
case PlainValue.Type.BLOCK_FOLDED:
case PlainValue.Type.BLOCK_LITERAL:
return new BlockValue(type, props);
case PlainValue.Type.FLOW_MAP:
case PlainValue.Type.FLOW_SEQ:
return new FlowCollection(type, props);
case PlainValue.Type.MAP_KEY:
case PlainValue.Type.MAP_VALUE:
case PlainValue.Type.SEQ_ITEM:
return new CollectionItem(type, props);
case PlainValue.Type.COMMENT:
case PlainValue.Type.PLAIN:
return new PlainValue.PlainValue(type, props);
case PlainValue.Type.QUOTE_DOUBLE:
return new QuoteDouble(type, props);
case PlainValue.Type.QUOTE_SINGLE:
return new QuoteSingle(type, props);
/* istanbul ignore next */
default:
return null;
// should never happen
}
}
/**
* @param {boolean} atLineStart - Node starts at beginning of line
* @param {boolean} inFlow - true if currently in a flow context
* @param {boolean} inCollection - true if currently in a collection context
* @param {number} indent - Current level of indentation
* @param {number} lineStart - Start of the current line
* @param {Node} parent - The parent of the node
* @param {string} src - Source of the YAML document
*/
class ParseContext {
static parseType(src, offset, inFlow) {
switch (src[offset]) {
case '*':
return PlainValue.Type.ALIAS;
case '>':
return PlainValue.Type.BLOCK_FOLDED;
case '|':
return PlainValue.Type.BLOCK_LITERAL;
case '{':
return PlainValue.Type.FLOW_MAP;
case '[':
return PlainValue.Type.FLOW_SEQ;
case '?':
return !inFlow && PlainValue.Node.atBlank(src, offset + 1, true) ? PlainValue.Type.MAP_KEY : PlainValue.Type.PLAIN;
case ':':
return !inFlow && PlainValue.Node.atBlank(src, offset + 1, true) ? PlainValue.Type.MAP_VALUE : PlainValue.Type.PLAIN;
case '-':
return !inFlow && PlainValue.Node.atBlank(src, offset + 1, true) ? PlainValue.Type.SEQ_ITEM : PlainValue.Type.PLAIN;
case '"':
return PlainValue.Type.QUOTE_DOUBLE;
case "'":
return PlainValue.Type.QUOTE_SINGLE;
default:
return PlainValue.Type.PLAIN;
}
}
constructor(orig = {}, {
atLineStart,
inCollection,
inFlow,
indent,
lineStart,
parent
} = {}) {
PlainValue._defineProperty(this, "parseNode", (overlay, start) => {
if (PlainValue.Node.atDocumentBoundary(this.src, start)) return null;
const context = new ParseContext(this, overlay);
const {
props,
type,
valueStart
} = context.parseProps(start);
const node = createNewNode(type, props);
let offset = node.parse(context, valueStart);
node.range = new PlainValue.Range(start, offset);
/* istanbul ignore if */
if (offset <= start) {
// This should never happen, but if it does, let's make sure to at least
// step one character forward to avoid a busy loop.
node.error = new Error(`Node#parse consumed no characters`);
node.error.parseEnd = offset;
node.error.source = node;
node.range.end = start + 1;
}
if (context.nodeStartsCollection(node)) {
if (!node.error && !context.atLineStart && context.parent.type === PlainValue.Type.DOCUMENT) {
node.error = new PlainValue.YAMLSyntaxError(node, 'Block collection must not have preceding content here (e.g. directives-end indicator)');
}
const collection = new Collection(node);
offset = collection.parse(new ParseContext(context), offset);
collection.range = new PlainValue.Range(start, offset);
return collection;
}
return node;
});
this.atLineStart = atLineStart != null ? atLineStart : orig.atLineStart || false;
this.inCollection = inCollection != null ? inCollection : orig.inCollection || false;
this.inFlow = inFlow != null ? inFlow : orig.inFlow || false;
this.indent = indent != null ? indent : orig.indent;
this.lineStart = lineStart != null ? lineStart : orig.lineStart;
this.parent = parent != null ? parent : orig.parent || {};
this.root = orig.root;
this.src = orig.src;
}
nodeStartsCollection(node) {
const {
inCollection,
inFlow,
src
} = this;
if (inCollection || inFlow) return false;
if (node instanceof CollectionItem) return true; // check for implicit key
let offset = node.range.end;
if (src[offset] === '\n' || src[offset - 1] === '\n') return false;
offset = PlainValue.Node.endOfWhiteSpace(src, offset);
return src[offset] === ':';
} // Anchor and tag are before type, which determines the node implementation
// class; hence this intermediate step.
parseProps(offset) {
const {
inFlow,
parent,
src
} = this;
const props = [];
let lineHasProps = false;
offset = this.atLineStart ? PlainValue.Node.endOfIndent(src, offset) : PlainValue.Node.endOfWhiteSpace(src, offset);
let ch = src[offset];
while (ch === PlainValue.Char.ANCHOR || ch === PlainValue.Char.COMMENT || ch === PlainValue.Char.TAG || ch === '\n') {
if (ch === '\n') {
const lineStart = offset + 1;
const inEnd = PlainValue.Node.endOfIndent(src, lineStart);
const indentDiff = inEnd - (lineStart + this.indent);
const noIndicatorAsIndent = parent.type === PlainValue.Type.SEQ_ITEM && parent.context.atLineStart;
if (!PlainValue.Node.nextNodeIsIndented(src[inEnd], indentDiff, !noIndicatorAsIndent)) break;
this.atLineStart = true;
this.lineStart = lineStart;
lineHasProps = false;
offset = inEnd;
} else if (ch === PlainValue.Char.COMMENT) {
const end = PlainValue.Node.endOfLine(src, offset + 1);
props.push(new PlainValue.Range(offset, end));
offset = end;
} else {
let end = PlainValue.Node.endOfIdentifier(src, offset + 1);
if (ch === PlainValue.Char.TAG && src[end] === ',' && /^[a-zA-Z0-9-]+\.[a-zA-Z0-9-]+,\d\d\d\d(-\d\d){0,2}\/\S/.test(src.slice(offset + 1, end + 13))) {
// Let's presume we're dealing with a YAML 1.0 domain tag here, rather
// than an empty but 'foo.bar' private-tagged node in a flow collection
// followed without whitespace by a plain string starting with a year
// or date divided by something.
end = PlainValue.Node.endOfIdentifier(src, end + 5);
}
props.push(new PlainValue.Range(offset, end));
lineHasProps = true;
offset = PlainValue.Node.endOfWhiteSpace(src, end);
}
ch = src[offset];
} // '- &a : b' has an anchor on an empty node
if (lineHasProps && ch === ':' && PlainValue.Node.atBlank(src, offset + 1, true)) offset -= 1;
const type = ParseContext.parseType(src, offset, inFlow);
return {
props,
type,
valueStart: offset
};
}
/**
* Parses a node from the source
* @param {ParseContext} overlay
* @param {number} start - Index of first non-whitespace character for the node
* @returns {?Node} - null if at a document boundary
*/
}
// Published as 'yaml/parse-cst'
function parse(src) {
const cr = [];
if (src.indexOf('\r') !== -1) {
src = src.replace(/\r\n?/g, (match, offset) => {
if (match.length > 1) cr.push(offset);
return '\n';
});
}
const documents = [];
let offset = 0;
do {
const doc = new Document();
const context = new ParseContext({
src
});
offset = doc.parse(context, offset);
documents.push(doc);
} while (offset < src.length);
documents.setOrigRanges = () => {
if (cr.length === 0) return false;
for (let i = 1; i < cr.length; ++i) cr[i] -= i;
let crOffset = 0;
for (let i = 0; i < documents.length; ++i) {
crOffset = documents[i].setOrigRanges(cr, crOffset);
}
cr.splice(0, cr.length);
return true;
};
documents.toString = () => documents.join('...\n');
return documents;
}
exports.parse = parse;
exports.parse = parseCst.parse;
'use strict';
require('./PlainValue-ec8e588e.js');
var parseCst = require('./parse-cst.js');
require('./resolveSeq-4a68b39b.js');
var Document$1 = require('./Document-2cf6b08c.js');
require('./Schema-42e9705c.js');
require('./warnings-39684f17.js');
var parseCst = require('./parse-ab8de154.js');
require('./resolveSeq-6b2dc4ac.js');
var Document = require('./Document-59bd9290.js');
require('./Schema-fe1471c4.js');

@@ -16,3 +15,3 @@ function testEvents(src, options) {

}, options);
const docs = parseCst.parse(src).map(cstDoc => new Document$1.Document(opt).parse(cstDoc));
const docs = parseCst.parse(src).map(cstDoc => new Document.Document(null, opt).parse(cstDoc));
const errDoc = docs.find(doc => doc.errors.length > 0);

@@ -19,0 +18,0 @@ const error = errDoc ? errDoc.errors[0].message : null;

'use strict';
require('./PlainValue-ec8e588e.js');
var resolveSeq = require('./resolveSeq-4a68b39b.js');
var Schema = require('./Schema-42e9705c.js');
require('./warnings-39684f17.js');
var resolveSeq = require('./resolveSeq-6b2dc4ac.js');
var Schema = require('./Schema-fe1471c4.js');

@@ -8,0 +7,0 @@

'use strict';
var PlainValue = require('./PlainValue-ec8e588e.js');
var resolveSeq = require('./resolveSeq-4a68b39b.js');
var resolveSeq = require('./resolveSeq-6b2dc4ac.js');

@@ -6,0 +6,0 @@

@@ -8,2 +8,3 @@ import { CST } from './parse-cst'

Node,
Pair,
Scalar,

@@ -82,3 +83,3 @@ Schema,

*
* Default: `false`
* Default: `true`
*/

@@ -162,3 +163,3 @@ prettyErrors?: boolean

/**
* The default type of string literal used to stringify values
* The default type of string literal used to stringify values in general
*

@@ -168,2 +169,14 @@ * Default: `'PLAIN'`

defaultType: Scalar.Type
/**
* The default type of string literal used to stringify implicit key values
*
* Default: `'PLAIN'`
*/
defaultKeyType: Scalar.Type
/**
* Use 'single quote' rather than "double quote" by default
*
* Default: `false`
*/
defaultQuoteSingle: boolean
doubleQuoted: {

@@ -202,3 +215,7 @@ /**

cstNode?: CST.Document
constructor(options?: Options)
/**
* @param value - The initial value for the document, which will be wrapped
* in a Node container.
*/
constructor(value?: any, options?: Options)
tag: never

@@ -233,3 +250,25 @@ directivesEndMarker?: boolean

warnings: YAMLWarning[]
/**
* Convert any value into a `Node` using the current schema, recursively
* turning objects into collections.
*
* @param options Use `tag` to specify the collection type, e.g. `"!!omap"`.
* Note that this requires the corresponding tag to be available in this
* document's schema. If `wrapScalars` is not `false`, also wraps plain
* values in `Scalar` objects.
*/
createNode(
value: any,
options?: { tag?: string; wrapScalars?: boolean }
): Node
/**
* Convert a key and a value into a `Pair` using the current schema,
* recursively wrapping all values as `Scalar` or `Collection` nodes.
*
* @param options If `wrapScalars` is not `false`, wraps plain values in
* `Scalar` objects.
*/
createPair(key: any, value: any, options?: { wrapScalars?: boolean }): Pair
/**
* List the tags used in the document that are not in the default

@@ -236,0 +275,0 @@ * `tag:yaml.org,2002:` namespace.

{
"name": "yaml",
"version": "1.10.0",
"version": "2.0.0-0",
"license": "ISC",

@@ -27,15 +27,5 @@ "author": "Eemeli Aro <eemeli@gmail.com>",

"./index.js": "./browser/index.js",
"./map.js": "./browser/map.js",
"./pair.js": "./browser/pair.js",
"./parse-cst.js": "./browser/parse-cst.js",
"./scalar.js": "./browser/scalar.js",
"./schema.js": "./browser/schema.js",
"./seq.js": "./browser/seq.js",
"./types.js": "./browser/types.js",
"./types.mjs": "./browser/types.js",
"./types/binary.js": "./browser/types/binary.js",
"./types/omap.js": "./browser/types/omap.js",
"./types/pairs.js": "./browser/types/pairs.js",
"./types/set.js": "./browser/types/set.js",
"./types/timestamp.js": "./browser/types/timestamp.js",
"./util.js": "./browser/util.js",

@@ -46,2 +36,3 @@ "./util.mjs": "./browser/util.js"

".": "./index.js",
"./package.json": "./package.json",
"./parse-cst": "./parse-cst.js",

@@ -59,4 +50,3 @@ "./types": [

"./util.js"
],
"./": "./"
]
},

@@ -72,2 +62,3 @@ "scripts": {

"test": "jest",
"test:browsers": "cd playground && npm test",
"test:dist": "npm run build:node && jest",

@@ -89,19 +80,18 @@ "test:types": "tsc --lib ES2017 --noEmit tests/typings.ts",

"devDependencies": {
"@babel/core": "^7.9.6",
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/preset-env": "^7.9.6",
"@rollup/plugin-babel": "^5.0.0",
"@babel/core": "^7.11.4",
"@babel/plugin-proposal-class-properties": "^7.10.4",
"@babel/preset-env": "^7.11.0",
"@rollup/plugin-babel": "^5.2.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^26.0.1",
"babel-jest": "^26.3.0",
"babel-plugin-trace": "^1.1.0",
"common-tags": "^1.8.0",
"cross-env": "^7.0.2",
"eslint": "^7.0.0",
"eslint": "^7.7.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-prettier": "^3.1.3",
"fast-check": "^1.24.2",
"jest": "^26.0.1",
"fast-check": "^2.2.0",
"jest": "^26.4.2",
"prettier": "^2.0.5",
"rollup": "^2.10.2",
"typescript": "^3.9.2"
"rollup": "^2.26.5",
"typescript": "^4.0.2"
},

@@ -108,0 +98,0 @@ "engines": {

@@ -14,6 +14,6 @@ # YAML <a href="https://www.npmjs.com/package/yaml"><img align="right" src="https://badge.fury.io/js/yaml.svg" title="npm package" /></a><a href="https://travis-ci.org/eemeli/yaml"><img align="right" src="https://travis-ci.org/eemeli/yaml.svg?branch=master" title="Build status" /></a>

```sh
npm install yaml
npm install yaml@next
```
Note: `yaml` 0.x and 1.x are rather different implementations. For the earlier `yaml`, see [tj/js-yaml](https://github.com/tj/js-yaml).
**Note:** These docs are for `yaml@2`. For v1, see the [v1.10.0 tag](https://github.com/eemeli/yaml/tree/v1.10.0) for the source and [eemeli.org/yaml/v1](https://eemeli.org/yaml/v1/) for the documentation.

@@ -37,7 +37,7 @@ ## API Overview

- [`YAML.createNode(value, wrapScalars, tag): Node`](https://eemeli.org/yaml/#creating-nodes)
- [`YAML.defaultOptions`](https://eemeli.org/yaml/#options)
- [`YAML.Document`](https://eemeli.org/yaml/#yaml-documents)
- [`constructor(options)`](https://eemeli.org/yaml/#creating-documents)
- [`constructor(value, options)`](https://eemeli.org/yaml/#creating-documents)
- [`defaults`](https://eemeli.org/yaml/#options)
- [`#createNode(value, options): Node`](https://eemeli.org/yaml/#creating-nodes)
- [`#anchors`](https://eemeli.org/yaml/#working-with-anchors)

@@ -44,0 +44,0 @@ - [`#contents`](https://eemeli.org/yaml/#content-nodes)

@@ -12,36 +12,4 @@ import { Document, scalarOptions } from './index'

export class Schema {
/** Default: `'tag:yaml.org,2002:'` */
static defaultPrefix: string
static defaultTags: {
/** Default: `'tag:yaml.org,2002:map'` */
MAP: string
/** Default: `'tag:yaml.org,2002:seq'` */
SEQ: string
/** Default: `'tag:yaml.org,2002:str'` */
STR: string
}
constructor(options: Schema.Options)
/**
* Convert any value into a `Node` using this schema, recursively turning
* objects into collections.
*
* @param wrapScalars If `true`, also wraps plain values in `Scalar` objects;
* if undefined or `false` and `value` is not an object, it will be returned
* directly.
* @param tag Use to specify the collection type, e.g. `"!!omap"`. Note that
* this requires the corresponding tag to be available in this schema.
*/
createNode(
value: any,
wrapScalars?: boolean,
tag?: string,
ctx?: Schema.CreateNodeContext
): Node
/**
* Convert a key and a value into a `Pair` using this schema, recursively
* wrapping all values as `Scalar` or `Collection` nodes.
*
* @param ctx To not wrap scalars, use a context `{ wrapScalars: false }`
*/
createPair(key: any, value: any, ctx?: Schema.CreateNodeContext): Pair
knownTags: { [key: string]: Schema.CustomTag }
merge: boolean

@@ -69,2 +37,11 @@ name: Schema.Name

/**
* When using the `'core'` schema, support parsing values with these
* explicit YAML 1.1 tags:
*
* `!!binary`, `!!omap`, `!!pairs`, `!!set`, `!!timestamp`.
*
* Default `true`
*/
resolveKnownTags?: boolean
/**
* The base schema to use.

@@ -174,7 +151,2 @@ *

/**
* A JavaScript class that should be matched to this tag, e.g. `Date` for `!!timestamp`.
* @deprecated Use `Tag.identify` instead
*/
class?: new () => any
/**
* Turns a CST node into an AST node. If returning a non-`Node` value, the

@@ -181,0 +153,0 @@ * output will be wrapped as a `Scalar`.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc