Skip to content

Commit

Permalink
poc
Browse files Browse the repository at this point in the history
  • Loading branch information
horvbalint committed Feb 15, 2025
1 parent 722d586 commit c661248
Showing 1 changed file with 38 additions and 44 deletions.
82 changes: 38 additions & 44 deletions src/rollup/plugins/handlers-meta.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { readFile } from "node:fs/promises";
import { transform } from "esbuild";
import type { Expression, Literal } from "estree";
import type { Nitro, NitroEventHandler } from "nitropack/types";
import type { Nitro } from "nitropack/types";
import { extname } from "pathe";
import type { Plugin } from "rollup";
import MagicString from "magic-string";

const virtualPrefix = "\0nitro-handler-meta:";

Expand All @@ -28,9 +28,8 @@ export function handlersMeta(nitro: Nitro) {
importer,
resolveOpts
);
if (!resolved) {
return;
}
if (!resolved) return;

return virtualPrefix + resolved.id;
}
},
Expand All @@ -41,62 +40,57 @@ export function handlersMeta(nitro: Nitro) {
}
},
async transform(code, id) {
if (!id.startsWith(virtualPrefix)) {
return;
}

let meta: NitroEventHandler["meta"] | null = null;
if (!id.startsWith(virtualPrefix)) return;

try {
const ext = extname(id) as keyof typeof esbuildLoaders;
const jsCode = await transform(code, {
const { code: jsCode } = await transform(code, {
loader: esbuildLoaders[ext],
}).then((r) => r.code);
});
const ast = this.parse(jsCode);
const s = new MagicString(jsCode);

for (const node of ast.body) {
// if its a relative import, we remove it, since it won't be in place
if (
node.type === "ImportDeclaration" &&
typeof node.source.value === "string" &&
node.source.value?.startsWith(".")
) {
s.remove(node.start!, node.end!);

Check failure on line 60 in src/rollup/plugins/handlers-meta.ts

View workflow job for this annotation

GitHub Actions / ci (ubuntu-latest)

Property 'start' does not exist on type 'ImportDeclaration'.

Check failure on line 60 in src/rollup/plugins/handlers-meta.ts

View workflow job for this annotation

GitHub Actions / ci (ubuntu-latest)

Property 'end' does not exist on type 'ImportDeclaration'.
}

// if its the macro call, we remove the code after it and replace it with the export
if (
node.type === "ExpressionStatement" &&
node.expression.type === "CallExpression" &&
node.expression.callee.type === "Identifier" &&
node.expression.callee.name === "defineRouteMeta" &&
node.expression.arguments.length === 1
) {
meta = astToObject(node.expression.arguments[0] as any);
break;
s.remove(node.end!, jsCode.length);

Check failure on line 71 in src/rollup/plugins/handlers-meta.ts

View workflow job for this annotation

GitHub Actions / ci (ubuntu-latest)

Property 'end' does not exist on type 'Directive | ExpressionStatement'.

const arg = jsCode.slice(
node.expression.arguments[0].start!,

Check failure on line 74 in src/rollup/plugins/handlers-meta.ts

View workflow job for this annotation

GitHub Actions / ci (ubuntu-latest)

Property 'start' does not exist on type 'Expression | SpreadElement'.
node.expression.arguments[0].end!

Check failure on line 75 in src/rollup/plugins/handlers-meta.ts

View workflow job for this annotation

GitHub Actions / ci (ubuntu-latest)

Property 'end' does not exist on type 'Expression | SpreadElement'.
);
s.overwrite(node.start!, node.end!, `export default ${arg}`);

Check failure on line 77 in src/rollup/plugins/handlers-meta.ts

View workflow job for this annotation

GitHub Actions / ci (ubuntu-latest)

Property 'start' does not exist on type 'Directive | ExpressionStatement'.

Check failure on line 77 in src/rollup/plugins/handlers-meta.ts

View workflow job for this annotation

GitHub Actions / ci (ubuntu-latest)

Property 'end' does not exist on type 'Directive | ExpressionStatement'.

return {
code: s.toString(),
map: s.generateMap(),
};
}
}

return {
code: "export default null",
map: null,
};
} catch (error) {
console.warn(
`[nitro] [handlers-meta] Cannot extra route meta for: ${id}: ${error}`
);
console.error(error);
return { code, map: null };
}

return {
code: `export default ${JSON.stringify(meta)};`,
map: null,
};
},
} satisfies Plugin;
}

function astToObject(node: Expression | Literal): any {
switch (node.type) {
case "ObjectExpression": {
const obj: Record<string, any> = {};
for (const prop of node.properties) {
if (prop.type === "Property") {
const key = (prop.key as any).name ?? (prop.key as any).value;
obj[key] = astToObject(prop.value as any);
}
}
return obj;
}
case "ArrayExpression": {
return node.elements.map((el) => astToObject(el as any)).filter(Boolean);
}
case "Literal": {
return node.value;
}
// No default
}
}

0 comments on commit c661248

Please sign in to comment.