@stoplight/yaml
Advanced tools
Comparing version
{ | ||
"name": "@stoplight/yaml", | ||
"version": "3.4.0", | ||
"version": "3.5.0", | ||
"description": "Useful functions when working with YAML.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -5,3 +5,3 @@ "use strict"; | ||
const parseWithPointers_1 = require("./parseWithPointers"); | ||
exports.parse = (value) => parseWithPointers_1.walkAST(yaml_ast_parser_1.load(value)); | ||
exports.parse = (value) => parseWithPointers_1.walkAST(yaml_ast_parser_1.load(value), void 0, [], []); | ||
//# sourceMappingURL=parse.js.map |
@@ -0,3 +1,4 @@ | ||
import { IDiagnostic } from '@stoplight/types'; | ||
import { IParseOptions, Kind, YAMLAnchorReference, YAMLMapping, YAMLNode, YAMLScalar } from './types'; | ||
export declare const parseWithPointers: <T>(value: string, options?: IParseOptions | undefined) => import("@stoplight/types").IParserResult<T | undefined, YAMLNode, number[], IParseOptions>; | ||
export declare const walkAST: (node: YAMLAnchorReference | import("./types").YAMLBaseNode<Kind.INCLUDE_REF> | YAMLScalar | import("./types").YAMLMap | YAMLMapping | import("./types").YAMLSequence | null, options?: IParseOptions | undefined, duplicatedMappingKeys?: YAMLNode[] | undefined) => unknown; | ||
export declare const walkAST: (node: YAMLAnchorReference | import("./types").YAMLBaseNode<Kind.INCLUDE_REF> | YAMLScalar | import("./types").YAMLMap | YAMLMapping | import("./types").YAMLSequence | null, options: IParseOptions | undefined, lineMap: number[], diagnostics: IDiagnostic[]) => unknown; |
@@ -21,7 +21,3 @@ "use strict"; | ||
return parsed; | ||
const duplicatedMappingKeys = []; | ||
parsed.data = exports.walkAST(ast, options, options !== undefined && options.ignoreDuplicateKeys === false ? duplicatedMappingKeys : undefined); | ||
if (duplicatedMappingKeys.length > 0) { | ||
parsed.diagnostics.push(...transformDuplicatedMappingKeys(duplicatedMappingKeys, lineMap)); | ||
} | ||
parsed.data = exports.walkAST(ast, options, lineMap, parsed.diagnostics); | ||
if (ast.errors) { | ||
@@ -39,3 +35,3 @@ parsed.diagnostics.push(...transformErrors(ast.errors, lineMap)); | ||
const KEYS = Symbol('object_keys'); | ||
exports.walkAST = (node, options, duplicatedMappingKeys) => { | ||
exports.walkAST = (node, options, lineMap, diagnostics) => { | ||
if (node) { | ||
@@ -48,12 +44,15 @@ switch (node.kind) { | ||
const handleMergeKeys = options !== void 0 && options.mergeKeys === true; | ||
const handleDuplicates = (options !== void 0 && options.json === false) || duplicatedMappingKeys !== void 0; | ||
const yamlMode = options !== void 0 && options.json === false; | ||
const handleDuplicates = options !== void 0 && options.ignoreDuplicateKeys === false; | ||
for (const mapping of node.mappings) { | ||
const key = mapping.key.value; | ||
if (handleDuplicates && (!handleMergeKeys || key !== "<<")) { | ||
if (seenKeys.includes(mapping.key.value)) { | ||
if (options !== void 0 && options.json === false) { | ||
if (!validateMappingKey(mapping, lineMap, diagnostics, yamlMode)) | ||
continue; | ||
const key = String(getScalarValue(mapping.key)); | ||
if ((yamlMode || handleDuplicates) && (!handleMergeKeys || key !== "<<")) { | ||
if (seenKeys.includes(key)) { | ||
if (yamlMode) { | ||
throw new Error('Duplicate YAML mapping key encountered'); | ||
} | ||
if (duplicatedMappingKeys !== void 0) { | ||
duplicatedMappingKeys.push(mapping.key); | ||
if (handleDuplicates) { | ||
diagnostics.push(createYAMLException(mapping.key, lineMap, 'duplicate key')); | ||
} | ||
@@ -66,3 +65,3 @@ } | ||
if (handleMergeKeys && key === "<<") { | ||
const reduced = reduceMergeKeys(exports.walkAST(mapping.value, options, duplicatedMappingKeys), preserveKeyOrder); | ||
const reduced = reduceMergeKeys(exports.walkAST(mapping.value, options, lineMap, diagnostics), preserveKeyOrder); | ||
if (preserveKeyOrder && reduced !== null) { | ||
@@ -76,3 +75,3 @@ for (const reducedKey of Object.keys(reduced)) { | ||
else { | ||
container[key] = exports.walkAST(mapping.value, options, duplicatedMappingKeys); | ||
container[key] = exports.walkAST(mapping.value, options, lineMap, diagnostics); | ||
if (preserveKeyOrder) { | ||
@@ -89,3 +88,3 @@ pushKey(container, key); | ||
case types_2.Kind.SEQ: | ||
return node.items.map(item => exports.walkAST(item, options, duplicatedMappingKeys)); | ||
return node.items.map(item => exports.walkAST(item, options, lineMap, diagnostics)); | ||
case types_2.Kind.SCALAR: | ||
@@ -97,3 +96,3 @@ return getScalarValue(node); | ||
} | ||
return node.value && exports.walkAST(node.value, options, duplicatedMappingKeys); | ||
return node.value && exports.walkAST(node.value, options, lineMap, diagnostics); | ||
} | ||
@@ -192,26 +191,2 @@ default: | ||
}; | ||
const transformDuplicatedMappingKeys = (nodes, lineMap) => { | ||
const validations = []; | ||
for (const node of nodes) { | ||
const startLine = lineForPosition_1.lineForPosition(node.startPosition, lineMap); | ||
const endLine = lineForPosition_1.lineForPosition(node.endPosition, lineMap); | ||
validations.push({ | ||
code: 'YAMLException', | ||
message: 'duplicate key', | ||
path: buildJsonPath_1.buildJsonPath(node), | ||
range: { | ||
start: { | ||
line: startLine, | ||
character: startLine === 0 ? node.startPosition : node.startPosition - lineMap[startLine - 1], | ||
}, | ||
end: { | ||
line: endLine, | ||
character: endLine === 0 ? node.endPosition : node.endPosition - lineMap[endLine - 1], | ||
}, | ||
}, | ||
severity: types_1.DiagnosticSeverity.Error, | ||
}); | ||
} | ||
return validations; | ||
}; | ||
const reduceMergeKeys = (items, preserveKeyOrder) => { | ||
@@ -264,2 +239,43 @@ if (Array.isArray(items)) { | ||
} | ||
function validateMappingKey(mapping, lineMap, diagnostics, yamlMode) { | ||
if (mapping.key.kind !== types_2.Kind.SCALAR) { | ||
if (!yamlMode) { | ||
diagnostics.push(createYAMLIncompatibilityException(mapping.key, lineMap, 'mapping key must be a string scalar', yamlMode)); | ||
} | ||
return false; | ||
} | ||
if (!yamlMode) { | ||
const type = typeof getScalarValue(mapping.key); | ||
if (type !== 'string') { | ||
diagnostics.push(createYAMLIncompatibilityException(mapping.key, lineMap, `mapping key must be a string scalar rather than ${mapping.key.valueObject === null ? 'null' : type}`, yamlMode)); | ||
} | ||
} | ||
return true; | ||
} | ||
function createYAMLIncompatibilityException(node, lineMap, message, yamlMode) { | ||
const exception = createYAMLException(node, lineMap, message); | ||
exception.code = 'YAMLIncompatibleValue'; | ||
exception.severity = yamlMode ? types_1.DiagnosticSeverity.Hint : types_1.DiagnosticSeverity.Error; | ||
return exception; | ||
} | ||
function createYAMLException(node, lineMap, message) { | ||
const startLine = lineForPosition_1.lineForPosition(node.startPosition, lineMap); | ||
const endLine = lineForPosition_1.lineForPosition(node.endPosition, lineMap); | ||
return { | ||
code: 'YAMLException', | ||
message, | ||
severity: types_1.DiagnosticSeverity.Error, | ||
path: buildJsonPath_1.buildJsonPath(node), | ||
range: { | ||
start: { | ||
line: startLine, | ||
character: startLine === 0 ? node.startPosition : node.startPosition - lineMap[startLine - 1], | ||
}, | ||
end: { | ||
line: endLine, | ||
character: endLine === 0 ? node.endPosition : node.endPosition - lineMap[endLine - 1], | ||
}, | ||
}, | ||
}; | ||
} | ||
//# sourceMappingURL=parseWithPointers.js.map |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
62509
2.48%688
2.53%