This commit is contained in:
shadcn
2026-03-02 14:22:31 +04:00
parent a59144d8e1
commit 57f9d875be
23 changed files with 62 additions and 42 deletions

View File

@@ -5,4 +5,3 @@ build
.contentlayer
**/fixtures
deprecated
packages

View File

@@ -31,8 +31,8 @@
"lint:fix": "turbo run lint:fix",
"preview": "turbo run preview",
"typecheck": "turbo run typecheck",
"format:write": "turbo run format:write --filter='!./packages/*'",
"format:check": "turbo run format:check --filter='!./packages/*'",
"format:write": "turbo run format:write",
"format:check": "turbo run format:check",
"sync:templates": "./scripts/sync-templates.sh \"templates/*\"",
"check": "turbo lint typecheck format:check",
"release": "changeset version",

View File

@@ -25,9 +25,9 @@ import { createProject } from "@/src/utils/create-project"
import { loadEnvFiles } from "@/src/utils/env-loader"
import * as ERRORS from "@/src/utils/errors"
import {
FILE_BACKUP_SUFFIX,
createFileBackup,
deleteFileBackup,
FILE_BACKUP_SUFFIX,
restoreFileBackup,
} from "@/src/utils/file-helper"
import {

View File

@@ -4,7 +4,7 @@ import { preFlightRegistryBuild } from "@/src/preflights/preflight-registry"
import { recursivelyResolveFileImports } from "@/src/registry/utils"
import { configSchema, registryItemSchema, registrySchema } from "@/src/schema"
import * as ERRORS from "@/src/utils/errors"
import { ProjectInfo, getProjectInfo } from "@/src/utils/get-project-info"
import { getProjectInfo, ProjectInfo } from "@/src/utils/get-project-info"
import { handleError } from "@/src/utils/handle-error"
import { highlighter } from "@/src/utils/highlighter"
import { logger } from "@/src/utils/logger"

View File

@@ -186,8 +186,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
For example: \`${await npxShadcn(
"view @shadcn"
)}\` or \`${await npxShadcn(
"view @shadcn @acme"
)}\` to view multiple registries.
"view @shadcn @acme"
)}\` to view multiple registries.
`,
},
],

View File

@@ -1,7 +1,13 @@
import { describe, expect, it } from "vitest"
import {
decodePreset,
DEFAULT_PRESET_CONFIG,
encodePreset,
fromBase62,
generateRandomPreset,
isPresetCode,
isValidPreset,
PRESET_BASE_COLORS,
PRESET_FONTS,
PRESET_ICON_LIBRARIES,
@@ -10,12 +16,6 @@ import {
PRESET_RADII,
PRESET_STYLES,
PRESET_THEMES,
decodePreset,
encodePreset,
fromBase62,
generateRandomPreset,
isPresetCode,
isValidPreset,
toBase62,
type PresetConfig,
} from "./preset"

View File

@@ -14,7 +14,7 @@ import {
RegistryParseError,
RegistryUnauthorizedError,
} from "@/src/registry/errors"
import { HttpResponse, http } from "msw"
import { http, HttpResponse } from "msw"
import { setupServer } from "msw/node"
import {
afterAll,

View File

@@ -1,6 +1,6 @@
import { BUILTIN_REGISTRIES, FALLBACK_STYLE } from "@/src/registry/constants"
import { configSchema } from "@/src/schema"
import { Config, DeepPartial, createConfig } from "@/src/utils/get-config"
import { Config, createConfig, DeepPartial } from "@/src/utils/get-config"
import deepmerge from "deepmerge"
function resolveStyleFromConfig(config: DeepPartial<Config>) {

View File

@@ -76,7 +76,10 @@ export class RegistryError extends Error {
}
export class RegistryNotFoundError extends RegistryError {
constructor(public readonly url: string, cause?: unknown) {
constructor(
public readonly url: string,
cause?: unknown
) {
const message = `The item at ${url} was not found. It may not exist at the registry.`
super(message, {
@@ -92,7 +95,10 @@ export class RegistryNotFoundError extends RegistryError {
}
export class RegistryGoneError extends RegistryError {
constructor(public readonly url: string, cause?: unknown) {
constructor(
public readonly url: string,
cause?: unknown
) {
const message = `The item at ${url} is no longer available. It may have been removed or expired.`
super(message, {
@@ -108,7 +114,10 @@ export class RegistryGoneError extends RegistryError {
}
export class RegistryUnauthorizedError extends RegistryError {
constructor(public readonly url: string, cause?: unknown) {
constructor(
public readonly url: string,
cause?: unknown
) {
const message = `You are not authorized to access the item at ${url}. If this is a remote registry, you may need to authenticate.`
super(message, {
@@ -124,7 +133,10 @@ export class RegistryUnauthorizedError extends RegistryError {
}
export class RegistryForbiddenError extends RegistryError {
constructor(public readonly url: string, cause?: unknown) {
constructor(
public readonly url: string,
cause?: unknown
) {
const message = `You are not authorized to access the item at ${url}. If this is a remote registry, you may need to authenticate.`
super(message, {
@@ -199,7 +211,10 @@ export class RegistryNotConfiguredError extends RegistryError {
}
export class RegistryLocalFileError extends RegistryError {
constructor(public readonly filePath: string, cause?: unknown) {
constructor(
public readonly filePath: string,
cause?: unknown
) {
super(`Failed to read local registry file: ${filePath}`, {
code: RegistryErrorCode.LOCAL_FILE_ERROR,
cause,
@@ -213,7 +228,10 @@ export class RegistryLocalFileError extends RegistryError {
export class RegistryParseError extends RegistryError {
public readonly parseError: unknown
constructor(public readonly item: string, parseError: unknown) {
constructor(
public readonly item: string,
parseError: unknown
) {
let message = `Failed to parse registry item: ${item}`
if (parseError instanceof z.ZodError) {
@@ -283,7 +301,10 @@ export class ConfigMissingError extends RegistryError {
}
export class ConfigParseError extends RegistryError {
constructor(public readonly cwd: string, parseError: unknown) {
constructor(
public readonly cwd: string,
parseError: unknown
) {
let message = `Invalid components.json configuration in ${cwd}.`
if (parseError instanceof z.ZodError) {

View File

@@ -6,7 +6,7 @@ import {
RegistryNotFoundError,
RegistryUnauthorizedError,
} from "@/src/registry/errors"
import { HttpResponse, http } from "msw"
import { http, HttpResponse } from "msw"
import { setupServer } from "msw/node"
import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest"

View File

@@ -2,7 +2,7 @@
import { promises as fs } from "fs"
import { tmpdir } from "os"
import path from "path"
import { HttpResponse, http } from "msw"
import { http, HttpResponse } from "msw"
import { setupServer } from "msw/node"
import {
afterAll,

View File

@@ -80,7 +80,7 @@ function searchItems<
description?: string
addCommandArgument?: string
[key: string]: any
} = SearchableItem
} = SearchableItem,
>(
items: T[],
options: {

View File

@@ -443,7 +443,7 @@ describe("deduplicateFilesByTarget", () => {
ui: "/test/project/components/ui",
},
...overrides,
} as Config)
}) as Config
test("should deduplicate files with same resolved path", async () => {
const config = createMockConfig()

View File

@@ -7,7 +7,7 @@ import {
registryItemSchema,
} from "@/src/schema"
import { Config } from "@/src/utils/get-config"
import { ProjectInfo, getProjectInfo } from "@/src/utils/get-project-info"
import { getProjectInfo, ProjectInfo } from "@/src/utils/get-project-info"
import { resolveImport } from "@/src/utils/resolve-import"
import {
findCommonRoot,

View File

@@ -138,8 +138,8 @@ async function addProjectComponents(
// Write CSS last so the file watcher triggers a rebuild
// after all component files and dependencies are in place.
const overwriteCssVars = tree.cssVars
? options.overwriteCssVars ??
(await shouldOverwriteCssVars(components, config))
? (options.overwriteCssVars ??
(await shouldOverwriteCssVars(components, config)))
: undefined
await updateCss(tree.css, config, {
silent: options.silent,
@@ -200,9 +200,8 @@ async function addWorkspaceComponents(
// Process global updates for the main target.
// These should typically go to the UI package in a workspace.
const mainTargetConfig = workspaceConfig.ui
const tailwindVersion = await getProjectTailwindVersionFromConfig(
mainTargetConfig
)
const tailwindVersion =
await getProjectTailwindVersionFromConfig(mainTargetConfig)
const workspaceRoot = findCommonRoot(
config.resolvedPaths.cwd,
mainTargetConfig.resolvedPaths.ui
@@ -317,8 +316,8 @@ async function addWorkspaceComponents(
// 6. Write CSS last so the file watcher triggers a rebuild
// after all component files and dependencies are in place.
const overwriteCssVars = tree.cssVars
? options.overwriteCssVars ??
(await shouldOverwriteCssVars(components, config))
? (options.overwriteCssVars ??
(await shouldOverwriteCssVars(components, config)))
: undefined
await updateCss(tree.css, mainTargetConfig, {
silent: true,

View File

@@ -299,8 +299,8 @@ function formatFilesSection(result: DryRunResult, lines: string[]) {
file.action === "create"
? green
: file.action === "overwrite"
? yellow
: dim
? yellow
: dim
const pathStr = file.action === "skip" ? dim(file.path) : file.path

View File

@@ -2,7 +2,7 @@ import { promises as fsPromises } from "fs"
import path from "path"
import { getShadcnRegistryIndex } from "@/src/registry/api"
import { rawConfigSchema } from "@/src/schema"
import { FRAMEWORKS, Framework } from "@/src/utils/frameworks"
import { Framework, FRAMEWORKS } from "@/src/utils/frameworks"
import { Config, getConfig, resolveConfigPaths } from "@/src/utils/get-config"
import { getPackageInfo } from "@/src/utils/get-package-info"
import fg from "fast-glob"

View File

@@ -1,7 +1,7 @@
import { Transformer } from "@/src/utils/transformers"
import {
NoSubstitutionTemplateLiteral,
Node,
NoSubstitutionTemplateLiteral,
Project,
ScriptKind,
SourceFile,

View File

@@ -1,6 +1,6 @@
import { type Transformer } from "@/src/utils/transformers"
import { transformFromAstSync } from "@babel/core"
import { ParserOptions, parse } from "@babel/parser"
import { parse, ParserOptions } from "@babel/parser"
// @ts-ignore
import transformTypescript from "@babel/plugin-transform-typescript"
import * as recast from "recast"

View File

@@ -2,8 +2,8 @@ import { Transformer } from "@/src/utils/transformers"
import { SyntaxKind } from "ts-morph"
import {
TailwindVersion,
getProjectTailwindVersionFromConfig,
TailwindVersion,
} from "../get-project-info"
import { splitClassName } from "./transform-css-vars"

View File

@@ -12,7 +12,7 @@ import {
parseEnvContent,
} from "@/src/utils/env-helpers"
import { Config } from "@/src/utils/get-config"
import { ProjectInfo, getProjectInfo } from "@/src/utils/get-project-info"
import { getProjectInfo, ProjectInfo } from "@/src/utils/get-project-info"
import { highlighter } from "@/src/utils/highlighter"
import { logger } from "@/src/utils/logger"
import { resolveImport } from "@/src/utils/resolve-import"

View File

@@ -2,7 +2,7 @@ import { existsSync, promises as fs } from "fs"
import path from "path"
import { RegistryFontItem, registryResolvedItemsTreeSchema } from "@/src/schema"
import { Config } from "@/src/utils/get-config"
import { ProjectInfo, getProjectInfo } from "@/src/utils/get-project-info"
import { getProjectInfo, ProjectInfo } from "@/src/utils/get-project-info"
import { spinner } from "@/src/utils/spinner"
import {
CallExpression,

View File

@@ -0,0 +1 @@
fixtures/**