UNPKG

yini-parser

Version:

Readable configuration without YAML foot-guns or JSON noise. The official Node.js parser for YINI config format — An INI-inspired configuration format with clear nesting, explicit types, and predictable parsing.

125 lines 3.69 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.removeUndefinedDeep = exports.removeUndefinedShallow = exports.sortObjectKeys = void 0; const isPlainObject = (value) => { return (typeof value === 'object' && value !== null && !Array.isArray(value) && Object.prototype.toString.call(value) === '[object Object]'); }; /** * Returns a new object with keys sorted alphabetically. * Arrays and non-plain objects are preserved as-is (unless deep + they contain plain objects). */ const sortObjectKeys = (obj, options = {}) => { const { deep = false, comparator } = options; if (!isPlainObject(obj)) { // If it's not a plain object (array, Date, null, primitive), return as-is. return obj; } const keys = Object.keys(obj).sort(comparator ?? ((a, b) => a.localeCompare(b))); const sortedEntries = keys.map((k) => { const value = obj[k]; if (deep) { if (isPlainObject(value)) { return [k, (0, exports.sortObjectKeys)(value, options)]; } if (Array.isArray(value)) { // Deep-sort any plain objects inside arrays, leave others as-is. return [ k, value.map((item) => isPlainObject(item) ? (0, exports.sortObjectKeys)(item, options) : item), ]; } } return [k, value]; }); // Preserve the original type T structurally. return Object.fromEntries(sortedEntries); }; exports.sortObjectKeys = sortObjectKeys; /** * Removes top-level properties with value `undefined`. * Does not recurse into nested objects or arrays. * * @param obj Any JS object * @returns A shallow copy with undefined properties removed, * except in nested objects or arrays. * * @example * Input: * const input = { * a: 1, * b: undefined, * c: { d: undefined, e: 2 }, * f: [1, undefined, 2] * }; * * Output: * { * a: 1, * c: { d: undefined, e: 2 }, * f: [1, undefined, 2] * } */ const removeUndefinedShallow = (obj) => { const cleaned = {}; for (const [key, value] of Object.entries(obj)) { if (value !== undefined) { cleaned[key] = value; } } return cleaned; }; exports.removeUndefinedShallow = removeUndefinedShallow; /** * Recursively removes properties with value `undefined` from objects * and arrays. * * @param obj Any JS value (object, array, primitive) * @returns A deep-cloned copy with all `undefined` removed, including in * nested objects and arrays. * * @example * Input: * const input = { * a: 1, * b: undefined, * c: { * d: undefined, * e: 2, * f: [1, undefined, { g: undefined, h: 42 }] * } * }; * * Output: * { * a: 1, * c: { * e: 2, * f: [1, { h: 42 }] * } * } */ const removeUndefinedDeep = (obj) => { if (obj === null || typeof obj !== 'object') { return obj; // primitive value } if (Array.isArray(obj)) { // Clean each element, and filter out undefined entries return obj .map((item) => (0, exports.removeUndefinedDeep)(item)) .filter((item) => item !== undefined); } const cleaned = {}; for (const [key, value] of Object.entries(obj)) { if (value !== undefined) { cleaned[key] = (0, exports.removeUndefinedDeep)(value); } } return cleaned; }; exports.removeUndefinedDeep = removeUndefinedDeep; //# sourceMappingURL=object.js.map