Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
constructor(contents, row, col) {
this.ast = loadYaml(contents)
let lines = this.lines = contents.split(/\n/g, -1)
this._index = {
range: new IntervalTree(),
nodePos: [],
nodePath: {},
posToRow: [],
}
// create index of pos to row,col
let pos = 0
for (let s = 0, len=lines.length; s < len; ++s) {
this._index.posToRow.push([pos, lines[s].length])
pos += lines[s].length + 1
}
this.visit(this.ast)
export default function parseYamlAST(ymlPath) {
try {
const contents = fs.readFileSync(ymlPath, 'utf8')
lineNumbers = [] // reset current AST line Numbers array
window.CURRENT_AST = {} // reset current AST
window.CURRENT_AST.PATH = ymlPath
lineNumbers = getLineNumberInfo(contents)
// console.log('lineNumbers', lineNumbers)
const yamlAST = yaml.load(contents)
const nullYamlValues = []
const valueWithParent = []
parseAST(yamlAST, valueWithParent, nullYamlValues)
// console.log('nullYamlValues', nullYamlValues)
// console.log('valueWithParent', valueWithParent)
// console.log(window.CURRENT_AST)
// TODO: Validate Yaml Fields
// validateYamlFields(valueWithParent)
return yamlAST
} catch (e) {
return e
}
}
*onHoverRef(docAnalysis, position) {
const refValueJsonPath = docAnalysis.GetJsonPathFromJsonReferenceAt(position);
if (refValueJsonPath) {
for (const location of docAnalysis.GetDefinitionLocations(refValueJsonPath)) {
yield {
language: "yaml",
value: yaml_ast_parser_1.safeDump(location.value, {})
};
}
} // else {console.log("found nothing that looks like a JSON reference"); return null; }
}
*onHoverJsonPath(docAnalysis, position) {
function parseYAMLSource(projectSource: ProjectSource, validationContext: ValidationContext): ParsedObjectProjectSource | undefined {
const root: YAMLNode | undefined = load(projectSource.body);
if (!root) {
return undefined;
}
root.errors.forEach(error => {
const severity = error.isWarning ? Severity.Warning : Severity.Error;
const endPos = getLineEndPosition(error.mark.line + 1, projectSource);
validationContext.addMessage(new ValidationMessage(severity, error.reason, new MessageLocation(projectSource, new SourcePosition(error.mark.position, error.mark.line + 1, error.mark.column + 1), endPos)));
});
if (root.errors.some(error => !error.isWarning)) {
// returning undefined will lead to ignoring this source file in future steps
return undefined;
}
function recursiveObjectExtraction(node: YAMLNode | undefined, object: PlainObject, validationContext: ValidationContext, source: ProjectSource): any {
// ATTENTION: Typings of the yaml ast parser are wrong
if (!node) {
return object;
}
switch (node.kind) {
case Kind.MAP:
const mapNode = node as YamlMap;
mapNode.mappings.forEach(val => {
object[val.key.value] = recursiveObjectExtraction(val.value, {}, validationContext, source);
});
return object;
case Kind.MAPPING:
throw new Error('Should never be reached since a mapping can not exist without a map.');
case Kind.SCALAR:
const scalarNode = node as YAMLScalar;
// check whether string or number scalar
if (scalarNode.doubleQuoted || scalarNode.singleQuoted || isNaN(Number(scalarNode.value))) {
return scalarNode.value;
} else {
return Number(scalarNode.value);
}
case Kind.SEQ:
function recursiveObjectExtraction(node: YAMLNode | undefined, object: PlainObject, validationContext: ValidationContext, source: ProjectSource): any {
// ATTENTION: Typings of the yaml ast parser are wrong
if (!node) {
return object;
}
switch (node.kind) {
case Kind.MAP:
const mapNode = node as YamlMap;
mapNode.mappings.forEach(val => {
object[val.key.value] = recursiveObjectExtraction(val.value, {}, validationContext, source);
});
return object;
case Kind.MAPPING:
throw new Error('Should never be reached since a mapping can not exist without a map.');
case Kind.SCALAR:
const scalarNode = node as YAMLScalar;
// check whether string or number scalar
if (scalarNode.doubleQuoted || scalarNode.singleQuoted || isNaN(Number(scalarNode.value))) {
return scalarNode.value;
} else {
return Number(scalarNode.value);
}
case Kind.SEQ:
const seqNode = node as YAMLSequence;
return seqNode.items.map(val => recursiveObjectExtraction(val, {}, validationContext, source));
case Kind.INCLUDE_REF:
validationContext.addMessage(ValidationMessage.error(`Include references are not supported`, new MessageLocation(source, node.startPosition, node.endPosition)));
return undefined;
case Kind.ANCHOR_REF:
function recursiveObjectExtraction(node: YAMLNode | undefined, object: PlainObject, validationContext: ValidationContext, source: ProjectSource): any {
// ATTENTION: Typings of the yaml ast parser are wrong
if (!node) {
return object;
}
switch (node.kind) {
case Kind.MAP:
const mapNode = node as YamlMap;
mapNode.mappings.forEach(val => {
object[val.key.value] = recursiveObjectExtraction(val.value, {}, validationContext, source);
});
return object;
case Kind.MAPPING:
throw new Error('Should never be reached since a mapping can not exist without a map.');
case Kind.SCALAR:
const scalarNode = node as YAMLScalar;
// check whether string or number scalar
if (scalarNode.doubleQuoted || scalarNode.singleQuoted || isNaN(Number(scalarNode.value))) {
return scalarNode.value;
} else {
return Number(scalarNode.value);
}
case Kind.SEQ:
const seqNode = node as YAMLSequence;
return seqNode.items.map(val => recursiveObjectExtraction(val, {}, validationContext, source));
case Kind.INCLUDE_REF:
validationContext.addMessage(ValidationMessage.error(`Include references are not supported`, new MessageLocation(source, node.startPosition, node.endPosition)));
return undefined;
case Kind.ANCHOR_REF:
validationContext.addMessage(ValidationMessage.error(`Anchor references are not supported`, new MessageLocation(source, node.startPosition, node.endPosition)));
return undefined;
parent,
null,
instance.endPosition,
instance.endPosition
)
: this.recursivelyBuildAst(result, item)
itemNode.location = count++
result.addItem(itemNode)
}
return result
}
case Yaml.Kind.SCALAR: {
const instance = node as YamlScalar
const type = Yaml.determineScalarType(instance)
// The name is set either by the sequence or the mapping case.
const name = null
const value = instance.value
// This is a patch for redirecting values with these strings to be boolean nodes because its not supported in the parser.
const possibleBooleanValues = [
"y",
"Y",
"yes",
"Yes",
"YES",
"n",
"N",
"no",
"No",
indexPositionAndPath(path, parent, node, elementIndex) {
path = path || '.'
if (node) {
if (node.endPosition < node.startPosition) {
console.error(`unexpected node start/end combination: ${JSON.stringify(node)}`)
}
} else if (parent.kind === YAML.Kind.SEQ) {
let prevItem = null
if (elementIndex > 0) {
for (let i=elementIndex-1; i >= 0 && prevItem === null; --i) {
prevItem = parent.items[i]
}
}
let startPos = (prevItem ? prevItem.endPosition : parent.startPosition) + 1
let endPos = elementIndex + 1 < parent.items.length ? parent.items[elementIndex+1].startPosition : parent.endPosition
node = {startPosition: startPos, endPosition: endPos, parent: parent}
} else if (parent.kind === YAML.Kind.MAPPING) {
let map = parent.parent
let startPos, endPos
if (elementIndex > 0) {
startPos = map.mappings[elementIndex-1].endPosition
} else {
startPos = parent.endPosition
var offset = positionOffset || 0;
lineColumnFinder = lineColumnFinder || lineColumn(inYaml);
if (!inYaml) {
return [noDocError(inYaml)];
}
var root;
try {
root = yaml.safeLoad(inYaml);
}
catch (err) {
return [loadYamlError(err, inYaml, lineColumnFinder, offset)];
}
if (!root) {
return [noDocError(inYaml)];
}
var yamlAST = ast.safeLoad(inYaml, null);
if (_.isEmpty(rules)) {
return [];
}
var ruleTriggers = [];
_.forEach(rules, function (rule) {
var result = rule.test.test(root);
if (result.matched) {
var positions = _.flatMap(result.paths, function (path) { return ast_1.astPosition(yamlAST, path, lineColumnFinder, offset); });
if (_.isEmpty(positions)) {
var shorterPaths = _.map(result.paths, function (p) { return p.split(".").slice(0, -1).join("."); });
positions = _.flatMap(shorterPaths, function (path) { return ast_1.astPosition(yamlAST, path, lineColumnFinder, offset); });
}
ruleTriggers.push({
type: rule.type,
rule: rule.name,
received: _.map(result.paths, function (p) { return _.get(root, p); })[0],