UNPKG

@nitrogenbuilder/client-core

Version:

Nitrogen Builder Core Client

89 lines (88 loc) 2.64 kB
export function parseSegment(raw) { const trimmed = raw.trim(); const parts = []; const tokens = splitOnPlus(trimmed); for (const token of tokens) { const t = token.trim(); if ((t.startsWith("'") && t.endsWith("'")) || (t.startsWith('"') && t.endsWith('"'))) { parts.push({ type: 'literal', value: t.slice(1, -1), filters: [] }); } else { const colonParts = splitOnColons(t); const path = colonParts[0]; const filters = colonParts.slice(1).map(parseFilterToken); parts.push({ type: 'path', value: path, filters }); } } return { parts }; } function parseFilterToken(token) { const parenIndex = token.indexOf('('); if (parenIndex === -1) { return { name: token, args: [] }; } const name = token.slice(0, parenIndex); const argsStr = token.slice(parenIndex + 1, -1); // strip parens const args = splitArgs(argsStr).map(parseArg); return { name, args }; } function parseArg(raw) { const trimmed = raw.trim(); if ((trimmed.startsWith("'") && trimmed.endsWith("'")) || (trimmed.startsWith('"') && trimmed.endsWith('"'))) { return trimmed.slice(1, -1); } const num = Number(trimmed); return isNaN(num) ? trimmed : num; } /** Split on `+` outside of quotes and parentheses */ function splitOnPlus(str) { return splitOutside(str, '+'); } /** Split on `:` outside of quotes and parentheses */ function splitOnColons(str) { return splitOutside(str, ':'); } /** Split on `,` outside of quotes and parentheses */ function splitArgs(str) { return splitOutside(str, ','); } function splitOutside(str, delimiter) { const results = []; let current = ''; let inQuote = false; let parenDepth = 0; for (let i = 0; i < str.length; i++) { const ch = str[i]; if ((ch === "'" || ch === '"') && parenDepth === 0 && !inQuote) { inQuote = ch; current += ch; } else if (inQuote && ch === inQuote) { inQuote = false; current += ch; } else if (inQuote) { current += ch; } else if (ch === '(') { parenDepth++; current += ch; } else if (ch === ')') { parenDepth--; current += ch; } else if (ch === delimiter && parenDepth === 0) { results.push(current); current = ''; } else { current += ch; } } if (current) results.push(current); return results; }