yini-parser
Version:
Node.js parser for YINI — a clean, structured INI alternative with types, simple section nesting, comments, and strict mode.
115 lines (114 loc) • 5.11 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const env_1 = require("./config/env");
const parseEntry_1 = require("./parseEntry");
const pathAndFileName_1 = require("./utils/pathAndFileName");
const print_1 = require("./utils/print");
/**
* This class is the public API, which exposes only parse(..) and
* parseFile(..), rest of the implementation details are hidden.
* @note Only parse and parseFile are public.
*/
class YINI {
}
_a = YINI;
YINI.filePath = ''; // Used in error reporting.
/**
* Parse YINI content into a JavaScript object.
*
* @param yiniContent YINI code as a string (multi‑line content supported).
* @param strictMode If `true`, enforce strict parsing rules (e.g. require `/END`, disallow trailing commas).
* @param bailSensitivity Controls how errors and warnings are handled:
* - `'auto'` : Auto‑select level (strict→1, lenient→0)
* - `0` / `'Ignore-Errors'` : Continue parsing despite errors; log them and attempt recovery.
* - `1` / `'Abort-on-Errors'` : Stop parsing on the first error.
* - `2` / `'Abort-Even-on-Warnings'`: Stop parsing on the first warning **or** error.
* @param includeMetaData If `true`, return additional metadata (e.g. warnings, statistics) alongside the parsed object.
*
* @note The order of properties in each output object may differ from their order in the YINI source.
*
* @returns A JavaScript object representing the parsed YINI content.
*/
YINI.parse = (yiniContent, strictMode = false, bailSensitivity = 'auto', includeMetaData = false) => {
(0, print_1.debugPrint)('-> Entered static parse(..) in class YINI\n');
// Important: First, before anything, trim beginning and trailing whitespaces!
yiniContent = yiniContent.trim();
if (!yiniContent) {
throw new Error('Syntax-Error: Unexpected blank YINI input');
}
if (!yiniContent.endsWith('\n')) {
yiniContent += '\n';
}
let level = 0;
if (bailSensitivity === 'auto') {
if (!strictMode)
level = 0;
if (strictMode)
level = 1;
}
else {
level = bailSensitivity;
}
const options = {
isStrict: strictMode,
bailSensitivityLevel: level,
isIncludeMeta: includeMetaData,
isWithDiagnostics: (0, env_1.isDev)() || (0, env_1.isDebug)(),
isWithTiming: (0, env_1.isDebug)(),
};
(0, print_1.debugPrint)();
(0, print_1.debugPrint)('==== Call parse ==========================');
const result = (0, parseEntry_1.parseMain)(yiniContent, options);
(0, print_1.debugPrint)('==== End call parse ==========================\n');
if ((0, env_1.isDev)()) {
console.log();
(0, print_1.devPrint)('YINI.parse(..): result:');
console.log(result);
(0, print_1.devPrint)('Complete result:');
(0, print_1.printObject)(result);
}
return result;
};
/**
* Parse a YINI file into a JavaScript object.
*
* @param yiniFile Path to the YINI file.
* @param strictMode If `true`, enforce strict parsing rules (e.g. require `/END`, disallow trailing commas).
* @param bailSensitivity Controls how errors and warnings are handled:
* - `'auto'` : Auto‑select level (strict→1, lenient→0)
* - `0` / `'Ignore-Errors'` : Continue parsing despite errors; log them and attempt recovery.
* - `1` / `'Abort-on-Errors'` : Stop parsing on the first error.
* - `2` / `'Abort-Even-on-Warnings'`: Stop parsing on the first warning **or** error.
* @param includeMetaData If `true`, return additional metadata (e.g. warnings, statistics) alongside the parsed object.
*
* @note The order of properties in each output object may differ from their order in the YINI source.
*
* @returns A JavaScript object representing the parsed YINI content.
*/
YINI.parseFile = (filePath, strictMode = false, bailSensitivity = 'auto', includeMetaData = false) => {
(0, print_1.debugPrint)('Current directory = ' + process.cwd());
if ((0, pathAndFileName_1.getFileNameExtension)(filePath).toLowerCase() !== '.yini') {
console.error('Invalid file extension for YINI file:');
console.error(`"${filePath}"`);
console.log('File does not have a valid ".yini" extension (case-insensitive).');
throw new Error('Error: Unexpected file extension for YINI file');
}
let content = fs_1.default.readFileSync(filePath, 'utf8');
let hasNoNewlineAtEOF = false;
if (!content.endsWith('\n')) {
content += '\n';
hasNoNewlineAtEOF = true;
}
_a.filePath = filePath;
const result = _a.parse(content, strictMode, bailSensitivity, includeMetaData);
if (hasNoNewlineAtEOF) {
console.warn(`No newline at end of file, it's recommended to end a file with a newline. File:\n"${filePath}"`);
}
return result;
};
exports.default = YINI;