@formatjs/cli
Version:
A CLI for formatjs.
99 lines (98 loc) • 3.65 kB
JavaScript
import { fileURLToPath as _furl } from "node:url";
import { dirname as _dname } from "node:path";
_dname(_furl(import.meta.url));
import { parse } from "svelte/compiler";
//#region packages/cli-lib/svelte_extractor.ts
function walkFragment(fragment, source, parseScriptFn) {
if (!fragment || !fragment.nodes) return;
for (const node of fragment.nodes) walkNode(node, source, parseScriptFn);
}
function extractExpression(expression, source, parseScriptFn) {
if (!expression || expression.start == null || expression.end == null) return;
const content = source.slice(expression.start, expression.end);
try {
parseScriptFn(`(${content})`);
} catch (e) {
console.warn(`Failed to parse "${content}". Ignore this if content has no extractable message`, e);
}
}
function walkNode(node, source, parseScriptFn) {
switch (node.type) {
case "ExpressionTag":
extractExpression(node.expression, source, parseScriptFn);
break;
case "ConstTag":
if (node.declaration) {
const content = source.slice(node.declaration.start, node.declaration.end);
try {
parseScriptFn(content);
} catch (e) {
console.warn(`Failed to parse const declaration. Ignore this if content has no extractable message`, e);
}
}
break;
case "IfBlock":
extractExpression(node.test, source, parseScriptFn);
walkFragment(node.consequent, source, parseScriptFn);
walkFragment(node.alternate, source, parseScriptFn);
break;
case "EachBlock":
extractExpression(node.expression, source, parseScriptFn);
if (node.key) extractExpression(node.key, source, parseScriptFn);
walkFragment(node.body, source, parseScriptFn);
walkFragment(node.fallback, source, parseScriptFn);
break;
case "AwaitBlock":
extractExpression(node.expression, source, parseScriptFn);
walkFragment(node.pending, source, parseScriptFn);
walkFragment(node.then, source, parseScriptFn);
walkFragment(node.catch, source, parseScriptFn);
break;
case "KeyBlock":
extractExpression(node.expression, source, parseScriptFn);
walkFragment(node.fragment, source, parseScriptFn);
break;
case "SnippetBlock":
walkFragment(node.body, source, parseScriptFn);
break;
case "RegularElement":
case "Component":
case "SvelteComponent":
case "SvelteElement":
case "SvelteHead":
case "SvelteBody":
case "SvelteWindow":
case "SvelteDocument":
case "SlotElement":
case "SvelteSelf":
case "SvelteFragment":
if (node.attributes) {
for (const attr of node.attributes) if (attr.type === "Attribute") {
if (Array.isArray(attr.value)) {
for (const v of attr.value) if (v.type === "ExpressionTag") extractExpression(v.expression, source, parseScriptFn);
} else if (typeof attr.value === "object" && attr.value !== null && attr.value.type === "ExpressionTag") extractExpression(attr.value.expression, source, parseScriptFn);
} else if (attr.type === "SpreadAttribute") extractExpression(attr.expression, source, parseScriptFn);
else if (attr.expression) extractExpression(attr.expression, source, parseScriptFn);
}
walkFragment(node.fragment, source, parseScriptFn);
break;
}
}
function parseFile(source, filename, parseScriptFn) {
const ast = parse(source, {
modern: true,
filename
});
walkFragment(ast.fragment, source, parseScriptFn);
if (ast.instance) {
const program = ast.instance.content;
parseScriptFn(source.slice(program.start, program.end));
}
if (ast.module) {
const program = ast.module.content;
parseScriptFn(source.slice(program.start, program.end));
}
}
//#endregion
export { parseFile };
//# sourceMappingURL=svelte_extractor-R4PlmulG.js.map