215 lines
6.3 KiB
TypeScript
215 lines
6.3 KiB
TypeScript
import { tmpdir } from "os"
|
|
import path from "path"
|
|
import fs from "fs-extra"
|
|
import { describe, expect, it } from "vitest"
|
|
|
|
import { addRegistriesToConfig, parseRegistryArg } from "./add"
|
|
|
|
describe("parseRegistryArg", () => {
|
|
it("should parse namespace without URL", () => {
|
|
expect(parseRegistryArg("@magicui")).toEqual({ namespace: "@magicui" })
|
|
expect(parseRegistryArg("@aceternity")).toEqual({
|
|
namespace: "@aceternity",
|
|
})
|
|
})
|
|
|
|
it("should parse namespace with URL", () => {
|
|
expect(
|
|
parseRegistryArg("@mycompany=https://example.com/r/{name}.json")
|
|
).toEqual({
|
|
namespace: "@mycompany",
|
|
url: "https://example.com/r/{name}.json",
|
|
})
|
|
})
|
|
|
|
it("should handle URL with query params containing =", () => {
|
|
expect(
|
|
parseRegistryArg("@foo=https://example.com/r/{name}.json?token=abc")
|
|
).toEqual({
|
|
namespace: "@foo",
|
|
url: "https://example.com/r/{name}.json?token=abc",
|
|
})
|
|
})
|
|
|
|
it("should handle URL with multiple = in query params", () => {
|
|
expect(
|
|
parseRegistryArg(
|
|
"@bar=https://example.com/r/{name}.json?token=abc&key=xyz"
|
|
)
|
|
).toEqual({
|
|
namespace: "@bar",
|
|
url: "https://example.com/r/{name}.json?token=abc&key=xyz",
|
|
})
|
|
})
|
|
|
|
it("should handle URL with port number", () => {
|
|
expect(
|
|
parseRegistryArg("@local=http://localhost:8080/r/{name}.json")
|
|
).toEqual({
|
|
namespace: "@local",
|
|
url: "http://localhost:8080/r/{name}.json",
|
|
})
|
|
})
|
|
|
|
it("should throw for namespace without @", () => {
|
|
expect(() => parseRegistryArg("foo")).toThrow("must start with @")
|
|
expect(() => parseRegistryArg("magicui")).toThrow("must start with @")
|
|
expect(() =>
|
|
parseRegistryArg("mycompany=https://example.com/r/{name}.json")
|
|
).toThrow("must start with @")
|
|
})
|
|
})
|
|
|
|
describe("addRegistriesToConfig", () => {
|
|
it("should write registries to components.json when it exists", async () => {
|
|
const tempDir = await fs.mkdtemp(path.join(tmpdir(), "shadcn-test-"))
|
|
const componentsJsonFile = path.join(tempDir, "components.json")
|
|
|
|
await fs.writeJson(componentsJsonFile, { style: "new-york" })
|
|
|
|
try {
|
|
await addRegistriesToConfig(
|
|
["@acme=https://acme.com/r/{name}.json"],
|
|
tempDir,
|
|
{ silent: true }
|
|
)
|
|
|
|
const config = await fs.readJson(componentsJsonFile)
|
|
expect(config).toEqual({
|
|
style: "new-york",
|
|
registries: {
|
|
"@acme": "https://acme.com/r/{name}.json",
|
|
},
|
|
})
|
|
} finally {
|
|
await fs.rm(tempDir, { recursive: true })
|
|
}
|
|
})
|
|
|
|
it("should prefer components.json over package.json when both exist", async () => {
|
|
const tempDir = await fs.mkdtemp(path.join(tmpdir(), "shadcn-test-"))
|
|
const componentsJsonFile = path.join(tempDir, "components.json")
|
|
const packageJsonFile = path.join(tempDir, "package.json")
|
|
|
|
await fs.writeJson(componentsJsonFile, { style: "new-york" })
|
|
await fs.writeJson(packageJsonFile, { name: "test-package" })
|
|
|
|
try {
|
|
await addRegistriesToConfig(
|
|
["@acme=https://acme.com/r/{name}.json"],
|
|
tempDir,
|
|
{ silent: true }
|
|
)
|
|
|
|
const componentsJson = await fs.readJson(componentsJsonFile)
|
|
const packageJson = await fs.readJson(packageJsonFile)
|
|
expect(componentsJson.registries).toEqual({
|
|
"@acme": "https://acme.com/r/{name}.json",
|
|
})
|
|
expect(packageJson.registries).toBeUndefined()
|
|
} finally {
|
|
await fs.rm(tempDir, { recursive: true })
|
|
}
|
|
})
|
|
|
|
it("should write registries to package.json when components.json does not exist", async () => {
|
|
const tempDir = await fs.mkdtemp(path.join(tmpdir(), "shadcn-test-"))
|
|
const packageJsonFile = path.join(tempDir, "package.json")
|
|
|
|
await fs.writeJson(packageJsonFile, {
|
|
name: "test-package",
|
|
version: "1.0.0",
|
|
})
|
|
|
|
try {
|
|
await addRegistriesToConfig(
|
|
["@acme=https://acme.com/r/{name}.json"],
|
|
tempDir,
|
|
{ silent: true }
|
|
)
|
|
|
|
const packageJson = await fs.readJson(packageJsonFile)
|
|
expect(packageJson).toEqual({
|
|
name: "test-package",
|
|
version: "1.0.0",
|
|
registries: {
|
|
"@acme": "https://acme.com/r/{name}.json",
|
|
},
|
|
})
|
|
} finally {
|
|
await fs.rm(tempDir, { recursive: true })
|
|
}
|
|
})
|
|
|
|
it("should preserve existing registries when adding to package.json", async () => {
|
|
const tempDir = await fs.mkdtemp(path.join(tmpdir(), "shadcn-test-"))
|
|
const packageJsonFile = path.join(tempDir, "package.json")
|
|
|
|
await fs.writeJson(packageJsonFile, {
|
|
name: "test-package",
|
|
registries: {
|
|
"@existing": "https://existing.com/r/{name}.json",
|
|
},
|
|
})
|
|
|
|
try {
|
|
await addRegistriesToConfig(
|
|
["@acme=https://acme.com/r/{name}.json"],
|
|
tempDir,
|
|
{ silent: true }
|
|
)
|
|
|
|
const packageJson = await fs.readJson(packageJsonFile)
|
|
expect(packageJson.registries).toEqual({
|
|
"@existing": "https://existing.com/r/{name}.json",
|
|
"@acme": "https://acme.com/r/{name}.json",
|
|
})
|
|
} finally {
|
|
await fs.rm(tempDir, { recursive: true })
|
|
}
|
|
})
|
|
|
|
it("should skip registries already configured in package.json", async () => {
|
|
const tempDir = await fs.mkdtemp(path.join(tmpdir(), "shadcn-test-"))
|
|
const packageJsonFile = path.join(tempDir, "package.json")
|
|
|
|
await fs.writeJson(packageJsonFile, {
|
|
name: "test-package",
|
|
registries: {
|
|
"@acme": "https://existing.com/r/{name}.json",
|
|
},
|
|
})
|
|
|
|
try {
|
|
await addRegistriesToConfig(
|
|
["@acme=https://new.com/r/{name}.json"],
|
|
tempDir,
|
|
{ silent: true }
|
|
)
|
|
|
|
const packageJson = await fs.readJson(packageJsonFile)
|
|
expect(packageJson.registries).toEqual({
|
|
"@acme": "https://existing.com/r/{name}.json",
|
|
})
|
|
} finally {
|
|
await fs.rm(tempDir, { recursive: true })
|
|
}
|
|
})
|
|
|
|
it("should throw when neither components.json nor package.json exists", async () => {
|
|
const tempDir = await fs.mkdtemp(path.join(tmpdir(), "shadcn-test-"))
|
|
|
|
try {
|
|
await expect(
|
|
addRegistriesToConfig(
|
|
["@acme=https://acme.com/r/{name}.json"],
|
|
tempDir,
|
|
{ silent: true }
|
|
)
|
|
).rejects.toThrow(/No .*components\.json.* or .*package\.json.* found/)
|
|
} finally {
|
|
await fs.rm(tempDir, { recursive: true })
|
|
}
|
|
})
|
|
})
|