@jirutka/ajv-cli
Version:
CLI for Ajv JSON Schema Validator with human-friendly error messages
65 lines • 2.03 kB
JavaScript
import { evaluate as evaluateAst, parse as parseJsonAst, } from '@humanwhocodes/momoa';
const convertLocation = (loc) => ({
line: loc.line,
col: loc.column,
});
export function parse(input, filename, mode) {
// NOTE: JSON.parse is faster, so we parse it using momoa only when needed.
let jsonAst;
let data;
if (!mode || mode === 'json') {
try {
data = JSON.parse(input);
mode = 'json';
}
catch (err) {
if (mode === 'json' || !(err instanceof SyntaxError)) {
throw err;
}
mode = 'jsonc';
}
}
const parseOpts = { mode, ranges: false, tokens: false };
if (mode === 'jsonc') {
jsonAst = parseJsonAst(input, parseOpts);
data = evaluateAst(jsonAst);
}
return {
data,
filename,
lines: input.split('\n'),
locate(jsonPath) {
jsonAst ??= parseJsonAst(input, parseOpts);
const node = getValueAtPath(jsonAst, jsonPath);
if (node) {
return {
start: convertLocation(node.loc.start),
end: convertLocation(node.loc.end),
};
}
},
};
}
function getValueAtPath(jsonAst, jsonPath) {
let value = jsonAst.body;
for (const key of jsonPath) {
switch (value.type) {
case 'Object': {
const filtered = value.members.filter(member => 'value' in member.name && member.name.value === key);
if (filtered.length !== 1) {
return undefined;
}
value = filtered[0].value;
break;
}
case 'Array':
value = value.elements[key].value;
break;
default:
// This should not happen.
throw new Error(`BUG: Unexpected object type: ${value.type}`);
}
}
return value;
}
//# sourceMappingURL=json.js.map