2025-09-05 14:59:21 +08:00

176 lines
5.5 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getStaticYAMLValue = getStaticYAMLValue;
exports.sortedLastIndex = sortedLastIndex;
const yaml_1 = require("yaml");
const tags_1 = require("./tags");
/**
* Gets the static value for the given node.
*/
function getStaticYAMLValue(node) {
return getValue(node, null);
}
/**
* Gets the static value for the given node with YAML version.
*/
function getValue(node, version) {
return resolver[node.type](node, version);
}
const resolver = {
Program(node) {
return node.body.length === 0
? null
: node.body.length === 1
? // eslint-disable-next-line new-cap -- traverse key
resolver.YAMLDocument(node.body[0])
: // eslint-disable-next-line new-cap -- traverse key
node.body.map((n) => resolver.YAMLDocument(n));
},
YAMLDocument(node) {
return node.content ? getValue(node.content, node.version) : null;
},
YAMLMapping(node, version) {
const result = {};
for (const pair of node.pairs) {
Object.assign(result, getValue(pair, version));
}
return result;
},
YAMLPair(node, version) {
const result = {};
let key = node.key ? getValue(node.key, version) : null;
if (typeof key !== "string" && typeof key !== "number") {
key = String(key);
}
result[key] = node.value ? getValue(node.value, version) : null;
return result;
},
YAMLSequence(node, version) {
const result = [];
for (const entry of node.entries) {
result.push(entry ? getValue(entry, version) : null);
}
return result;
},
YAMLScalar(node) {
return node.value;
},
YAMLAlias(node, version) {
const anchor = findAnchor(node);
return anchor ? getValue(anchor.parent, version) : null;
},
YAMLWithMeta(node, version) {
if (node.tag) {
const value = node.value;
if (value == null) {
return getTaggedValue(node.tag, "", "", version);
}
if (value.type === "YAMLScalar") {
if (value.style === "plain") {
return getTaggedValue(node.tag, value.strValue, value.strValue, version);
}
if (value.style === "double-quoted" ||
value.style === "single-quoted") {
return getTaggedValue(node.tag, value.raw, value.strValue, version);
}
}
for (const tagResolver of tags_1.tagNodeResolvers[version || "1.2"]) {
if (tagResolver.tag === node.tag.tag && tagResolver.testNode(value)) {
return tagResolver.resolveNode(value);
}
}
}
if (node.value == null) {
return null;
}
return getValue(node.value, version);
},
};
/**
* Find Anchor
*/
function findAnchor(node) {
let p = node.parent;
let doc = null;
while (p) {
if (p.type === "YAMLDocument") {
doc = p;
break;
}
p = p.parent;
}
const anchors = doc.anchors[node.name];
if (!anchors) {
return null;
}
let target = {
anchor: null,
distance: Infinity,
};
for (const anchor of anchors) {
if (anchor.range[0] < node.range[0]) {
const distance = node.range[0] - anchor.range[0];
if (target.distance >= distance) {
target = {
anchor,
distance,
};
}
}
}
return target.anchor;
}
/**
* Get tagged value
*/
function getTaggedValue(tag, text, str, version) {
for (const tagResolver of tags_1.tagResolvers[version || "1.2"]) {
if (tagResolver.tag === tag.tag && tagResolver.testString(str)) {
return tagResolver.resolveString(str);
}
}
const tagText = tag.tag.startsWith("!") ? tag.tag : `!<${tag.tag}>`;
const value = (0, yaml_1.parseDocument)(`${version ? `%YAML ${version}` : ""}
---
${tagText} ${text}`).toJSON();
return value;
}
/**
* Find the insertion position (index) of an item in an array with items sorted
* in ascending order; so that `splice(sortedIndex, 0, item)` would result in
* maintaining the array's sort-ness. The array can contain duplicates.
* If the item already exists in the array the index would be of the *last*
* occurrence of the item.
*
* Runs in O(logN) time.
*
* MIT License | Copyright (c) 2018 remeda | https://remedajs.com/
*
* The implementation is copied from remeda package:
* https://github.com/remeda/remeda/blob/878206eb3e8ec1c7f1300b1909b7aa629810c8bb/src/sortedLastIndex.ts
* https://github.com/remeda/remeda/blob/878206eb3e8ec1c7f1300b1909b7aa629810c8bb/src/internal/binarySearchCutoffIndex.ts#L1
*
* @param data - The (ascending) sorted array.
* @param item - The item to insert.
* @returns Insertion index (In the range 0..data.length).
* @signature
* sortedLastIndex(data, item)
* @example
* sortedLastIndex(['a','a','b','c','c'], 'c') // => 5
*/
function sortedLastIndex(array, item) {
let lowIndex = 0;
let highIndex = array.length;
while (lowIndex < highIndex) {
const pivotIndex = (lowIndex + highIndex) >>> 1;
const pivot = array[pivotIndex];
if (pivot <= item) {
lowIndex = pivotIndex + 1;
}
else {
highIndex = pivotIndex;
}
}
return highIndex;
}