mirror of
https://github.com/deployphp/action.git
synced 2025-04-20 11:06:47 +00:00
Add node_modules
This commit is contained in:
parent
e1f786311a
commit
554eb0b122
994 changed files with 195567 additions and 0 deletions
332
node_modules/yaml/browser/dist/doc/Document.js
generated
vendored
Normal file
332
node_modules/yaml/browser/dist/doc/Document.js
generated
vendored
Normal file
|
@ -0,0 +1,332 @@
|
|||
import { Alias } from '../nodes/Alias.js';
|
||||
import { isEmptyPath, collectionFromPath } from '../nodes/Collection.js';
|
||||
import { NODE_TYPE, DOC, isNode, isCollection, isScalar } from '../nodes/Node.js';
|
||||
import { Pair } from '../nodes/Pair.js';
|
||||
import { toJS } from '../nodes/toJS.js';
|
||||
import { Schema } from '../schema/Schema.js';
|
||||
import { stringify } from '../stringify/stringify.js';
|
||||
import { stringifyDocument } from '../stringify/stringifyDocument.js';
|
||||
import { anchorNames, findNewAnchor, createNodeAnchors } from './anchors.js';
|
||||
import { applyReviver } from './applyReviver.js';
|
||||
import { createNode } from './createNode.js';
|
||||
import { Directives } from './directives.js';
|
||||
|
||||
class Document {
|
||||
constructor(value, replacer, options) {
|
||||
/** A comment before this Document */
|
||||
this.commentBefore = null;
|
||||
/** A comment immediately after this Document */
|
||||
this.comment = null;
|
||||
/** Errors encountered during parsing. */
|
||||
this.errors = [];
|
||||
/** Warnings encountered during parsing. */
|
||||
this.warnings = [];
|
||||
Object.defineProperty(this, NODE_TYPE, { value: DOC });
|
||||
let _replacer = null;
|
||||
if (typeof replacer === 'function' || Array.isArray(replacer)) {
|
||||
_replacer = replacer;
|
||||
}
|
||||
else if (options === undefined && replacer) {
|
||||
options = replacer;
|
||||
replacer = undefined;
|
||||
}
|
||||
const opt = Object.assign({
|
||||
intAsBigInt: false,
|
||||
keepSourceTokens: false,
|
||||
logLevel: 'warn',
|
||||
prettyErrors: true,
|
||||
strict: true,
|
||||
uniqueKeys: true,
|
||||
version: '1.2'
|
||||
}, options);
|
||||
this.options = opt;
|
||||
let { version } = opt;
|
||||
if (options?._directives) {
|
||||
this.directives = options._directives.atDocument();
|
||||
if (this.directives.yaml.explicit)
|
||||
version = this.directives.yaml.version;
|
||||
}
|
||||
else
|
||||
this.directives = new Directives({ version });
|
||||
this.setSchema(version, options);
|
||||
if (value === undefined)
|
||||
this.contents = null;
|
||||
else {
|
||||
this.contents = this.createNode(value, _replacer, options);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Create a deep copy of this Document and its contents.
|
||||
*
|
||||
* Custom Node values that inherit from `Object` still refer to their original instances.
|
||||
*/
|
||||
clone() {
|
||||
const copy = Object.create(Document.prototype, {
|
||||
[NODE_TYPE]: { value: DOC }
|
||||
});
|
||||
copy.commentBefore = this.commentBefore;
|
||||
copy.comment = this.comment;
|
||||
copy.errors = this.errors.slice();
|
||||
copy.warnings = this.warnings.slice();
|
||||
copy.options = Object.assign({}, this.options);
|
||||
if (this.directives)
|
||||
copy.directives = this.directives.clone();
|
||||
copy.schema = this.schema.clone();
|
||||
copy.contents = isNode(this.contents)
|
||||
? this.contents.clone(copy.schema)
|
||||
: this.contents;
|
||||
if (this.range)
|
||||
copy.range = this.range.slice();
|
||||
return copy;
|
||||
}
|
||||
/** Adds a value to the document. */
|
||||
add(value) {
|
||||
if (assertCollection(this.contents))
|
||||
this.contents.add(value);
|
||||
}
|
||||
/** Adds a value to the document. */
|
||||
addIn(path, value) {
|
||||
if (assertCollection(this.contents))
|
||||
this.contents.addIn(path, value);
|
||||
}
|
||||
/**
|
||||
* Create a new `Alias` node, ensuring that the target `node` has the required anchor.
|
||||
*
|
||||
* If `node` already has an anchor, `name` is ignored.
|
||||
* Otherwise, the `node.anchor` value will be set to `name`,
|
||||
* or if an anchor with that name is already present in the document,
|
||||
* `name` will be used as a prefix for a new unique anchor.
|
||||
* If `name` is undefined, the generated anchor will use 'a' as a prefix.
|
||||
*/
|
||||
createAlias(node, name) {
|
||||
if (!node.anchor) {
|
||||
const prev = anchorNames(this);
|
||||
node.anchor =
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
!name || prev.has(name) ? findNewAnchor(name || 'a', prev) : name;
|
||||
}
|
||||
return new Alias(node.anchor);
|
||||
}
|
||||
createNode(value, replacer, options) {
|
||||
let _replacer = undefined;
|
||||
if (typeof replacer === 'function') {
|
||||
value = replacer.call({ '': value }, '', value);
|
||||
_replacer = replacer;
|
||||
}
|
||||
else if (Array.isArray(replacer)) {
|
||||
const keyToStr = (v) => typeof v === 'number' || v instanceof String || v instanceof Number;
|
||||
const asStr = replacer.filter(keyToStr).map(String);
|
||||
if (asStr.length > 0)
|
||||
replacer = replacer.concat(asStr);
|
||||
_replacer = replacer;
|
||||
}
|
||||
else if (options === undefined && replacer) {
|
||||
options = replacer;
|
||||
replacer = undefined;
|
||||
}
|
||||
const { aliasDuplicateObjects, anchorPrefix, flow, keepUndefined, onTagObj, tag } = options ?? {};
|
||||
const { onAnchor, setAnchors, sourceObjects } = createNodeAnchors(this,
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
anchorPrefix || 'a');
|
||||
const ctx = {
|
||||
aliasDuplicateObjects: aliasDuplicateObjects ?? true,
|
||||
keepUndefined: keepUndefined ?? false,
|
||||
onAnchor,
|
||||
onTagObj,
|
||||
replacer: _replacer,
|
||||
schema: this.schema,
|
||||
sourceObjects
|
||||
};
|
||||
const node = createNode(value, tag, ctx);
|
||||
if (flow && isCollection(node))
|
||||
node.flow = true;
|
||||
setAnchors();
|
||||
return node;
|
||||
}
|
||||
/**
|
||||
* Convert a key and a value into a `Pair` using the current schema,
|
||||
* recursively wrapping all values as `Scalar` or `Collection` nodes.
|
||||
*/
|
||||
createPair(key, value, options = {}) {
|
||||
const k = this.createNode(key, null, options);
|
||||
const v = this.createNode(value, null, options);
|
||||
return new Pair(k, v);
|
||||
}
|
||||
/**
|
||||
* Removes a value from the document.
|
||||
* @returns `true` if the item was found and removed.
|
||||
*/
|
||||
delete(key) {
|
||||
return assertCollection(this.contents) ? this.contents.delete(key) : false;
|
||||
}
|
||||
/**
|
||||
* Removes a value from the document.
|
||||
* @returns `true` if the item was found and removed.
|
||||
*/
|
||||
deleteIn(path) {
|
||||
if (isEmptyPath(path)) {
|
||||
if (this.contents == null)
|
||||
return false;
|
||||
this.contents = null;
|
||||
return true;
|
||||
}
|
||||
return assertCollection(this.contents)
|
||||
? this.contents.deleteIn(path)
|
||||
: false;
|
||||
}
|
||||
/**
|
||||
* Returns item at `key`, or `undefined` if not found. By default unwraps
|
||||
* scalar values from their surrounding node; to disable set `keepScalar` to
|
||||
* `true` (collections are always returned intact).
|
||||
*/
|
||||
get(key, keepScalar) {
|
||||
return isCollection(this.contents)
|
||||
? this.contents.get(key, keepScalar)
|
||||
: undefined;
|
||||
}
|
||||
/**
|
||||
* Returns item at `path`, or `undefined` if not found. By default unwraps
|
||||
* scalar values from their surrounding node; to disable set `keepScalar` to
|
||||
* `true` (collections are always returned intact).
|
||||
*/
|
||||
getIn(path, keepScalar) {
|
||||
if (isEmptyPath(path))
|
||||
return !keepScalar && isScalar(this.contents)
|
||||
? this.contents.value
|
||||
: this.contents;
|
||||
return isCollection(this.contents)
|
||||
? this.contents.getIn(path, keepScalar)
|
||||
: undefined;
|
||||
}
|
||||
/**
|
||||
* Checks if the document includes a value with the key `key`.
|
||||
*/
|
||||
has(key) {
|
||||
return isCollection(this.contents) ? this.contents.has(key) : false;
|
||||
}
|
||||
/**
|
||||
* Checks if the document includes a value at `path`.
|
||||
*/
|
||||
hasIn(path) {
|
||||
if (isEmptyPath(path))
|
||||
return this.contents !== undefined;
|
||||
return isCollection(this.contents) ? this.contents.hasIn(path) : false;
|
||||
}
|
||||
/**
|
||||
* Sets a value in this document. For `!!set`, `value` needs to be a
|
||||
* boolean to add/remove the item from the set.
|
||||
*/
|
||||
set(key, value) {
|
||||
if (this.contents == null) {
|
||||
this.contents = collectionFromPath(this.schema, [key], value);
|
||||
}
|
||||
else if (assertCollection(this.contents)) {
|
||||
this.contents.set(key, value);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Sets a value in this document. For `!!set`, `value` needs to be a
|
||||
* boolean to add/remove the item from the set.
|
||||
*/
|
||||
setIn(path, value) {
|
||||
if (isEmptyPath(path))
|
||||
this.contents = value;
|
||||
else if (this.contents == null) {
|
||||
this.contents = collectionFromPath(this.schema, Array.from(path), value);
|
||||
}
|
||||
else if (assertCollection(this.contents)) {
|
||||
this.contents.setIn(path, value);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Change the YAML version and schema used by the document.
|
||||
* A `null` version disables support for directives, explicit tags, anchors, and aliases.
|
||||
* It also requires the `schema` option to be given as a `Schema` instance value.
|
||||
*
|
||||
* Overrides all previously set schema options.
|
||||
*/
|
||||
setSchema(version, options = {}) {
|
||||
if (typeof version === 'number')
|
||||
version = String(version);
|
||||
let opt;
|
||||
switch (version) {
|
||||
case '1.1':
|
||||
if (this.directives)
|
||||
this.directives.yaml.version = '1.1';
|
||||
else
|
||||
this.directives = new Directives({ version: '1.1' });
|
||||
opt = { merge: true, resolveKnownTags: false, schema: 'yaml-1.1' };
|
||||
break;
|
||||
case '1.2':
|
||||
case 'next':
|
||||
if (this.directives)
|
||||
this.directives.yaml.version = version;
|
||||
else
|
||||
this.directives = new Directives({ version });
|
||||
opt = { merge: false, resolveKnownTags: true, schema: 'core' };
|
||||
break;
|
||||
case null:
|
||||
if (this.directives)
|
||||
delete this.directives;
|
||||
opt = null;
|
||||
break;
|
||||
default: {
|
||||
const sv = JSON.stringify(version);
|
||||
throw new Error(`Expected '1.1', '1.2' or null as first argument, but found: ${sv}`);
|
||||
}
|
||||
}
|
||||
// Not using `instanceof Schema` to allow for duck typing
|
||||
if (options.schema instanceof Object)
|
||||
this.schema = options.schema;
|
||||
else if (opt)
|
||||
this.schema = new Schema(Object.assign(opt, options));
|
||||
else
|
||||
throw new Error(`With a null YAML version, the { schema: Schema } option is required`);
|
||||
}
|
||||
// json & jsonArg are only used from toJSON()
|
||||
toJS({ json, jsonArg, mapAsMap, maxAliasCount, onAnchor, reviver } = {}) {
|
||||
const ctx = {
|
||||
anchors: new Map(),
|
||||
doc: this,
|
||||
keep: !json,
|
||||
mapAsMap: mapAsMap === true,
|
||||
mapKeyWarned: false,
|
||||
maxAliasCount: typeof maxAliasCount === 'number' ? maxAliasCount : 100,
|
||||
stringify
|
||||
};
|
||||
const res = toJS(this.contents, jsonArg ?? '', ctx);
|
||||
if (typeof onAnchor === 'function')
|
||||
for (const { count, res } of ctx.anchors.values())
|
||||
onAnchor(res, count);
|
||||
return typeof reviver === 'function'
|
||||
? applyReviver(reviver, { '': res }, '', res)
|
||||
: res;
|
||||
}
|
||||
/**
|
||||
* A JSON representation of the document `contents`.
|
||||
*
|
||||
* @param jsonArg Used by `JSON.stringify` to indicate the array index or
|
||||
* property name.
|
||||
*/
|
||||
toJSON(jsonArg, onAnchor) {
|
||||
return this.toJS({ json: true, jsonArg, mapAsMap: false, onAnchor });
|
||||
}
|
||||
/** A YAML representation of the document. */
|
||||
toString(options = {}) {
|
||||
if (this.errors.length > 0)
|
||||
throw new Error('Document with errors cannot be stringified');
|
||||
if ('indent' in options &&
|
||||
(!Number.isInteger(options.indent) || Number(options.indent) <= 0)) {
|
||||
const s = JSON.stringify(options.indent);
|
||||
throw new Error(`"indent" option must be a positive integer, not ${s}`);
|
||||
}
|
||||
return stringifyDocument(this, options);
|
||||
}
|
||||
}
|
||||
function assertCollection(contents) {
|
||||
if (isCollection(contents))
|
||||
return true;
|
||||
throw new Error('Expected a YAML collection as document contents');
|
||||
}
|
||||
|
||||
export { Document };
|
72
node_modules/yaml/browser/dist/doc/anchors.js
generated
vendored
Normal file
72
node_modules/yaml/browser/dist/doc/anchors.js
generated
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
import { isScalar, isCollection } from '../nodes/Node.js';
|
||||
import { visit } from '../visit.js';
|
||||
|
||||
/**
|
||||
* Verify that the input string is a valid anchor.
|
||||
*
|
||||
* Will throw on errors.
|
||||
*/
|
||||
function anchorIsValid(anchor) {
|
||||
if (/[\x00-\x19\s,[\]{}]/.test(anchor)) {
|
||||
const sa = JSON.stringify(anchor);
|
||||
const msg = `Anchor must not contain whitespace or control characters: ${sa}`;
|
||||
throw new Error(msg);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function anchorNames(root) {
|
||||
const anchors = new Set();
|
||||
visit(root, {
|
||||
Value(_key, node) {
|
||||
if (node.anchor)
|
||||
anchors.add(node.anchor);
|
||||
}
|
||||
});
|
||||
return anchors;
|
||||
}
|
||||
/** Find a new anchor name with the given `prefix` and a one-indexed suffix. */
|
||||
function findNewAnchor(prefix, exclude) {
|
||||
for (let i = 1; true; ++i) {
|
||||
const name = `${prefix}${i}`;
|
||||
if (!exclude.has(name))
|
||||
return name;
|
||||
}
|
||||
}
|
||||
function createNodeAnchors(doc, prefix) {
|
||||
const aliasObjects = [];
|
||||
const sourceObjects = new Map();
|
||||
let prevAnchors = null;
|
||||
return {
|
||||
onAnchor: (source) => {
|
||||
aliasObjects.push(source);
|
||||
if (!prevAnchors)
|
||||
prevAnchors = anchorNames(doc);
|
||||
const anchor = findNewAnchor(prefix, prevAnchors);
|
||||
prevAnchors.add(anchor);
|
||||
return anchor;
|
||||
},
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
setAnchors: () => {
|
||||
for (const source of aliasObjects) {
|
||||
const ref = sourceObjects.get(source);
|
||||
if (typeof ref === 'object' &&
|
||||
ref.anchor &&
|
||||
(isScalar(ref.node) || isCollection(ref.node))) {
|
||||
ref.node.anchor = ref.anchor;
|
||||
}
|
||||
else {
|
||||
const error = new Error('Failed to resolve repeated object (this should not happen)');
|
||||
error.source = source;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
},
|
||||
sourceObjects
|
||||
};
|
||||
}
|
||||
|
||||
export { anchorIsValid, anchorNames, createNodeAnchors, findNewAnchor };
|
54
node_modules/yaml/browser/dist/doc/applyReviver.js
generated
vendored
Normal file
54
node_modules/yaml/browser/dist/doc/applyReviver.js
generated
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
* Applies the JSON.parse reviver algorithm as defined in the ECMA-262 spec,
|
||||
* in section 24.5.1.1 "Runtime Semantics: InternalizeJSONProperty" of the
|
||||
* 2021 edition: https://tc39.es/ecma262/#sec-json.parse
|
||||
*
|
||||
* Includes extensions for handling Map and Set objects.
|
||||
*/
|
||||
function applyReviver(reviver, obj, key, val) {
|
||||
if (val && typeof val === 'object') {
|
||||
if (Array.isArray(val)) {
|
||||
for (let i = 0, len = val.length; i < len; ++i) {
|
||||
const v0 = val[i];
|
||||
const v1 = applyReviver(reviver, val, String(i), v0);
|
||||
if (v1 === undefined)
|
||||
delete val[i];
|
||||
else if (v1 !== v0)
|
||||
val[i] = v1;
|
||||
}
|
||||
}
|
||||
else if (val instanceof Map) {
|
||||
for (const k of Array.from(val.keys())) {
|
||||
const v0 = val.get(k);
|
||||
const v1 = applyReviver(reviver, val, k, v0);
|
||||
if (v1 === undefined)
|
||||
val.delete(k);
|
||||
else if (v1 !== v0)
|
||||
val.set(k, v1);
|
||||
}
|
||||
}
|
||||
else if (val instanceof Set) {
|
||||
for (const v0 of Array.from(val)) {
|
||||
const v1 = applyReviver(reviver, val, v0, v0);
|
||||
if (v1 === undefined)
|
||||
val.delete(v0);
|
||||
else if (v1 !== v0) {
|
||||
val.delete(v0);
|
||||
val.add(v1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (const [k, v0] of Object.entries(val)) {
|
||||
const v1 = applyReviver(reviver, val, k, v0);
|
||||
if (v1 === undefined)
|
||||
delete val[k];
|
||||
else if (v1 !== v0)
|
||||
val[k] = v1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return reviver.call(obj, key, val);
|
||||
}
|
||||
|
||||
export { applyReviver };
|
85
node_modules/yaml/browser/dist/doc/createNode.js
generated
vendored
Normal file
85
node_modules/yaml/browser/dist/doc/createNode.js
generated
vendored
Normal file
|
@ -0,0 +1,85 @@
|
|||
import { Alias } from '../nodes/Alias.js';
|
||||
import { isNode, isPair, MAP, SEQ, isDocument } from '../nodes/Node.js';
|
||||
import { Scalar } from '../nodes/Scalar.js';
|
||||
|
||||
const defaultTagPrefix = 'tag:yaml.org,2002:';
|
||||
function findTagObject(value, tagName, tags) {
|
||||
if (tagName) {
|
||||
const match = tags.filter(t => t.tag === tagName);
|
||||
const tagObj = match.find(t => !t.format) ?? match[0];
|
||||
if (!tagObj)
|
||||
throw new Error(`Tag ${tagName} not found`);
|
||||
return tagObj;
|
||||
}
|
||||
return tags.find(t => t.identify?.(value) && !t.format);
|
||||
}
|
||||
function createNode(value, tagName, ctx) {
|
||||
if (isDocument(value))
|
||||
value = value.contents;
|
||||
if (isNode(value))
|
||||
return value;
|
||||
if (isPair(value)) {
|
||||
const map = ctx.schema[MAP].createNode?.(ctx.schema, null, ctx);
|
||||
map.items.push(value);
|
||||
return map;
|
||||
}
|
||||
if (value instanceof String ||
|
||||
value instanceof Number ||
|
||||
value instanceof Boolean ||
|
||||
(typeof BigInt !== 'undefined' && value instanceof BigInt) // not supported everywhere
|
||||
) {
|
||||
// https://tc39.es/ecma262/#sec-serializejsonproperty
|
||||
value = value.valueOf();
|
||||
}
|
||||
const { aliasDuplicateObjects, onAnchor, onTagObj, schema, sourceObjects } = ctx;
|
||||
// Detect duplicate references to the same object & use Alias nodes for all
|
||||
// after first. The `ref` wrapper allows for circular references to resolve.
|
||||
let ref = undefined;
|
||||
if (aliasDuplicateObjects && value && typeof value === 'object') {
|
||||
ref = sourceObjects.get(value);
|
||||
if (ref) {
|
||||
if (!ref.anchor)
|
||||
ref.anchor = onAnchor(value);
|
||||
return new Alias(ref.anchor);
|
||||
}
|
||||
else {
|
||||
ref = { anchor: null, node: null };
|
||||
sourceObjects.set(value, ref);
|
||||
}
|
||||
}
|
||||
if (tagName?.startsWith('!!'))
|
||||
tagName = defaultTagPrefix + tagName.slice(2);
|
||||
let tagObj = findTagObject(value, tagName, schema.tags);
|
||||
if (!tagObj) {
|
||||
if (value && typeof value.toJSON === 'function') {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||||
value = value.toJSON();
|
||||
}
|
||||
if (!value || typeof value !== 'object') {
|
||||
const node = new Scalar(value);
|
||||
if (ref)
|
||||
ref.node = node;
|
||||
return node;
|
||||
}
|
||||
tagObj =
|
||||
value instanceof Map
|
||||
? schema[MAP]
|
||||
: Symbol.iterator in Object(value)
|
||||
? schema[SEQ]
|
||||
: schema[MAP];
|
||||
}
|
||||
if (onTagObj) {
|
||||
onTagObj(tagObj);
|
||||
delete ctx.onTagObj;
|
||||
}
|
||||
const node = tagObj?.createNode
|
||||
? tagObj.createNode(ctx.schema, value, ctx)
|
||||
: new Scalar(value);
|
||||
if (tagName)
|
||||
node.tag = tagName;
|
||||
if (ref)
|
||||
ref.node = node;
|
||||
return node;
|
||||
}
|
||||
|
||||
export { createNode };
|
169
node_modules/yaml/browser/dist/doc/directives.js
generated
vendored
Normal file
169
node_modules/yaml/browser/dist/doc/directives.js
generated
vendored
Normal file
|
@ -0,0 +1,169 @@
|
|||
import { isNode } from '../nodes/Node.js';
|
||||
import { visit } from '../visit.js';
|
||||
|
||||
const escapeChars = {
|
||||
'!': '%21',
|
||||
',': '%2C',
|
||||
'[': '%5B',
|
||||
']': '%5D',
|
||||
'{': '%7B',
|
||||
'}': '%7D'
|
||||
};
|
||||
const escapeTagName = (tn) => tn.replace(/[!,[\]{}]/g, ch => escapeChars[ch]);
|
||||
class Directives {
|
||||
constructor(yaml, tags) {
|
||||
/**
|
||||
* The directives-end/doc-start marker `---`. If `null`, a marker may still be
|
||||
* included in the document's stringified representation.
|
||||
*/
|
||||
this.docStart = null;
|
||||
/** The doc-end marker `...`. */
|
||||
this.docEnd = false;
|
||||
this.yaml = Object.assign({}, Directives.defaultYaml, yaml);
|
||||
this.tags = Object.assign({}, Directives.defaultTags, tags);
|
||||
}
|
||||
clone() {
|
||||
const copy = new Directives(this.yaml, this.tags);
|
||||
copy.docStart = this.docStart;
|
||||
return copy;
|
||||
}
|
||||
/**
|
||||
* During parsing, get a Directives instance for the current document and
|
||||
* update the stream state according to the current version's spec.
|
||||
*/
|
||||
atDocument() {
|
||||
const res = new Directives(this.yaml, this.tags);
|
||||
switch (this.yaml.version) {
|
||||
case '1.1':
|
||||
this.atNextDocument = true;
|
||||
break;
|
||||
case '1.2':
|
||||
this.atNextDocument = false;
|
||||
this.yaml = {
|
||||
explicit: Directives.defaultYaml.explicit,
|
||||
version: '1.2'
|
||||
};
|
||||
this.tags = Object.assign({}, Directives.defaultTags);
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
/**
|
||||
* @param onError - May be called even if the action was successful
|
||||
* @returns `true` on success
|
||||
*/
|
||||
add(line, onError) {
|
||||
if (this.atNextDocument) {
|
||||
this.yaml = { explicit: Directives.defaultYaml.explicit, version: '1.1' };
|
||||
this.tags = Object.assign({}, Directives.defaultTags);
|
||||
this.atNextDocument = false;
|
||||
}
|
||||
const parts = line.trim().split(/[ \t]+/);
|
||||
const name = parts.shift();
|
||||
switch (name) {
|
||||
case '%TAG': {
|
||||
if (parts.length !== 2) {
|
||||
onError(0, '%TAG directive should contain exactly two parts');
|
||||
if (parts.length < 2)
|
||||
return false;
|
||||
}
|
||||
const [handle, prefix] = parts;
|
||||
this.tags[handle] = prefix;
|
||||
return true;
|
||||
}
|
||||
case '%YAML': {
|
||||
this.yaml.explicit = true;
|
||||
if (parts.length !== 1) {
|
||||
onError(0, '%YAML directive should contain exactly one part');
|
||||
return false;
|
||||
}
|
||||
const [version] = parts;
|
||||
if (version === '1.1' || version === '1.2') {
|
||||
this.yaml.version = version;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
const isValid = /^\d+\.\d+$/.test(version);
|
||||
onError(6, `Unsupported YAML version ${version}`, isValid);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
default:
|
||||
onError(0, `Unknown directive ${name}`, true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Resolves a tag, matching handles to those defined in %TAG directives.
|
||||
*
|
||||
* @returns Resolved tag, which may also be the non-specific tag `'!'` or a
|
||||
* `'!local'` tag, or `null` if unresolvable.
|
||||
*/
|
||||
tagName(source, onError) {
|
||||
if (source === '!')
|
||||
return '!'; // non-specific tag
|
||||
if (source[0] !== '!') {
|
||||
onError(`Not a valid tag: ${source}`);
|
||||
return null;
|
||||
}
|
||||
if (source[1] === '<') {
|
||||
const verbatim = source.slice(2, -1);
|
||||
if (verbatim === '!' || verbatim === '!!') {
|
||||
onError(`Verbatim tags aren't resolved, so ${source} is invalid.`);
|
||||
return null;
|
||||
}
|
||||
if (source[source.length - 1] !== '>')
|
||||
onError('Verbatim tags must end with a >');
|
||||
return verbatim;
|
||||
}
|
||||
const [, handle, suffix] = source.match(/^(.*!)([^!]*)$/);
|
||||
if (!suffix)
|
||||
onError(`The ${source} tag has no suffix`);
|
||||
const prefix = this.tags[handle];
|
||||
if (prefix)
|
||||
return prefix + decodeURIComponent(suffix);
|
||||
if (handle === '!')
|
||||
return source; // local tag
|
||||
onError(`Could not resolve tag: ${source}`);
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Given a fully resolved tag, returns its printable string form,
|
||||
* taking into account current tag prefixes and defaults.
|
||||
*/
|
||||
tagString(tag) {
|
||||
for (const [handle, prefix] of Object.entries(this.tags)) {
|
||||
if (tag.startsWith(prefix))
|
||||
return handle + escapeTagName(tag.substring(prefix.length));
|
||||
}
|
||||
return tag[0] === '!' ? tag : `!<${tag}>`;
|
||||
}
|
||||
toString(doc) {
|
||||
const lines = this.yaml.explicit
|
||||
? [`%YAML ${this.yaml.version || '1.2'}`]
|
||||
: [];
|
||||
const tagEntries = Object.entries(this.tags);
|
||||
let tagNames;
|
||||
if (doc && tagEntries.length > 0 && isNode(doc.contents)) {
|
||||
const tags = {};
|
||||
visit(doc.contents, (_key, node) => {
|
||||
if (isNode(node) && node.tag)
|
||||
tags[node.tag] = true;
|
||||
});
|
||||
tagNames = Object.keys(tags);
|
||||
}
|
||||
else
|
||||
tagNames = [];
|
||||
for (const [handle, prefix] of tagEntries) {
|
||||
if (handle === '!!' && prefix === 'tag:yaml.org,2002:')
|
||||
continue;
|
||||
if (!doc || tagNames.some(tn => tn.startsWith(prefix)))
|
||||
lines.push(`%TAG ${handle} ${prefix}`);
|
||||
}
|
||||
return lines.join('\n');
|
||||
}
|
||||
}
|
||||
Directives.defaultYaml = { explicit: false, version: '1.2' };
|
||||
Directives.defaultTags = { '!!': 'tag:yaml.org,2002:' };
|
||||
|
||||
export { Directives };
|
Loading…
Add table
Add a link
Reference in a new issue