diff --git a/packages/vue-script-setup-converter/src/lib/__snapshots__/convertSrc.test.ts.snap b/packages/vue-script-setup-converter/src/lib/__snapshots__/convertSrc.test.ts.snap
index 6a82991..9acbf06 100644
--- a/packages/vue-script-setup-converter/src/lib/__snapshots__/convertSrc.test.ts.snap
+++ b/packages/vue-script-setup-converter/src/lib/__snapshots__/convertSrc.test.ts.snap
@@ -2,6 +2,9 @@
exports[`snapshot > defineNuxtComponent 1`] = `
"import { defineNuxtComponent, useNuxtApp } from '#imports';
+definePageMeta({
+ name: 'HelloWorld', layout: 'test-layout', middleware: 'test-middleware'
+});
const { $client } = useNuxtApp();
diff --git a/packages/vue-script-setup-converter/src/lib/convertSrc.test.ts b/packages/vue-script-setup-converter/src/lib/convertSrc.test.ts
index c0a5d64..31b90b0 100644
--- a/packages/vue-script-setup-converter/src/lib/convertSrc.test.ts
+++ b/packages/vue-script-setup-converter/src/lib/convertSrc.test.ts
@@ -79,6 +79,8 @@ import { defineNuxtComponent, useNuxtApp } from '#imports';
export default defineNuxtComponent({
name: 'HelloWorld',
+ layout: 'test-layout',
+ middleware: 'test-middleware',
setup(props, ctx) {
const { $client } = useNuxtApp();
diff --git a/packages/vue-script-setup-converter/src/lib/convertSrc.ts b/packages/vue-script-setup-converter/src/lib/convertSrc.ts
index e096dca..8b9b735 100644
--- a/packages/vue-script-setup-converter/src/lib/convertSrc.ts
+++ b/packages/vue-script-setup-converter/src/lib/convertSrc.ts
@@ -8,6 +8,7 @@ import {
} from "ts-morph";
import { parse } from "@vue/compiler-sfc";
import { getNodeByKind } from "./helper";
+import { convertPageMeta } from "./converter/pageMetaConverter";
import { convertProps } from "./converter/propsConverter";
import { convertSetup } from "./converter/setupConverter";
import { convertEmits } from "./converter/emitsConverter";
@@ -40,6 +41,7 @@ export const convertSrc = (input: string) => {
throw new Error("defineComponent is not found.");
}
+ const pageMeta = convertPageMeta(callexpression, lang) ?? "";
const props = convertProps(callexpression, lang) ?? "";
const emits = convertEmits(callexpression, lang) ?? "";
const statement = convertSetup(callexpression) ?? "";
@@ -53,6 +55,10 @@ export const convertSrc = (input: string) => {
.map((x) => x.getText())
);
+ if (isDefineNuxtComponent(callexpression)) {
+ statements.addStatements(pageMeta);
+ }
+
statements.addStatements(props);
statements.addStatements(emits);
statements.addStatements(statement);
@@ -75,3 +81,10 @@ const isDefineComponent = (node: CallExpression) => {
node.getExpression().getText() === "defineNuxtComponent"
);
};
+
+const isDefineNuxtComponent = (node: CallExpression) => {
+ if (!Node.isIdentifier(node.getExpression())) {
+ return false;
+ }
+ return node.getExpression().getText() === "defineNuxtComponent";
+};
diff --git a/packages/vue-script-setup-converter/src/lib/converter/index.ts b/packages/vue-script-setup-converter/src/lib/converter/index.ts
index 5863e10..6af55d1 100644
--- a/packages/vue-script-setup-converter/src/lib/converter/index.ts
+++ b/packages/vue-script-setup-converter/src/lib/converter/index.ts
@@ -1,3 +1,4 @@
export * from "./emitsConverter";
+export * from "./pageMetaConverter";
export * from "./propsConverter";
export * from "./setupConverter";
diff --git a/packages/vue-script-setup-converter/src/lib/converter/pageMetaConverter.test.ts b/packages/vue-script-setup-converter/src/lib/converter/pageMetaConverter.test.ts
new file mode 100644
index 0000000..9cac85b
--- /dev/null
+++ b/packages/vue-script-setup-converter/src/lib/converter/pageMetaConverter.test.ts
@@ -0,0 +1,85 @@
+import { expect, describe, it } from "vitest";
+import { CallExpression, ScriptTarget, SyntaxKind, Project } from "ts-morph";
+import { parse } from "@vue/compiler-sfc";
+import prettier from "prettier";
+import parserTypeScript from "prettier/parser-typescript";
+import { getNodeByKind } from "../helper";
+import { convertPageMeta } from "./pageMetaConverter";
+
+const parseScript = (input: string, lang: "js" | "ts" = "js") => {
+ const {
+ descriptor: { script },
+ } = parse(input);
+
+ const project = new Project({
+ tsConfigFilePath: "tsconfig.json",
+ compilerOptions: {
+ target: ScriptTarget.Latest,
+ },
+ });
+
+ const sourceFile = project.createSourceFile("s.tsx", script?.content ?? "");
+
+ const callExpression = getNodeByKind(sourceFile, SyntaxKind.CallExpression);
+
+ const pageMeta = convertPageMeta(callExpression as CallExpression, lang);
+
+ const formatedText = prettier.format(pageMeta, {
+ parser: "typescript",
+ plugins: [parserTypeScript],
+ });
+
+ return formatedText;
+};
+
+describe("convertPageMeta", () => {
+ describe("basic", () => {
+ const source = ``;
+
+ it("returns text including definePageMeta", () => {
+ const output = parseScript(source);
+
+ const expected = `definePageMeta({
+ name: "HelloWorld",
+ layout: "test-layout",
+ middleware: "test-middleware",
+});
+`;
+
+ expect(output).toBe(expected);
+ });
+ });
+
+ describe("when middleware is array", () => {
+ const source = ``;
+
+ it("returns text including definePageMeta", () => {
+ const output = parseScript(source);
+
+ const expected = `definePageMeta({
+ name: "HelloWorld",
+ layout: "test-layout",
+ middleware: ["test-middleware-1", "test-middleware-2"],
+});
+`;
+
+ expect(output).toBe(expected);
+ });
+ });
+});
diff --git a/packages/vue-script-setup-converter/src/lib/converter/pageMetaConverter.ts b/packages/vue-script-setup-converter/src/lib/converter/pageMetaConverter.ts
new file mode 100644
index 0000000..70cbf5f
--- /dev/null
+++ b/packages/vue-script-setup-converter/src/lib/converter/pageMetaConverter.ts
@@ -0,0 +1,32 @@
+import { CallExpression, PropertyAssignment } from "ts-morph";
+import { getOptionsNode } from "../helper";
+
+export const convertPageMeta = (node: CallExpression, lang: string = "js") => {
+ const nameNode = getOptionsNode(node, "name");
+ const layoutNode = getOptionsNode(node, "layout");
+ const middlewareNode = getOptionsNode(node, "middleware");
+
+ if (!nameNode && !layoutNode && !middlewareNode) return "";
+
+ return convertToDefinePageMeta({ nameNode, layoutNode, middlewareNode });
+};
+
+const convertToDefinePageMeta = ({
+ nameNode,
+ layoutNode,
+ middlewareNode,
+}: {
+ nameNode: PropertyAssignment | undefined;
+ layoutNode: PropertyAssignment | undefined;
+ middlewareNode: PropertyAssignment | undefined;
+}) => {
+ const nameProperty = nameNode ? nameNode.getText() : "";
+ const layoutProperty = layoutNode ? layoutNode.getText() : "";
+ const middlewareProperty = middlewareNode ? middlewareNode.getText() : "";
+
+ return `definePageMeta({
+ ${[nameProperty, layoutProperty, middlewareProperty]
+ .filter(Boolean)
+ .join(",")}
+ });`;
+};
diff --git a/packages/vue-script-setup-converter/src/lib/helper.ts b/packages/vue-script-setup-converter/src/lib/helper.ts
index a20b97a..c6057b7 100644
--- a/packages/vue-script-setup-converter/src/lib/helper.ts
+++ b/packages/vue-script-setup-converter/src/lib/helper.ts
@@ -17,7 +17,7 @@ export const getNodeByKind = (
export const getOptionsNode = (
node: CallExpression,
- type: "props" | "emits"
+ type: "name" | "layout" | "middleware" | "props" | "emits"
) => {
const expression = getNodeByKind(node, SyntaxKind.ObjectLiteralExpression);