UNPKG

@vendure/ngx-translate-extract

Version:
133 lines 5.19 kB
import { parseTemplate, BindingPipe, LiteralPrimitive, Conditional, Binary, LiteralMap, LiteralArray, Interpolation, Call, TmplAstIfBlock, TmplAstSwitchBlock, TmplAstDeferredBlock, TmplAstForLoopBlock, KeyedRead } from '@angular/compiler'; import { TranslationCollection } from '../utils/translation.collection.js'; import { isPathAngularComponent, extractComponentInlineTemplate } from '../utils/utils.js'; export const TRANSLATE_PIPE_NAMES = ['translate', 'marker']; function traverseAstNodes(nodes, visitor, accumulator = []) { for (const node of nodes) { if (node) { traverseAstNode(node, visitor, accumulator); } } return accumulator; } function traverseAstNode(node, visitor, accumulator = []) { accumulator.push(...visitor(node)); const children = []; if ('children' in node && node.children) { children.push(...node.children); } if (node instanceof TmplAstForLoopBlock) { children.push(node.empty); } if (node instanceof TmplAstDeferredBlock) { children.push(node.error); children.push(node.loading); children.push(node.placeholder); } if (node instanceof TmplAstIfBlock) { children.push(...node.branches.flatMap((inner) => inner.children)); } if (node instanceof TmplAstSwitchBlock) { children.push(...node.cases.flatMap((inner) => inner.children)); } return traverseAstNodes(children, visitor, accumulator); } export class PipeParser { extract(source, filePath) { if (filePath && isPathAngularComponent(filePath)) { source = extractComponentInlineTemplate(source); } let collection = new TranslationCollection(); const nodes = this.parseTemplate(source, filePath); const pipes = traverseAstNodes(nodes, (node) => this.findPipesInNode(node)); pipes.forEach((pipe) => { this.parseTranslationKeysFromPipe(pipe).forEach((key) => { collection = collection.add(key, '', filePath); }); }); return collection; } findPipesInNode(node) { const ret = []; if (node?.value?.ast) { ret.push(...this.getTranslatablesFromAst(node.value.ast)); } if (node?.attributes) { const translateableAttributes = node.attributes.filter((attr) => TRANSLATE_PIPE_NAMES.includes(attr.name)); ret.push(...ret, ...translateableAttributes); } if (node?.inputs) { node.inputs.forEach((input) => { if (input?.value?.ast) { ret.push(...this.getTranslatablesFromAst(input.value.ast)); } }); } if (node?.templateAttrs) { node.templateAttrs.forEach((attr) => { if (attr?.value?.ast) { ret.push(...this.getTranslatablesFromAst(attr.value.ast)); } }); } return ret; } parseTranslationKeysFromPipe(pipeContent) { const ret = []; if (pipeContent instanceof LiteralPrimitive) { ret.push(pipeContent.value); } else if (pipeContent instanceof Conditional) { const trueExp = pipeContent.trueExp; ret.push(...this.parseTranslationKeysFromPipe(trueExp)); const falseExp = pipeContent.falseExp; ret.push(...this.parseTranslationKeysFromPipe(falseExp)); } else if (pipeContent instanceof BindingPipe) { ret.push(...this.parseTranslationKeysFromPipe(pipeContent.exp)); } return ret; } getTranslatablesFromAst(ast) { if (ast instanceof BindingPipe) { if (TRANSLATE_PIPE_NAMES.includes(ast.name)) { return [ast, ...this.getTranslatablesFromAsts(ast.args)]; } return this.getTranslatablesFromAsts([ast.exp, ...ast.args]); } if (ast instanceof Interpolation) { return this.getTranslatablesFromAsts(ast.expressions); } if (ast instanceof Conditional) { return this.getTranslatablesFromAsts([ast.trueExp, ast.falseExp]); } if (ast instanceof Binary) { if (ast?.left && ast?.right) { return this.getTranslatablesFromAsts([ast.left, ast.right]); } } if (ast instanceof LiteralMap) { return this.getTranslatablesFromAsts(ast.values); } if (ast instanceof LiteralArray) { return this.getTranslatablesFromAsts(ast.expressions); } if (ast instanceof Call) { return this.getTranslatablesFromAsts(ast.args); } if (ast instanceof KeyedRead) { return this.getTranslatablesFromAsts([ast.receiver, ast.key]); } return []; } getTranslatablesFromAsts(asts) { return this.flatten(asts.map((ast) => this.getTranslatablesFromAst(ast))); } flatten(array) { return [].concat(...array); } parseTemplate(template, path) { return parseTemplate(template, path).nodes; } } //# sourceMappingURL=pipe.parser.js.map