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);