UNPKG

json-parser-yaml-converter

Version:
66 lines (60 loc) 1.92 kB
/** * This module contains the function jsonParse that parses a JSON file. * * @module parser */ 'use strict'; import { readFileSync } from 'fs'; import { YELLOW, RESET, BOLD, UNDERLINE } from './colors.js'; import nearley from 'nearley'; import grammar from './grammar.js'; /** * Parses a JSON file. * @param {string} jsonFile JSON file to parse. * @param {boolean} ast If true, returns the AST instead of the object. * @returns {Object} The parsed JSON file. * @throws {Error} If the JSON file could not be parsed. */ function jsonParse(jsonFile, ast = false) { const INPUT = readFileSync(jsonFile, 'utf-8'); const PARSER = new nearley.Parser(nearley.Grammar.fromCompiled(grammar)); try { const RESULT = PARSER.feed(INPUT); return ast ? RESULT.results[0] : astToObject(RESULT.results[0]); } catch (error) { const TOKEN = error.token; const EXPECTED = error.message.match(/(?<=A ).*(?= based on:)/g).map(s => s.replace(/\s+token/i, '')); if (INPUT.length === 0) { TOKEN.line = 0; TOKEN.col = 0; } const FINAL_ERROR = { token: TOKEN.value, line: TOKEN.line, col: TOKEN.col, expected: [...new Set(EXPECTED)] } throw FINAL_ERROR; } } /** * Converts an AST to an object. * @param {Object} ast AST to convert. * @returns {Object} The object. */ function astToObject(ast) { if (ast.type === 'object') { return ast.properties.reduce((acc, property) => { if (property.key in acc) { console.warn(YELLOW + 'Warning: Duplicate key ' + RESET + BOLD + UNDERLINE + property.key + RESET + YELLOW + ' found!' + RESET); } acc[property.key] = astToObject(property.value); return acc; }, {}); } if (ast.type === 'array') { return ast.elements.map(astToObject); } return ast.value; } export { jsonParse, astToObject };