INI Config Parser With Sections and Types
Parse INI configuration into null-prototype objects with sections, comments, quoted values, type coercion and duplicate detection.
Code
export function parseIni(text, options = {}) {
if (typeof text !== "string") throw new TypeError("text must be a string");
const { typed = true } = options;
const result = Object.create(null);
let section = result;
const lines = text.split(/\r?\n/);
for (let index = 0; index < lines.length; index += 1) {
const line = lines[index].trim();
if (line === "" || line.startsWith(";") || line.startsWith("#")) continue;
if (line.startsWith("[") && line.endsWith("]")) {
const name = line.slice(1, -1).trim();
if (name === "") throw new Error(`empty section name on line ${index + 1}`);
if (Object.prototype.hasOwnProperty.call(result, name)) {
throw new Error(`duplicate section "${name}" on line ${index + 1}`);
}
section = Object.create(null);
result[name] = section;
continue;
}
const equals = line.indexOf("=");
if (equals <= 0) throw new Error(`invalid entry on line ${index + 1}`);
const key = line.slice(0, equals).trim();
let value = line.slice(equals + 1).trim();
if (key === "" || /[\[\]]/.test(key)) throw new Error(`invalid key on line ${index + 1}`);
if (Object.prototype.hasOwnProperty.call(section, key)) {
throw new Error(`duplicate key "${key}" on line ${index + 1}`);
}
value = unquote(value);
section[key] = typed ? coerce(value) : value;
}
return result;
}
function unquote(value) {
if (value.length >= 2 && value.startsWith('"') && value.endsWith('"')) {
return value.slice(1, -1);
}
if (value.length >= 2 && value.startsWith("'") && value.endsWith("'")) {
return value.slice(1, -1);
}
return value;
}
function coerce(value) {
if (value === "true") return true;
if (value === "false") return false;
if (value === "null") return null;
if (/^-?\d+$/.test(value)) return Number(value);
if (/^-?\d+\.\d+$/.test(value)) return Number(value);
return value;
}
const config = parseIni(`
; application settings
name = "Demo App"
debug = false
retries = 3
[server]
host = 127.0.0.1
port = 8080
`);
console.log(config);Report a problem with this exampleOpens a pre-filled issue on GitHub.