-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Closed
Labels
Description
Environment
latest nuxt
Reproduction
async function getRouteMeta(contents, absolutePath) {
if (!(absolutePath in pageContentsCache) || pageContentsCache[absolutePath] !== contents) {
pageContentsCache[absolutePath] = contents;
delete metaCache$1[absolutePath];
}
if (absolutePath in metaCache$1 && metaCache$1[absolutePath]) {
return metaCache$1[absolutePath];
}
const loader = getLoader(absolutePath);
const scriptBlocks = !loader ? null : loader === "vue" ? extractScriptContent(contents) : [{ code: contents, loader }];
if (!scriptBlocks) {
metaCache$1[absolutePath] = {};
return {};
}
const extractedMeta = {};
for (const script of scriptBlocks) {
if (!PAGE_META_RE.test(script.code)) {
continue;
}
const js = await transform(script.code, { loader: script.loader });
throw new Error(js.code)
const ast = parse(js.code, {
sourceType: "module",
ecmaVersion: "latest",
ranges: true
});
const dynamicProperties = /* @__PURE__ */ new Set();
let foundMeta = false;
walk(ast, {
enter(node) {
if (foundMeta) {
return;
}
if (node.type !== "ExpressionStatement" || node.expression.type !== "CallExpression" || node.expression.callee.type !== "Identifier" || node.expression.callee.name !== "definePageMeta") {
return;
}
foundMeta = true;
const pageMetaArgument = node.expression.arguments[0];
for (const key of extractionKeys) {
const property = pageMetaArgument.properties.find((property2) => property2.type === "Property" && property2.key.type === "Identifier" && property2.key.name === key);
if (!property) {
continue;
}
if (property.value.type === "ObjectExpression") {
const valueString = js.code.slice(property.value.range[0], property.value.range[1]);
try {
extractedMeta[key] = JSON.parse(runInNewContext(`JSON.stringify(${valueString})`, {}));
} catch {
console.debug(`[nuxt] Skipping extraction of \`${key}\` metadata as it is not JSON-serializable (reading \`${absolutePath}\`).`);
dynamicProperties.add(key);
continue;
}
}
if (property.value.type === "ArrayExpression") {
const values = [];
for (const element of property.value.elements) {
if (!element) {
continue;
}
if (element.type !== "Literal" || typeof element.value !== "string") {
console.debug(`[nuxt] Skipping extraction of \`${key}\` metadata as it is not an array of string literals (reading \`${absolutePath}\`).`);
dynamicProperties.add(key);
continue;
}
values.push(element.value);
}
extractedMeta[key] = values;
continue;
}
if (property.value.type !== "Literal" || typeof property.value.value !== "string" && typeof property.value.value !== "boolean") {
console.debug(`[nuxt] Skipping extraction of \`${key}\` metadata as it is not a string literal or array of string literals (reading \`${absolutePath}\`).`);
dynamicProperties.add(key);
continue;
}
extractedMeta[key] = property.value.value;
}
for (const property of pageMetaArgument.properties) {
if (property.type !== "Property") {
continue;
}
const isIdentifierOrLiteral = property.key.type === "Literal" || property.key.type === "Identifier";
if (!isIdentifierOrLiteral) {
continue;
}
const name = property.key.type === "Identifier" ? property.key.name : String(property.value);
if (name) {
dynamicProperties.add("meta");
break;
}
}
if (dynamicProperties.size) {
extractedMeta.meta ?? (extractedMeta.meta = {});
extractedMeta.meta[DYNAMIC_META_KEY] = dynamicProperties;
}
}
});
}
metaCache$1[absolutePath] = extractedMeta;
return extractedMeta;
}
Describe the bug
Ts code with decorators is passed to acorn.parse which can parse only js code. I see some plugins for ancorn to support ts!?
const ast = parse(js.code, {
sourceType: "module",
ecmaVersion: "latest",
ranges: true
});
Additional context
No response
Logs
No response
Reactions are currently unavailable