UNPKG

@formatjs/cli-lib

Version:
69 lines (68 loc) 2.11 kB
import { NodeTypes, } from '@vue/compiler-core'; import { parse } from 'vue/compiler-sfc'; function walk(node, visitor) { if (typeof node !== 'object' || node == null) { return; } if (node.type === NodeTypes.ROOT) { node.children.forEach(n => walk(n, visitor)); return; } if (node.type !== NodeTypes.ELEMENT && node.type !== NodeTypes.COMPOUND_EXPRESSION && node.type !== NodeTypes.INTERPOLATION) { return; } visitor(node); if (node.type === NodeTypes.INTERPOLATION) { visitor(node.content); } else if (node.type === NodeTypes.ELEMENT) { node.children.forEach(n => walk(n, visitor)); node.props .filter((prop) => prop.type === NodeTypes.DIRECTIVE) .filter(prop => !!prop.exp) .forEach(prop => visitor(prop.exp)); } else { node.children.forEach(n => walk(n, visitor)); } } function templateSimpleExpressionNodeVisitor(parseScriptFn) { return (n) => { if (typeof n !== 'object') { return; } if (n.type !== NodeTypes.SIMPLE_EXPRESSION) { return; } const { content } = n; // Wrap this in () since a vue comp node attribute can just be // an object literal which, by itself is invalid TS // but with () it becomes an ExpressionStatement try { parseScriptFn(`(${content})`); } catch (e) { console.warn(`Failed to parse "${content}". Ignore this if content has no extractable message`, e); } }; } export function parseFile(source, filename, parseScriptFn) { const { descriptor, errors } = parse(source, { filename, }); if (errors.length) { throw errors[0]; } const { script, scriptSetup, template } = descriptor; if (template) { walk(template.ast, templateSimpleExpressionNodeVisitor(parseScriptFn)); } if (script) { parseScriptFn(script.content); } if (scriptSetup) { parseScriptFn(scriptSetup.content); } }