import { expect, test } from "vitest" import { transform } from "../../src/utils/transformers" test("transform nested workspace folder for utils, website/src/utils", async () => { expect( await transform({ filename: "test.ts", raw: `import { Button } from "website/src/components/ui/button" import { Box } from "website/src/components/box" import { cn } from "website/src/utils" `, config: { tsx: true, tailwind: { baseColor: "neutral", cssVariables: true, }, aliases: { components: "website/src/components", lib: "website/src/lib", utils: "website/src/utils", }, }, }) ).toMatchInlineSnapshot(` "import { Button } from "website/src/components/ui/button" import { Box } from "website/src/components/box" import { cn } from "website/src/utils" " `) }) test.each([ { name: "bare aliases", aliases: { components: "components", ui: "components/ui", lib: "lib", utils: "lib/utils", }, buttonImport: `import { Button } from "components/ui/button"`, utilsImport: `import { cn } from "lib/utils"`, }, { name: "path-like aliases", aliases: { components: "website/src/components", ui: "website/src/components/ui", lib: "website/src/lib", utils: "website/src/lib/utils", }, buttonImport: `import { Button } from "website/src/components/ui/button"`, utilsImport: `import { cn } from "website/src/lib/utils"`, }, ])( "transform import with non-sigil aliases: $name", async ({ aliases, buttonImport, utilsImport }) => { const result = await transform({ filename: "test.ts", raw: `import { Button } from "@/registry/new-york/ui/button" import { cn } from "@/lib/utils" `, config: { tsx: true, aliases, }, }) expect(result).toContain(buttonImport) expect(result).toContain(utilsImport) } ) test("transform import", async () => { expect( await transform({ filename: "test.ts", raw: `import * as React from "react" import { Foo } from "bar" import { Button } from "@/registry/new-york/ui/button" import { Label} from "ui/label" import { Box } from "@/registry/new-york/box" import { cn } from "@/lib/utils" `, config: { tsx: true, tailwind: { baseColor: "neutral", cssVariables: true, }, aliases: { components: "@/components", utils: "@/lib/utils", }, }, }) ).toMatchSnapshot() expect( await transform({ filename: "test.ts", raw: `import * as React from "react" import { Foo } from "bar" import { Button } from "@/registry/new-york/ui/button" import { Label} from "ui/label" import { Box } from "@/registry/new-york/box" import { cn, foo, bar } from "@/lib/utils" import { bar } from "@/lib/utils/bar" `, config: { tsx: true, aliases: { components: "~/src/components", utils: "~/lib", }, }, }) ).toMatchSnapshot() expect( await transform({ filename: "test.ts", raw: `import * as React from "react" import { Foo } from "bar" import { Button } from "@/registry/new-york/ui/button" import { Label} from "ui/label" import { Box } from "@/registry/new-york/box" import { cn } from "@/lib/utils" import { bar } from "@/lib/utils/bar" `, config: { tsx: true, aliases: { components: "~/src/components", utils: "~/src/utils", }, }, }) ).toMatchSnapshot() expect( await transform({ filename: "test.ts", raw: `import * as React from "react" import { Foo } from "bar" import { Button } from "@/registry/new-york/ui/button" import { Label} from "ui/label" import { Box } from "@/registry/new-york/box" import { cn } from "@/lib/utils" import { bar } from "@/lib/utils/bar" `, config: { tsx: true, aliases: { components: "~/src/components", utils: "~/src/utils", ui: "~/src/components", }, }, }) ).toMatchSnapshot() expect( await transform({ filename: "test.ts", raw: `import * as React from "react" import { Foo } from "bar" import { Button } from "@/registry/new-york/ui/button" import { Label} from "ui/label" import { Box } from "@/registry/new-york/box" import { cn } from "@/lib/utils" import { bar } from "@/lib/utils/bar" `, config: { tsx: true, aliases: { components: "~/src/components", utils: "~/src/utils", ui: "~/src/ui", }, }, }) ).toMatchSnapshot() expect( await transform({ filename: "test.ts", raw: `import * as React from "react" import { Foo } from "bar" import { Button } from "@/components/ui/button" import { Label} from "ui/label" import { Box } from "@/registry/new-york/box" import { cn } from "@/lib/utils" `, config: { tsx: true, tailwind: { baseColor: "neutral", cssVariables: true, }, aliases: { components: "@custom-alias/components", utils: "@custom-alias/lib/utils", }, }, }) ).toMatchSnapshot() }) test("transform import with configured package-import aliases", async () => { expect( await transform({ filename: "test.ts", raw: `import { Button } from "#app/components/ui/button" import { cn } from "#app/lib/utils" `, config: { tsx: true, aliases: { components: "#app/components", ui: "#app/components/ui", lib: "#app/lib", utils: "#app/lib/utils", }, }, }) ).toMatchInlineSnapshot(` "import { Button } from "#app/components/ui/button" import { cn } from "#app/lib/utils" " `) }) test("transform import keeps exact #utils aliases", async () => { expect( await transform({ filename: "test.ts", raw: `import { cn } from "@/lib/utils" `, config: { tsx: true, aliases: { components: "#components", utils: "#utils", ui: "#components/ui", lib: "#lib", hooks: "#hooks", }, }, }) ).toMatchInlineSnapshot(` "import { cn } from "#utils" " `) }) test("transform import keeps #lib/utils aliases", async () => { expect( await transform({ filename: "test.ts", raw: `import { cn } from "@/lib/utils" `, config: { tsx: true, aliases: { components: "#components", utils: "#lib/utils", ui: "#components/ui", lib: "#lib", hooks: "#hooks", }, }, }) ).toMatchInlineSnapshot(` "import { cn } from "#lib/utils" " `) }) test("transform import for monorepo", async () => { expect( await transform({ filename: "test.ts", raw: `import * as React from "react" import { Foo } from "bar" import { Button } from "@/registry/new-york/ui/button" import { Label} from "ui/label" import { Box } from "@/registry/new-york/box" import { cn } from "@/lib/utils" `, config: { tsx: true, tailwind: { baseColor: "neutral", cssVariables: true, }, aliases: { components: "@workspace/ui/components", utils: "@workspace/ui/lib/utils", }, }, }) ).toMatchSnapshot() expect( await transform({ filename: "test.ts", raw: `import * as React from "react" import { Foo } from "bar" import { Button } from "@/registry/new-york/ui/button" import { Label} from "ui/label" import { Box } from "@/registry/new-york/box" import { cn } from "@/lib/utils" `, config: { tsx: true, tailwind: { baseColor: "neutral", cssVariables: true, }, aliases: { components: "@repo/ui/components", utils: "@repo/ui/lib/utils", }, }, }) ).toMatchSnapshot() }) test("transform package import aliases and #registry placeholders", async () => { expect( await transform({ filename: "test.ts", raw: `import { Button } from "#registry/new-york/ui/button" import { Card } from "#/registry/new-york/ui/card" import * as RegistryRoot from "#registry" import * as RegistryRootCompat from "#/registry" import { cn } from "#utils" import { helper } from "#lib/helpers" import { useThing } from "#hooks/use-thing" `, config: { tsx: true, aliases: { components: "#components", ui: "#components/ui", utils: "#utils", lib: "#lib", hooks: "#hooks", }, }, }) ).toContain(`import { Button } from "#components/ui/button"`) expect( await transform({ filename: "test.ts", raw: `import { Button } from "#registry/new-york/ui/button" import { Card } from "#/registry/new-york/ui/card" import * as RegistryRoot from "#registry" import * as RegistryRootCompat from "#/registry" import { cn } from "#utils" import { helper } from "#lib/helpers" import { useThing } from "#hooks/use-thing" `, config: { tsx: true, aliases: { components: "#components", ui: "#components/ui", utils: "#utils", lib: "#lib", hooks: "#hooks", }, }, }) ).toContain(`import { Card } from "#components/ui/card"`) expect( await transform({ filename: "test.ts", raw: `import { Button } from "#registry/new-york/ui/button" import { Card } from "#/registry/new-york/ui/card" import * as RegistryRoot from "#registry" import * as RegistryRootCompat from "#/registry" import { cn } from "#utils" import { helper } from "#lib/helpers" import { useThing } from "#hooks/use-thing" `, config: { tsx: true, aliases: { components: "#components", ui: "#components/ui", utils: "#utils", lib: "#lib", hooks: "#hooks", }, }, }) ).toContain(`import { cn } from "#utils"`) expect( await transform({ filename: "test.ts", raw: `import * as RegistryRoot from "#registry" import * as RegistryRootCompat from "#/registry" `, config: { tsx: true, aliases: { components: "#components", ui: "#components/ui", utils: "#utils", lib: "#lib", hooks: "#hooks", }, }, }) ).toContain(`import * as RegistryRoot from "#components"`) expect( await transform({ filename: "test.ts", raw: `import * as RegistryRoot from "#registry" import * as RegistryRootCompat from "#/registry" `, config: { tsx: true, aliases: { components: "#components", ui: "#components/ui", utils: "#utils", lib: "#lib", hooks: "#hooks", }, }, }) ).toContain(`import * as RegistryRootCompat from "#components"`) }) test("prefers explicit workspace utils alias over local lib alias", async () => { expect( await transform({ filename: "test.tsx", raw: `import { cn } from "@/lib/utils" import { helper } from "@/lib/helper" `, config: { tsx: true, aliases: { components: "#components", lib: "#lib", hooks: "#hooks", ui: "@workspace/ui/components", utils: "@workspace/ui/lib/utils", }, }, }) ).toContain(`import { cn } from "@workspace/ui/lib/utils"`) }) test("prefers explicit utils alias for registry lib utils imports", async () => { expect( await transform({ filename: "login-form.tsx", raw: `import { cn } from "@/registry/new-york-v4/lib/utils" import { Button } from "@/registry/new-york-v4/ui/button" `, config: { tsx: true, aliases: { components: "#components", lib: "#lib", hooks: "#hooks", ui: "@workspace/ui/components", utils: "@workspace/ui/lib/utils", }, }, }) ).toContain(`import { cn } from "@workspace/ui/lib/utils"`) }) test("transform async/dynamic imports", async () => { expect( await transform({ filename: "test.ts", raw: `import * as React from "react" import { Button } from "@/registry/new-york/ui/button" async function loadComponent() { const { cn } = await import("@/lib/utils") const module = await import("@/registry/new-york/ui/card") return module } function lazyLoad() { return import("@/registry/new-york/ui/dialog").then(module => module) } `, config: { tsx: true, aliases: { components: "@/components", utils: "@/lib/utils", }, }, }) ).toMatchSnapshot() expect( await transform({ filename: "test.ts", raw: `import { Button } from "@/registry/new-york/ui/button" async function loadUtils() { const utils = await import("@/lib/utils") const { cn } = await import("@/lib/utils") return { utils, cn } } const dialogPromise = import("@/registry/new-york/ui/dialog") const cardModule = import("@/registry/new-york/ui/card") `, config: { tsx: true, aliases: { components: "~/components", utils: "~/lib/utils", }, }, }) ).toMatchSnapshot() }) test("transform dynamic imports with cn utility", async () => { expect( await transform({ filename: "test.ts", raw: `async function loadCn() { const { cn } = await import("@/lib/utils") return cn } async function loadMultiple() { const utils1 = await import("@/lib/utils") const { cn, twMerge } = await import("@/lib/utils") const other = await import("@/lib/other") } `, config: { tsx: true, aliases: { components: "@/components", utils: "@/lib/utils", }, }, }) ).toMatchSnapshot() expect( await transform({ filename: "test.ts", raw: `async function loadWorkspaceCn() { const { cn } = await import("@/lib/utils") return cn } `, config: { tsx: true, aliases: { components: "@workspace/ui/components", utils: "@workspace/ui/lib/utils", }, }, }) ).toMatchSnapshot() }) test("does not rewrite foreign scoped package imports when project uses # aliases", async () => { const result = await transform({ filename: "test.tsx", raw: `import { Analytics } from "@vercel/analytics/react" import posthog from "posthog-js" import { motion } from "motion/react" import { Button } from "@/registry/new-york-v4/ui/button" `, config: { tsx: true, aliases: { components: "#components", ui: "#components/ui", utils: "#utils", lib: "#lib", hooks: "#hooks", }, }, }) expect(result).toContain( `import { Analytics } from "@vercel/analytics/react"` ) expect(result).toContain(`import posthog from "posthog-js"`) expect(result).toContain(`import { motion } from "motion/react"`) expect(result).toContain(`import { Button } from "#components/ui/button"`) }) test("does not rewrite workspace package exports when project uses # aliases", async () => { const result = await transform({ filename: "test.tsx", raw: `import { Card } from "@workspace/ui/components/card" import { useTheme } from "@workspace/ui/hooks/use-theme" import { Button } from "@/registry/new-york-v4/ui/button" `, config: { tsx: true, aliases: { components: "#components", ui: "@workspace/ui/components", utils: "@workspace/ui/lib/utils", lib: "#lib", hooks: "#hooks", }, }, }) expect(result).toContain( `import { Card } from "@workspace/ui/components/card"` ) expect(result).toContain( `import { useTheme } from "@workspace/ui/hooks/use-theme"` ) expect(result).toContain( `import { Button } from "@workspace/ui/components/button"` ) }) test("transform re-exports with dynamic imports", async () => { expect( await transform({ filename: "test.ts", raw: `export { cn } from "@/lib/utils" export { Button } from "@/registry/new-york/ui/button" async function load() { const module = await import("@/registry/new-york/ui/card") return module } `, config: { tsx: true, aliases: { components: "@/components", utils: "@/lib/utils", }, }, }) ).toMatchSnapshot() })