| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470 | 'use strict';// match1 - section, match2 - optional full inheritance  part, match3 - inherited sectionvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var REGEXP_SECTION = /^\s*\[\s*([^:]*?)\s*(:\s*(.+?)\s*)?\]\s*$/;var REGEXP_COMMENT = /^;.*/;var REGEXP_SINGLE_LINE = /^\s*(.*?)\s*?=\s*?(\S.*?)$/;var REGEXP_MULTI_LINE = /^\s*(.*?)\s*?=\s*?"(.*?)$/;var REGEXP_NOT_ESCAPED_MULTI_LINE_END = /^(.*?)\\"$/;var REGEXP_MULTI_LINE_END = /^(.*?)"$/;var REGEXP_ARRAY = /^(.*?)\[\]$/;var STATUS_OK = 0;var STATUS_INVALID = 1;var defaults = {    ignore_invalid: true,    keep_quotes: false,    nested_section_names: false,    keep_zero_prefix: false,    oninvalid: function () {        return true;    },    filters: [],    constants: {}};var REGEXP_IGNORE_KEYS = /__proto__|constructor|prototype/;var Parser = function () {    function Parser() {        var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};        _classCallCheck(this, Parser);        this.options = _extends({}, defaults, options);        this.handlers = [this.handleMultiLineStart, this.handleMultiLineEnd, this.handleMultiLineAppend, this.handleComment, this.handleSection, this.handleSingleLine];    }    _createClass(Parser, [{        key: 'parse',        value: function parse(lines) {            var ctx = {                ini: {},                current: {},                multiLineKeys: false,                multiLineValue: ''            };            var _iteratorNormalCompletion = true;            var _didIteratorError = false;            var _iteratorError = undefined;            try {                for (var _iterator = lines[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {                    var line = _step.value;                    var _iteratorNormalCompletion2 = true;                    var _didIteratorError2 = false;                    var _iteratorError2 = undefined;                    try {                        for (var _iterator2 = this.handlers[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {                            var handler = _step2.value;                            var stop = handler.call(this, ctx, line);                            if (stop) {                                break;                            }                        }                    } catch (err) {                        _didIteratorError2 = true;                        _iteratorError2 = err;                    } finally {                        try {                            if (!_iteratorNormalCompletion2 && _iterator2.return) {                                _iterator2.return();                            }                        } finally {                            if (_didIteratorError2) {                                throw _iteratorError2;                            }                        }                    }                }            } catch (err) {                _didIteratorError = true;                _iteratorError = err;            } finally {                try {                    if (!_iteratorNormalCompletion && _iterator.return) {                        _iterator.return();                    }                } finally {                    if (_didIteratorError) {                        throw _iteratorError;                    }                }            }            return ctx.ini;        }    }, {        key: 'isSection',        value: function isSection(line) {            return line.match(REGEXP_SECTION);        }    }, {        key: 'getSection',        value: function getSection(line) {            return line.match(REGEXP_SECTION)[1];        }    }, {        key: 'getParentSection',        value: function getParentSection(line) {            return line.match(REGEXP_SECTION)[3];        }    }, {        key: 'isInheritedSection',        value: function isInheritedSection(line) {            return !!line.match(REGEXP_SECTION)[3];        }    }, {        key: 'isComment',        value: function isComment(line) {            return line.match(REGEXP_COMMENT);        }    }, {        key: 'isSingleLine',        value: function isSingleLine(line) {            var result = line.match(REGEXP_SINGLE_LINE);            if (!result) {                return false;            }            var check = result[2].match(/"/g);            return !check || check.length % 2 === 0;        }    }, {        key: 'isMultiLine',        value: function isMultiLine(line) {            var result = line.match(REGEXP_MULTI_LINE);            if (!result) {                return false;            }            var check = result[2].match(/"/g);            return !check || check.length % 2 === 0;        }    }, {        key: 'isMultiLineEnd',        value: function isMultiLineEnd(line) {            return line.match(REGEXP_MULTI_LINE_END) && !line.match(REGEXP_NOT_ESCAPED_MULTI_LINE_END);        }    }, {        key: 'isArray',        value: function isArray(line) {            return line.match(REGEXP_ARRAY);        }    }, {        key: 'assignValue',        value: function assignValue(element, keys, value) {            value = this.applyFilter(value);            var current = element;            var previous = element;            var array = false;            var key = void 0;            if (keys.some(function (key) {                return REGEXP_IGNORE_KEYS.test(key);            })) {                return;            }            var _iteratorNormalCompletion3 = true;            var _didIteratorError3 = false;            var _iteratorError3 = undefined;            try {                for (var _iterator3 = keys[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {                    key = _step3.value;                    if (this.isArray(key)) {                        key = this.getArrayKey(key);                        array = true;                    }                    if (current[key] == null) {                        current[key] = array ? [] : {};                    }                    previous = current;                    current = current[key];                }            } catch (err) {                _didIteratorError3 = true;                _iteratorError3 = err;            } finally {                try {                    if (!_iteratorNormalCompletion3 && _iterator3.return) {                        _iterator3.return();                    }                } finally {                    if (_didIteratorError3) {                        throw _iteratorError3;                    }                }            }            if (array) {                current.push(value);            } else {                previous[key] = value;            }            return element;        }    }, {        key: 'applyFilter',        value: function applyFilter(value) {            var _iteratorNormalCompletion4 = true;            var _didIteratorError4 = false;            var _iteratorError4 = undefined;            try {                for (var _iterator4 = this.options.filters[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {                    var filter = _step4.value;                    value = filter(value, this.options);                }            } catch (err) {                _didIteratorError4 = true;                _iteratorError4 = err;            } finally {                try {                    if (!_iteratorNormalCompletion4 && _iterator4.return) {                        _iterator4.return();                    }                } finally {                    if (_didIteratorError4) {                        throw _iteratorError4;                    }                }            }            return value;        }    }, {        key: 'getKeyValue',        value: function getKeyValue(line) {            var result = line.match(REGEXP_SINGLE_LINE);            if (!result) {                throw new Error();            }            var _result = _slicedToArray(result, 3),                key = _result[1],                value = _result[2];            if (!this.options.keep_quotes) {                value = value.replace(/^\s*?"(.*?)"\s*?$/, '$1');            }            return { key: key, value: value, status: STATUS_OK };        }    }, {        key: 'getMultiKeyValue',        value: function getMultiKeyValue(line) {            var result = line.match(REGEXP_MULTI_LINE);            if (!result) {                throw new Error();            }            var _result2 = _slicedToArray(result, 3),                key = _result2[1],                value = _result2[2];            if (this.options.keep_quotes) {                value = '"' + value;            }            return { key: key, value: value };        }    }, {        key: 'getMultiLineEndValue',        value: function getMultiLineEndValue(line) {            var result = line.match(REGEXP_MULTI_LINE_END);            if (!result) {                throw new Error();            }            var _result3 = _slicedToArray(result, 2),                value = _result3[1];            if (this.options.keep_quotes) {                value = value + '"';            }            return { value: value, status: STATUS_OK };        }    }, {        key: 'getArrayKey',        value: function getArrayKey(line) {            var result = line.match(REGEXP_ARRAY);            return result[1];        }    }, {        key: 'handleMultiLineStart',        value: function handleMultiLineStart(ctx, line) {            if (!this.isMultiLine(line.trim())) {                return false;            }            var _getMultiKeyValue = this.getMultiKeyValue(line),                key = _getMultiKeyValue.key,                value = _getMultiKeyValue.value;            var keys = key.split('.');            ctx.multiLineKeys = keys;            ctx.multiLineValue = value;            return true;        }    }, {        key: 'handleMultiLineEnd',        value: function handleMultiLineEnd(ctx, line) {            if (!ctx.multiLineKeys || !this.isMultiLineEnd(line.trim())) {                return false;            }            var _getMultiLineEndValue = this.getMultiLineEndValue(line),                value = _getMultiLineEndValue.value,                status = _getMultiLineEndValue.status;            // abort on false of onerror callback if we meet an invalid line            if (status === STATUS_INVALID && !this.options.oninvalid(line)) {                return;            }            // ignore whole multiline on invalid            if (status === STATUS_INVALID && this.options.ignore_invalid) {                ctx.multiLineKeys = false;                ctx.multiLineValue = '';                return true;            }            ctx.multiLineValue += '\n' + value;            this.assignValue(ctx.current, ctx.multiLineKeys, ctx.multiLineValue);            ctx.multiLineKeys = false;            ctx.multiLineValue = '';            return true;        }    }, {        key: 'handleMultiLineAppend',        value: function handleMultiLineAppend(ctx, line) {            if (!ctx.multiLineKeys || this.isMultiLineEnd(line.trim())) {                return false;            }            ctx.multiLineValue += '\n' + line;            return true;        }    }, {        key: 'handleComment',        value: function handleComment(ctx, line) {            return this.isComment(line.trim());        }    }, {        key: 'handleSection',        value: function handleSection(ctx, line) {            line = line.trim();            if (!this.isSection(line)) {                return false;            }            var section = this.getSection(line);            if (REGEXP_IGNORE_KEYS.test(section)) {                return false;            }            this.createSection(ctx, section);            if (this.isInheritedSection(line)) {                var parentSection = this.getParentSection(line);                ctx.current = _extends(ctx.current, JSON.parse(JSON.stringify(ctx.ini[parentSection])));            }            return true;        }    }, {        key: 'handleSingleLine',        value: function handleSingleLine(ctx, line) {            line = line.trim();            if (!this.isSingleLine(line)) {                return false;            }            var _getKeyValue = this.getKeyValue(line),                key = _getKeyValue.key,                value = _getKeyValue.value,                status = _getKeyValue.status;            // abort on false of onerror callback if we meet an invalid line            if (status === STATUS_INVALID && !this.options.oninvalid(line)) {                throw new Error('Abort');            }            // skip entry            if (status === STATUS_INVALID && !this.options.ignore_invalid) {                return true;            }            var keys = key.split('.');            this.assignValue(ctx.current, keys, value);            return true;        }    }, {        key: 'createSection',        value: function createSection(ctx, section) {            var sections = (this.options.nested_section_names ? section.split('.') : [section]).map(function (name) {                return name.trim();            });            ctx.current = sections.reduce(function (ini, name) {                if (typeof ini[name] === 'undefined') {                    ini[name] = {};                }                return ini[name];            }, ctx.ini);        }    }]);    return Parser;}();module.exports = Parser;
 |