mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-06-28 15:14:12 +00:00
fix
This commit is contained in:
@@ -21,6 +21,7 @@ import {
|
||||
templates,
|
||||
} from "@/src/templates/index"
|
||||
import { addComponents } from "@/src/utils/add-components"
|
||||
import { getInitAliasDefaults } from "@/src/utils/alias"
|
||||
import { createProject } from "@/src/utils/create-project"
|
||||
import { loadEnvFiles } from "@/src/utils/env-loader"
|
||||
import * as ERRORS from "@/src/utils/errors"
|
||||
@@ -905,63 +906,6 @@ async function promptForConfig(defaultConfig: Config | null = null) {
|
||||
})
|
||||
}
|
||||
|
||||
export function getInitAliasDefaults(
|
||||
componentsAlias: string,
|
||||
existingAliases?: Config["aliases"]
|
||||
) {
|
||||
const derivedLib =
|
||||
existingAliases?.lib ?? deriveAliasFromComponents(componentsAlias, "lib")
|
||||
|
||||
return {
|
||||
ui: existingAliases?.ui ?? deriveAliasFromComponents(componentsAlias, "ui"),
|
||||
lib: derivedLib,
|
||||
hooks:
|
||||
existingAliases?.hooks ??
|
||||
deriveAliasFromComponents(componentsAlias, "hooks"),
|
||||
utils:
|
||||
existingAliases?.utils ??
|
||||
deriveAliasFromComponents(componentsAlias, "utils", derivedLib),
|
||||
}
|
||||
}
|
||||
|
||||
function deriveAliasFromComponents(
|
||||
componentsAlias: string,
|
||||
kind: "ui" | "lib" | "hooks" | "utils",
|
||||
libAlias?: string
|
||||
) {
|
||||
const alias = componentsAlias || DEFAULT_COMPONENTS
|
||||
|
||||
if (kind === "ui") {
|
||||
return `${alias}/ui`
|
||||
}
|
||||
|
||||
if (kind === "utils") {
|
||||
const resolvedLib = libAlias || replaceComponentsAliasTail(alias, "lib")
|
||||
return resolvedLib ? `${resolvedLib}/utils` : DEFAULT_UTILS
|
||||
}
|
||||
|
||||
return replaceComponentsAliasTail(alias, kind)
|
||||
}
|
||||
|
||||
function replaceComponentsAliasTail(
|
||||
alias: string,
|
||||
kind: "lib" | "hooks"
|
||||
) {
|
||||
if (alias === "components") {
|
||||
return kind
|
||||
}
|
||||
|
||||
if (alias.endsWith("/components")) {
|
||||
return `${alias.slice(0, -"/components".length)}/${kind}`
|
||||
}
|
||||
|
||||
if (alias.endsWith("components") && !alias.includes("/")) {
|
||||
return `${alias.slice(0, -"components".length)}${kind}`
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
export function shouldRunTemplatePostInit(
|
||||
template:
|
||||
| { postInit?: (options: { projectPath: string }) => Promise<void> }
|
||||
|
||||
78
packages/shadcn/src/utils/alias.test.ts
Normal file
78
packages/shadcn/src/utils/alias.test.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { describe, expect, test } from "vitest"
|
||||
|
||||
import {
|
||||
deriveAliasFromComponents,
|
||||
getInitAliasDefaults,
|
||||
} from "@/src/utils/alias"
|
||||
|
||||
describe("deriveAliasFromComponents", () => {
|
||||
test("derives ui aliases from components", () => {
|
||||
expect(deriveAliasFromComponents("@/components", "ui")).toBe(
|
||||
"@/components/ui"
|
||||
)
|
||||
})
|
||||
|
||||
test("derives utils aliases from lib aliases", () => {
|
||||
expect(deriveAliasFromComponents("#components", "utils")).toBe("#lib/utils")
|
||||
expect(
|
||||
deriveAliasFromComponents("#custom/components", "utils", "#custom/lib")
|
||||
).toBe("#custom/lib/utils")
|
||||
})
|
||||
|
||||
test("derives sibling lib and hooks aliases from components", () => {
|
||||
expect(deriveAliasFromComponents("@/components", "lib")).toBe("@/lib")
|
||||
expect(deriveAliasFromComponents("#custom/components", "hooks")).toBe(
|
||||
"#custom/hooks"
|
||||
)
|
||||
})
|
||||
|
||||
test("returns an empty string when components alias has no sibling base", () => {
|
||||
expect(deriveAliasFromComponents("#custom/ui", "lib")).toBe("")
|
||||
})
|
||||
})
|
||||
|
||||
describe("getInitAliasDefaults", () => {
|
||||
test("derives standard aliases from components", () => {
|
||||
expect(getInitAliasDefaults("@/components")).toEqual({
|
||||
ui: "@/components/ui",
|
||||
lib: "@/lib",
|
||||
hooks: "@/hooks",
|
||||
utils: "@/lib/utils",
|
||||
})
|
||||
})
|
||||
|
||||
test("derives package import aliases from #components", () => {
|
||||
expect(getInitAliasDefaults("#components")).toEqual({
|
||||
ui: "#components/ui",
|
||||
lib: "#lib",
|
||||
hooks: "#hooks",
|
||||
utils: "#lib/utils",
|
||||
})
|
||||
})
|
||||
|
||||
test("derives sibling aliases for nested custom aliases", () => {
|
||||
expect(getInitAliasDefaults("#custom/components")).toEqual({
|
||||
ui: "#custom/components/ui",
|
||||
lib: "#custom/lib",
|
||||
hooks: "#custom/hooks",
|
||||
utils: "#custom/lib/utils",
|
||||
})
|
||||
})
|
||||
|
||||
test("preserves existing aliases when components alias is unchanged", () => {
|
||||
expect(
|
||||
getInitAliasDefaults("#components", {
|
||||
components: "#components",
|
||||
ui: "#components/ui",
|
||||
lib: "#lib",
|
||||
hooks: "#hooks",
|
||||
utils: "#lib/utils",
|
||||
})
|
||||
).toEqual({
|
||||
ui: "#components/ui",
|
||||
lib: "#lib",
|
||||
hooks: "#hooks",
|
||||
utils: "#lib/utils",
|
||||
})
|
||||
})
|
||||
})
|
||||
65
packages/shadcn/src/utils/alias.ts
Normal file
65
packages/shadcn/src/utils/alias.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import type { Config } from "@/src/utils/get-config"
|
||||
import { DEFAULT_COMPONENTS, DEFAULT_UTILS } from "@/src/utils/get-config"
|
||||
|
||||
export function getInitAliasDefaults(
|
||||
componentsAlias: string,
|
||||
existingAliases?: Config["aliases"]
|
||||
) {
|
||||
// `lib` is the anchor for deriving `utils`, so reuse the existing value first
|
||||
// when init is re-running against the same components alias.
|
||||
const derivedLib =
|
||||
existingAliases?.lib ?? deriveAliasFromComponents(componentsAlias, "lib")
|
||||
|
||||
return {
|
||||
ui: existingAliases?.ui ?? deriveAliasFromComponents(componentsAlias, "ui"),
|
||||
lib: derivedLib,
|
||||
hooks:
|
||||
existingAliases?.hooks ??
|
||||
deriveAliasFromComponents(componentsAlias, "hooks"),
|
||||
utils:
|
||||
existingAliases?.utils ??
|
||||
deriveAliasFromComponents(componentsAlias, "utils", derivedLib),
|
||||
}
|
||||
}
|
||||
|
||||
export function deriveAliasFromComponents(
|
||||
componentsAlias: string,
|
||||
kind: "ui" | "lib" | "hooks" | "utils",
|
||||
libAlias?: string
|
||||
) {
|
||||
const alias = componentsAlias || DEFAULT_COMPONENTS
|
||||
|
||||
if (kind === "ui") {
|
||||
return `${alias}/ui`
|
||||
}
|
||||
|
||||
if (kind === "utils") {
|
||||
// `utils` follows `lib`, not `components`, so derive or reuse the sibling
|
||||
// lib alias before appending `/utils`.
|
||||
const resolvedLib = libAlias || replaceComponentsAliasTail(alias, "lib")
|
||||
return resolvedLib ? `${resolvedLib}/utils` : DEFAULT_UTILS
|
||||
}
|
||||
|
||||
return replaceComponentsAliasTail(alias, kind)
|
||||
}
|
||||
|
||||
function replaceComponentsAliasTail(
|
||||
alias: string,
|
||||
kind: "lib" | "hooks"
|
||||
) {
|
||||
// Handles the common `@/components` and `#custom/components` forms by
|
||||
// swapping the trailing `components` segment for a sibling alias root.
|
||||
if (alias === "components") {
|
||||
return kind
|
||||
}
|
||||
|
||||
if (alias.endsWith("/components")) {
|
||||
return `${alias.slice(0, -"/components".length)}/${kind}`
|
||||
}
|
||||
|
||||
if (alias.endsWith("components") && !alias.includes("/")) {
|
||||
return `${alias.slice(0, -"components".length)}${kind}`
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
@@ -1,55 +1,6 @@
|
||||
import { describe, expect, test } from "vitest"
|
||||
|
||||
import {
|
||||
getInitAliasDefaults,
|
||||
shouldRunTemplatePostInit,
|
||||
} from "../../src/commands/init"
|
||||
|
||||
describe("getInitAliasDefaults", () => {
|
||||
test("derives standard aliases from components", () => {
|
||||
expect(getInitAliasDefaults("@/components")).toEqual({
|
||||
ui: "@/components/ui",
|
||||
lib: "@/lib",
|
||||
hooks: "@/hooks",
|
||||
utils: "@/lib/utils",
|
||||
})
|
||||
})
|
||||
|
||||
test("derives package import aliases from #components", () => {
|
||||
expect(getInitAliasDefaults("#components")).toEqual({
|
||||
ui: "#components/ui",
|
||||
lib: "#lib",
|
||||
hooks: "#hooks",
|
||||
utils: "#lib/utils",
|
||||
})
|
||||
})
|
||||
|
||||
test("derives sibling aliases for nested custom aliases", () => {
|
||||
expect(getInitAliasDefaults("#custom/components")).toEqual({
|
||||
ui: "#custom/components/ui",
|
||||
lib: "#custom/lib",
|
||||
hooks: "#custom/hooks",
|
||||
utils: "#custom/lib/utils",
|
||||
})
|
||||
})
|
||||
|
||||
test("preserves existing aliases when components alias is unchanged", () => {
|
||||
expect(
|
||||
getInitAliasDefaults("#components", {
|
||||
components: "#components",
|
||||
ui: "#components/ui",
|
||||
lib: "#lib",
|
||||
hooks: "#hooks",
|
||||
utils: "#lib/utils",
|
||||
})
|
||||
).toEqual({
|
||||
ui: "#components/ui",
|
||||
lib: "#lib",
|
||||
hooks: "#hooks",
|
||||
utils: "#lib/utils",
|
||||
})
|
||||
})
|
||||
})
|
||||
import { shouldRunTemplatePostInit } from "../../src/commands/init"
|
||||
|
||||
describe("shouldRunTemplatePostInit", () => {
|
||||
test("does not run post-init for existing projects with an explicit template", () => {
|
||||
|
||||
Reference in New Issue
Block a user