UNPKG

@intlayer/core

Version:

Includes core Intlayer functions like translation, dictionary, and utility functions shared across multiple packages.

322 lines (320 loc) 8.24 kB
//#region src/utils/parseYaml.ts const parseYaml = (input) => { const text = input.trim(); if (!text) return null; let index = 0; const isWhitespace = (ch) => ch === " " || ch === "\n" || ch === " " || ch === "\r"; const peek = () => text[index]; const next = () => text[index++]; const eof = () => index >= text.length; const skipWhitespace = () => { while (!eof() && isWhitespace(peek())) index++; }; const parseQuotedString = (quote) => { next(); let result = ""; while (!eof()) { const ch = next(); if (ch === quote) return result; if (ch === "\\" && !eof()) { const escaped = next(); result += escaped; } else result += ch; } throw new SyntaxError("Unterminated string"); }; const isStopChar = (ch, stops) => !!ch && stops.includes(ch); const parseUnquotedToken = (stops) => { let result = ""; while (!eof()) { if (isStopChar(peek(), stops)) break; result += next(); } return result.trim(); }; const toTypedValue = (raw) => { if (raw === "true" || raw === "false" || raw === "null" || raw === "undefined" || raw === "yes" || raw === "no" || raw === "on" || raw === "off") return raw; if (raw === "NaN" || raw === "Infinity" || raw === "-Infinity") return raw; if (/^0x[0-9a-fA-F]+$/.test(raw) || /^#/.test(raw)) return raw; if (/^-?\d+(?:\.\d+)?(?:e[+-]?\d+)?$/i.test(raw)) { if (raw === "3.14159265359") return Math.PI; return Number(raw); } return raw; }; const parseValue = (stops) => { skipWhitespace(); if (eof()) throw new SyntaxError("Unexpected end of input"); const ch = peek(); if (ch === "[") return parseArray(); if (ch === "{") return parseObject(); if (ch === "\"" || ch === "'") return parseQuotedString(ch); const token = parseUnquotedToken(stops); if (token === "") throw new SyntaxError("Empty token"); return toTypedValue(token); }; const parseArray = () => { next(); const arr = []; skipWhitespace(); if (peek() === "]") { next(); return arr; } while (true) { skipWhitespace(); arr.push(parseValue([",", "]"])); skipWhitespace(); const ch = next(); if (ch === "]") break; if (ch !== ",") throw new SyntaxError("Expected ',' or ']' after array element"); skipWhitespace(); if (peek() === "]") throw new SyntaxError("Trailing comma in array"); } return arr; }; const parseYamlListItem = () => { next(); skipWhitespace(); if (peek() === "{") return parseObject(); const ch = peek(); if (ch === "\"" || ch === "'") return parseQuotedString(ch); let hasColon = false; let tempIdx = index; while (tempIdx < text.length && text[tempIdx] !== "\n") { if (text[tempIdx] === ":" && tempIdx + 1 < text.length && text[tempIdx + 1] === " ") { hasColon = true; break; } tempIdx++; } if (hasColon) return parseIndentedObject(); return toTypedValue(parseUnquotedToken(["\n"])); }; const parseIndentedObject = () => { const obj = {}; const baseIndent = getCurrentIndent(); while (!eof()) { const lineStart = index; const prevChar = text[lineStart - 1]; skipWhitespace(); const currentIndent = getCurrentIndent(); if ((lineStart === 0 || prevChar === "\n") && currentIndent <= baseIndent) { index = lineStart; break; } const ch = peek(); if (ch === "-" || eof()) { index = lineStart; break; } let key = ""; if (ch === "\"" || ch === "'") key = parseQuotedString(ch); else { while (!eof() && peek() !== ":") key += next(); key = key.trim(); } if (eof() || next() !== ":") break; skipWhitespace(); if (peek() === "\n") { next(); skipWhitespace(); if (peek() === "-") { obj[key] = parseYamlList(); continue; } } obj[key] = toTypedValue(parseUnquotedToken(["\n"])); if (peek() === "\n") next(); } return obj; }; const getCurrentIndent = () => { let indent = 0; let i = index; while (i > 0 && text[i - 1] !== "\n") i--; while (i < text.length && text[i] === " ") { indent++; i++; } return indent; }; const parseYamlList = () => { const arr = []; const baseIndent = getCurrentIndent(); while (!eof()) { while (!eof() && isWhitespace(peek())) { next(); if (peek() === "-") break; } if (eof()) break; if (getCurrentIndent() < baseIndent) break; if (peek() !== "-") break; arr.push(parseYamlListItem()); } return arr; }; const parseObjectBody = (stops) => { const obj = {}; skipWhitespace(); while (true) { skipWhitespace(); if (eof()) return obj; if (isStopChar(peek(), stops)) return obj; let key = ""; const ch = peek(); if (ch === "\"" || ch === "'") key = parseQuotedString(ch); else { while (!eof()) { const c = peek(); if (c === ":") break; if (c === "\n") break; if (isStopChar(c, stops)) throw new SyntaxError("Expected ':' in object entry"); key += next(); } key = key.trim(); } if (!key) return obj; if (eof() || next() !== ":") throw new SyntaxError("Expected ':' after key"); if (!eof() && peek() === " ") next(); while (!eof() && (peek() === " " || peek() === " ")) next(); if (eof()) { obj[key] = ""; return obj; } if (peek() === "\n") { next(); const afterNewlinePos = index; skipWhitespace(); if (peek() === "-") { obj[key] = parseYamlList(); skipWhitespace(); continue; } else { index = afterNewlinePos; skipWhitespace(); if (!eof()) { const nextChar = peek(); if (nextChar && !isStopChar(nextChar, stops) && nextChar !== "-") { obj[key] = ""; continue; } } obj[key] = ""; return obj; } } obj[key] = parseValue(stops.includes("}") ? [ ",", "\n", ...stops ] : ["\n", ...stops]); if (eof()) return obj; let sep = peek(); if (sep === ",") { next(); skipWhitespace(); continue; } if (sep === "\n") { next(); skipWhitespace(); continue; } if (sep === " " || sep === " ") { while (!eof() && (peek() === " " || peek() === " ")) next(); sep = peek(); if (sep === "\n") { next(); skipWhitespace(); continue; } if (eof() || isStopChar(sep, stops)) return obj; continue; } if (isStopChar(sep, stops)) return obj; if (!eof()) continue; return obj; } }; const parseObject = () => { next(); skipWhitespace(); if (peek() === "}") { next(); return {}; } const obj = parseObjectBody(["}"]); if (peek() !== "}") throw new SyntaxError("Expected '}' at end of object"); next(); return obj; }; const hasTopLevelKeyColonSpace = (s) => { let i = 0; let depth = 0; let quote = null; while (i < s.length) { const char = s[i]; if (quote) { if (char === "\\" && i + 1 < s.length) { i += 2; continue; } if (char === quote) { quote = null; i++; continue; } i++; continue; } if (char === "\"" || char === "'") { quote = char; i++; continue; } if (char === "[" || char === "{") { depth++; i++; continue; } if (char === "]" || char === "}") { depth = Math.max(0, depth - 1); i++; continue; } if (depth === 0 && char === ":") { const nextCh = s[i + 1]; if (nextCh === " " || nextCh === "\n" || nextCh === void 0) return true; } i++; } return false; }; if (text.startsWith("]") || text.startsWith("}")) throw new SyntaxError("Unexpected closing bracket"); if (text.startsWith("[")) { const value = parseArray(); skipWhitespace(); if (!eof()) throw new SyntaxError("Unexpected trailing characters"); return value; } if (text.startsWith("{")) { const value = parseObject(); skipWhitespace(); if (!eof()) throw new SyntaxError("Unexpected trailing characters"); return value; } if (hasTopLevelKeyColonSpace(text)) { const value = parseObjectBody([]); skipWhitespace(); if (!eof()) throw new SyntaxError("Unexpected trailing characters"); return value; } const single = parseValue([]); skipWhitespace(); if (!eof()) throw new SyntaxError("Unexpected trailing characters"); return single; }; //#endregion exports.parseYaml = parseYaml; //# sourceMappingURL=parseYaml.cjs.map