UNPKG

@anatine/esbuild-decorators

Version:
158 lines 4.8 kB
"use strict"; // NOTE: Possible future adoption for HTML... thinking of React // But I haven't seen decorators much less metadata in React projects // const HTML = { // BLOCK_OPEN_REGEX: /^\n*<!--(?!-?>)/, // BLOCK_CLOSE_REGEX: /^(?<!(?:<!-))-->/, // BLOCK_CLOSE_LOOSE_REGEX: /^(?<!(?:<!-))--\s*>/, // BLOCK_CLOSE_STRICT_NEWLINE_REGEX: /^(?<!(?:<!-))-->(\s*\n+|\n*)/, // BLOCK_CLOSE_STRICT_LOOSE_REGEX: /^(?<!(?:<!-))--\s*>(\s*\n+|\n*)/, // }; Object.defineProperty(exports, "__esModule", { value: true }); exports.strip = void 0; class TextNode { constructor(node) { this.type = node.type; this.value = node.value; this.match = node.match; this.newline = node.newline || ''; } get protected() { return Boolean(this.match) && this.match[1] === '!'; } } class TextBlock extends TextNode { constructor(node) { super(node); this.nodes = node.nodes || []; } push(node) { this.nodes.push(node); } get protected() { return this.nodes.length > 0 && this.nodes[0].protected === true; } } const constants = { ESCAPED_CHAR_REGEX: /^\\./, QUOTED_STRING_REGEX: /^(['"`])((?:\\.|[^\1])+?)(\1)/, NEWLINE_REGEX: /^\r*\n/, BLOCK_OPEN_REGEX: /^\/\*\*?(!?)/, BLOCK_CLOSE_REGEX: /^\*\/(\n?)/, LINE_REGEX: /^\/\/(!?).*/, }; const parse = (input) => { const cst = new TextBlock({ type: 'root', nodes: [] }); const stack = [cst]; const { ESCAPED_CHAR_REGEX, QUOTED_STRING_REGEX, NEWLINE_REGEX, BLOCK_CLOSE_REGEX, BLOCK_OPEN_REGEX, LINE_REGEX, } = constants; let block = cst; let remaining = input; let token; let prev; /** * Helpers */ const consume = (value = remaining[0] || '') => { remaining = remaining.slice(value.length); return value; }; const scan = (regex, type = 'text') => { const match = regex.exec(remaining); if (match) { consume(match[0]); return { type, value: match[0], match }; } }; const push = (node) => { if (prev && prev.type === 'text' && node.type === 'text') { prev.value += node.value; return; } block.push(node); if (node.nodes) { stack.push(node); block = node; } prev = node; }; const pop = () => { if (block.type === 'root') { throw new SyntaxError('Unclosed block comment'); } stack.pop(); block = stack[stack.length - 1]; }; /** * Parse input string */ while (remaining !== '') { // escaped characters if ((token = scan(ESCAPED_CHAR_REGEX, 'text'))) { push(new TextNode(token)); continue; } // quoted strings if (block.type !== 'block' && (!prev || !/\w$/.test(prev.value))) { // Changing type "text" to "line" so that the code also removes strings if ((token = scan(QUOTED_STRING_REGEX, 'line'))) { push(new TextNode(token)); continue; } } // newlines if ((token = scan(NEWLINE_REGEX, 'newline'))) { push(new TextNode(token)); continue; } // block comment open if ((token = scan(BLOCK_OPEN_REGEX, 'open'))) { push(new TextBlock({ type: 'block' })); push(new TextNode(token)); continue; } // block comment close if (block.type === 'block') { if ((token = scan(BLOCK_CLOSE_REGEX, 'close'))) { token.newline = token.match[1] || ''; push(new TextNode(token)); pop(); continue; } } // line comment if (block.type !== 'block') { if ((token = scan(LINE_REGEX, 'line'))) { push(new TextNode(token)); continue; } } push(new TextNode({ type: 'text', value: consume(remaining[0]) })); } return cst; }; const compile = (cst) => { const walk = (node) => { let output = ''; for (const child of node.nodes) { switch (child.type) { case 'block': break; case 'line': break; case 'open': case 'close': case 'text': case 'newline': default: { output += child.value || ''; break; } } } return output; }; return walk(cst); }; const strip = (input) => compile(parse(input)); exports.strip = strip; //# sourceMappingURL=strip-it.js.map