UNPKG

promisified-properties

Version:

Handle .properties file via promisified and typed API

109 lines (108 loc) 3.55 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.PropertiesParser = void 0; exports.parse = parse; const parsimmon_1 = __importDefault(require("parsimmon")); /** * Append a line-break to the end of line, if the end of line is not escaped by '\' */ function appendLineBreak(line) { if (/(^|[^\\])(\\\\)*\\$/.test(line)) { return line.substring(0, line.length - 1); } else { return line + "\n"; } } function interpretEscapes(str) { return str.replace(/\\(u[0-9a-fA-F]{4}|[^u])/g, (_, escape) => { const type = escape.charAt(0); if (type === "u") { const hex = escape.slice(1); return String.fromCharCode(parseInt(hex, 16)); } switch (type) { case "f": return "\f"; case "n": return "\n"; case "r": return "\r"; case "t": return "\t"; } return type; }); } exports.PropertiesParser = parsimmon_1.default.createLanguage({ /** * WhiteSpace defined in the spec */ WhiteSpace: (r) => { return parsimmon_1.default.regexp(/( |\f|\t|\\u0009|\\u0020|\\u000C)*/); }, NaturalLine: (r) => { return r.BrankLine.map((_) => "").or(parsimmon_1.default.regexp(/.*/)); }, /** * The natural line that contains only white space characters. * Ignored by parser. */ BrankLine: (r) => { return parsimmon_1.default.regexp(/^( |\f|\t|\\u0009|\\u0020|\\u000C)*$/); }, /** * The natural line that has an ASCII '#' or '!' as its first non-white space character. * Ignored by parser. */ CommentLine: (r) => { return parsimmon_1.default.regexp(/^[!#].*/).trim(r.WhiteSpace); }, LogicalLine: (r) => { const p1 = parsimmon_1.default.seqObj(["key", r.Key.trim(r.WhiteSpace)], r.KeyTerminator, ["value", r.Value.trim(r.WhiteSpace)]); const p2 = parsimmon_1.default.seqObj(["key", r.Key.trim(r.WhiteSpace)], r.WhiteSpace); const p3 = parsimmon_1.default.seqObj(["text", r.Comment]); return p1.or(p2).or(p3); }, /** * Key terminator defined in the spec */ KeyTerminator: (r) => { return parsimmon_1.default.oneOf(":="); }, Key: (r) => { return parsimmon_1.default.regexp(/([a-zA-Z0-9_.-]|\\u[a-z0-9]{4}|\\[\\a-zA-Z0-9=:])+/) .trim(r.WhiteSpace) .map(interpretEscapes); }, Value: (r) => { return parsimmon_1.default.all.trim(r.WhiteSpace).map(interpretEscapes); }, Comment: (r) => { return parsimmon_1.default.all.map(interpretEscapes); }, }); function parse(s) { const logicalLines = exports.PropertiesParser.NaturalLine.sepBy(parsimmon_1.default.newline) .map((naturalLines) => { return naturalLines .map(appendLineBreak) .join("") .split("\n") .filter((s) => s.length > 0); }) .tryParse(s); const logicalLineParser = exports.PropertiesParser.LogicalLine; return logicalLines.map((logicalLine) => { const result = logicalLineParser.tryParse(logicalLine); if ("value" in result) { return { key: result.key, value: result.value?.trim() }; } else { return result; } }); }