read-ini
Version:
Read and parse INI or ENV files
59 lines (58 loc) • 2.15 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.readIni = readIni;
exports.readIniFile = readIniFile;
const node_fs_1 = require("node:fs");
/**
* Parses an `.ini` or `.env` content, with an optional value-type converter.
*
* - section `[name]` namespaces are supported:
* - When a section appears multiple times, its inner values are extended.
* - Sections called `global` (case-insensitive) expose global variables.
* - Sections support aliasing: `[section "alias"]`, with the alias used as
* override for the section name.
* - each variable must be in the form of `name = value`
* - spaces surrounding `=`, `value` or section names are ignored
* - the `value` is taken until the end of line
* - lines that start with `;` or `#` are skipped
*/
function readIni(text, cb) {
const lines = text
.replace(/\r/g, '')
.split('\n')
.map(a => a.trim())
.filter(f => f.length > 1 && f[0] !== ';' && f[0] !== '#');
const result = {};
let root = result, section;
for (const a of lines) {
const m = a.match(/^\s*([\w$.-]+)\s*=\s*(.*)/);
if (m) {
const key = m[1], value = m[2];
root[key] = typeof cb === 'function' ? cb({ key, value, section }) : value;
}
else {
const s = a.match(/\[\s*([\w$.-]+)\s*("(.*)")?\s*]/);
if (s) {
section = { name: s[1], alias: s[3] };
const name = section.alias || section.name; // alias overrides name
if (name.toLowerCase() === 'global') {
root = result;
section = undefined;
}
else {
root = result[name] ??= {};
}
}
}
}
return result;
}
/**
* Reads and parses an INI (or `./env`) file, with an optional value-type converter.
*
* Underneath, it just reads the file and passes the text into the `readIni` function.
*/
function readIniFile(iniFile, cb) {
const text = (0, node_fs_1.readFileSync)(iniFile, 'utf-8');
return readIni(text, cb);
}