From b5e75e465490aa0f0a835325b265a8ed082becf8 Mon Sep 17 00:00:00 2001 From: Hunter Johnston Date: Fri, 16 May 2025 15:06:16 -0400 Subject: [PATCH 1/8] tw4: registry cli docs --- sites/docs/src/content/cli.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/sites/docs/src/content/cli.md b/sites/docs/src/content/cli.md index a3372fd0d4..554d390b8a 100644 --- a/sites/docs/src/content/cli.md +++ b/sites/docs/src/content/cli.md @@ -93,28 +93,28 @@ Options: -h, --help display help for command ``` -## update +## build -Use the `update` command to update components in your project. This will overwrite any modifications you've made to the components, so be sure to commit your changes before running this command. +Use the `build` command to generate the registry JSON files. - + + +This command reads the `registry.json` file and generates the registry JSON files into the `static/r` directory. ### Options ```txt -Usage: shadcn-svelte update [options] [components...] +Usage: shadcn-svelte build [options] [registry] -update components in your project +build components for a shadcn-svelte registry Arguments: - components name of components + registry path to registry.json file (default: ./registry.json) Options: - -c, --cwd the working directory (default: the current directory) - -a, --all update all existing components (default: false) - -y, --yes skip confirmation prompt (default: false) - --proxy fetch components from registry using a proxy - -h, --help display help for command + -c, --cwd the working directory (default: the current directory) + -o, --output destination directory for json files (default: ./static/r) + -h, --help display help for command ``` ## Outgoing Requests From 2a323400bcbf096ba1b0c24796ac03236047d4e9 Mon Sep 17 00:00:00 2001 From: Hunter Johnston Date: Fri, 16 May 2025 15:23:37 -0400 Subject: [PATCH 2/8] registry doc --- packages/cli/src/commands/registry/build.ts | 2 +- .../src/content/registry/registry-json.md | 76 ++++++++++++++++++- 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/commands/registry/build.ts b/packages/cli/src/commands/registry/build.ts index 400c9d59f1..25e1f76634 100644 --- a/packages/cli/src/commands/registry/build.ts +++ b/packages/cli/src/commands/registry/build.ts @@ -25,7 +25,7 @@ type BuildOptions = z.infer; export const build = new Command() .command("build") - .description("build components for a shadcn registry") + .description("build components for a shadcn-svelte registry") .argument("[registry]", "path to registry.json file", "./registry.json") .option("-c, --cwd ", "the working directory", process.cwd()) .option("-o, --output ", "destination directory for json files", "./static/r") diff --git a/sites/docs/src/content/registry/registry-json.md b/sites/docs/src/content/registry/registry-json.md index 87110f8b5d..04659171b5 100644 --- a/sites/docs/src/content/registry/registry-json.md +++ b/sites/docs/src/content/registry/registry-json.md @@ -3,12 +3,16 @@ title: registry.json description: Schema for running your own component registry. --- + + The `registry.json` schema is used to define your custom component registry. ```json title="registry.json" showLineNumbers { "$schema": "https://next.shadcn-svelte.com/schema/registry.json", - "name": "shadcn", + "name": "shadcn-svelte", "homepage": "https://next.shadcn-svelte.com", "items": [ { @@ -85,3 +89,73 @@ The `items` in your registry. Each item must implement the [registry-item schema ``` See the [registry-item schema documentation](/docs/registry/registry-item-json) for more information. + +### aliases + +`aliases` define how your registry's internal import paths will be transformed when users install your components. These should match how you import components within your registry code. + +For example, if your registry's component has: + +```svelte + +``` + +Then your `registry.json` should have matching aliases: + +```json +{ + "aliases": { + "lib": "@/lib", // Matches your internal imports + "ui": "@/lib/registry/ui", // Matches your internal imports + "utils": "@/lib/utils" // Matches your internal imports + } +} +``` + +When users install your component, these paths will be transformed according to their `components.json` configuration. The aliases you define here are the "source" paths that will be replaced. + +Default aliases (if you don't specify any): + +```json +"aliases": { + "lib": "$lib/registry/lib", // For internal library code + "ui": "$lib/registry/ui", // For UI components + "components": "$lib/registry/components", // For component-specific code + "utils": "$lib/utils", // For utility functions + "hooks": "$lib/registry/hooks" // For reactive state and logic (.svelte.js|ts) +} +``` + +### overrideDependencies + +`overrideDependencies` lets you force specific version ranges for dependencies, overriding what `shadcn-svelte build` detects in your `package.json`. + +Common use cases: + +- Using latest pre-release versions: `"overrideDependencies": ["paneforge@next"]` +- Pinning to specific versions: `"overrideDependencies": ["dep@1.5.0"]` + + + +**Warning**: Overriding dependencies can lead to version conflicts if not carefully managed. This option should be used sparingly. + + + +Example transformation: + +```json +// Your registry's package.json +{ + "dependencies": { + "paneforge": "1.0.0-next.1" + } +} + +// With overrideDependencies: ["paneforge@next"] + + +// When the user installs your component, the latest next version will be used instead of 1.0.0-next.1 +``` From 89107eda9c2743558c667220f550f40fb99f37c8 Mon Sep 17 00:00:00 2001 From: Hunter Johnston Date: Fri, 16 May 2025 15:25:34 -0400 Subject: [PATCH 3/8] registry doc --- .../src/content/registry/registry-json.md | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/sites/docs/src/content/registry/registry-json.md b/sites/docs/src/content/registry/registry-json.md index 04659171b5..149bd061ff 100644 --- a/sites/docs/src/content/registry/registry-json.md +++ b/sites/docs/src/content/registry/registry-json.md @@ -105,12 +105,14 @@ For example, if your registry's component has: Then your `registry.json` should have matching aliases: -```json +```json title="registry.json" showLineNumbers { "aliases": { "lib": "@/lib", // Matches your internal imports "ui": "@/lib/registry/ui", // Matches your internal imports - "utils": "@/lib/utils" // Matches your internal imports + "components": "@/lib/registry/components", // Matches your internal imports + "utils": "@/lib/utils", // Matches your internal imports + "hooks": "@/lib/hooks" // Matches your internal imports } } ``` @@ -119,13 +121,15 @@ When users install your component, these paths will be transformed according to Default aliases (if you don't specify any): -```json -"aliases": { - "lib": "$lib/registry/lib", // For internal library code - "ui": "$lib/registry/ui", // For UI components - "components": "$lib/registry/components", // For component-specific code - "utils": "$lib/utils", // For utility functions - "hooks": "$lib/registry/hooks" // For reactive state and logic (.svelte.js|ts) +```json title="registry.json" showLineNumbers +{ + "aliases": { + "lib": "$lib/registry/lib", // For internal library code + "ui": "$lib/registry/ui", // For UI components + "components": "$lib/registry/components", // For component-specific code + "utils": "$lib/utils", // For utility functions + "hooks": "$lib/registry/hooks" // For reactive state and logic (.svelte.js|ts) + } } ``` From db7a409fddea794d2d4883f2cc7202195377e74b Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Fri, 16 May 2025 16:28:13 -0400 Subject: [PATCH 4/8] tweaks --- sites/docs/src/content/cli.md | 2 +- sites/docs/src/content/registry/registry-item-json.md | 6 +++--- sites/docs/src/content/registry/registry-json.md | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sites/docs/src/content/cli.md b/sites/docs/src/content/cli.md index 554d390b8a..339adf9dc5 100644 --- a/sites/docs/src/content/cli.md +++ b/sites/docs/src/content/cli.md @@ -97,7 +97,7 @@ Options: Use the `build` command to generate the registry JSON files. - + This command reads the `registry.json` file and generates the registry JSON files into the `static/r` directory. diff --git a/sites/docs/src/content/registry/registry-item-json.md b/sites/docs/src/content/registry/registry-item-json.md index 2a1d6535d0..7583f78f94 100644 --- a/sites/docs/src/content/registry/registry-item-json.md +++ b/sites/docs/src/content/registry/registry-item-json.md @@ -9,8 +9,8 @@ The `registry-item.json` schema is used to define your custom registry items. { "$schema": "https://next.shadcn-svelte.com/schema/registry-item.json", "name": "hello-world", - "type": "registry:block", "title": "Hello World", + "type": "registry:block", "description": "A simple hello world component.", "files": [ { @@ -44,7 +44,7 @@ The `registry-item.json` schema is used to define your custom registry items. ## Definitions -You can see the JSON Schema for `registry-item.json` [here](https://next.shadcn-svelte.com/schema/registry-item.json). +You can see the JSON Schema for `registry-item.json` [here](/schema/registry-item.json). ### $schema @@ -199,7 +199,7 @@ The `target` property is used to indicate where the file should be placed in a p By default, the `shadcn-svelte` cli will read a project's `components.json` file to determine the target path. For some files, such as routes or config you can specify the target path manually. -TODO: (is this correct?) - Use `~` to refer to the root of the project e.g `~/foo.config.js`. +Use `~` to refer to the root of the project e.g `~/foo.config.js`. ### cssVars diff --git a/sites/docs/src/content/registry/registry-json.md b/sites/docs/src/content/registry/registry-json.md index 149bd061ff..33384da7b7 100644 --- a/sites/docs/src/content/registry/registry-json.md +++ b/sites/docs/src/content/registry/registry-json.md @@ -33,7 +33,7 @@ The `registry.json` schema is used to define your custom component registry. ## Definitions -You can see the JSON Schema for `registry.json` [here](https://next.shadcn-svelte.com/schema/registry.json). +You can see the JSON Schema for `registry.json` [here](/schema/registry.json). ### $schema @@ -67,7 +67,7 @@ The homepage of your registry. This is used for data attributes and other metada ### items -The `items` in your registry. Each item must implement the [registry-item schema specification](https://next.shadcn-svelte.com/schema/registry-item.json). +The `items` in your registry. Each item must implement the [registry-item schema specification](/schema/registry-item.json). ```json title="registry.json" showLineNumbers { @@ -135,7 +135,7 @@ Default aliases (if you don't specify any): ### overrideDependencies -`overrideDependencies` lets you force specific version ranges for dependencies, overriding what `shadcn-svelte build` detects in your `package.json`. +`overrideDependencies` lets you force specific version ranges for dependencies, overriding what `shadcn-svelte registry build` detects in your `package.json`. Common use cases: From 60089e4b101ad1671a01969205f0dde57542ccce Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Fri, 16 May 2025 17:18:49 -0400 Subject: [PATCH 5/8] more --- sites/docs/src/content/cli.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sites/docs/src/content/cli.md b/sites/docs/src/content/cli.md index 339adf9dc5..7f8f0e12f2 100644 --- a/sites/docs/src/content/cli.md +++ b/sites/docs/src/content/cli.md @@ -104,7 +104,7 @@ This command reads the `registry.json` file and generates the registry JSON file ### Options ```txt -Usage: shadcn-svelte build [options] [registry] +Usage: shadcn-svelte registry build [options] [registry] build components for a shadcn-svelte registry @@ -121,7 +121,7 @@ Options: ### Proxy -This enables the use of a proxy when sending out requests to fetch from the `shadcn` registry. If the `HTTP_PROXY` or `http_proxy` environment variables have been set, the request library underneath will respect the proxy settings. +This enables the use of a proxy when sending out requests to fetch from the `shadcn-svelte` registry. If the `HTTP_PROXY` or `http_proxy` environment variables have been set, the request library underneath will respect the proxy settings. ```bash HTTP_PROXY="" npx shadcn-svelte@next init From 04722f45c4362bbf9d8b2152254f71ac68e8f91f Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Fri, 16 May 2025 17:40:29 -0400 Subject: [PATCH 6/8] add descriptions for registry schemas --- packages/registry/src/schemas.ts | 156 +++++++++++++++++++++++-------- 1 file changed, 119 insertions(+), 37 deletions(-) diff --git a/packages/registry/src/schemas.ts b/packages/registry/src/schemas.ts index 65a126288d..127793b177 100644 --- a/packages/registry/src/schemas.ts +++ b/packages/registry/src/schemas.ts @@ -17,31 +17,71 @@ const registryItemComplexType = ["registry:block"] as const; const registryItemInternalType = ["registry:example", "registry:internal"] as const; export type RegistryItemType = z.infer; -const registryItemTypeSchema = z.enum([ - ...registryItemFileType, - ...registryItemComplexType, - ...registryItemInternalType, -]); +const registryItemTypeSchema = z + .enum([...registryItemFileType, ...registryItemComplexType, ...registryItemInternalType]) + .describe( + "The type of the item. Used to determine the type and target path of the item when resolved for a project." + ); export type RegistryItemFileType = z.infer; -const registryItemFileTypeSchema = z.enum(registryItemFileType); +const registryItemFileTypeSchema = z + .enum(registryItemFileType) + .describe("The type of the file. Used to resolve the file's path for a project."); export type RegistryItemFile = z.infer; -const registryItemFileSchema = z.object({ - content: z.string(), - type: registryItemFileTypeSchema, - target: z.string(), -}); +const registryItemFileSchema = z + .object({ + content: z.string().describe("The content of the file."), + type: registryItemFileTypeSchema, + target: z + .string() + .describe("The target path of the file. This is where the file will be installed."), + }) + .describe( + "The main payload of the registry item. This is an array of files that are part of the registry item. Each file is an object with a target, type, and content." + ); + +const registryDependenciesSchema = z + .string() + .array() + .describe( + "An array of registry items that this item depends on. Use the name of the item to reference shadcn/ui components and urls to reference other registries." + ); const baseIndexItemSchema = z.object({ - name: z.string(), - title: z.string().optional(), + name: z + .string() + .describe( + "The name of the item. Used to identify the item in the registry. It should be unique for your registry." + ), + title: z + .string() + .optional() + .describe( + "The human-readable title for your registry item. Keep it short and descriptive." + ), + type: registryItemTypeSchema, - author: z.string().min(2, "Author name must be at least 2 characters").optional(), - description: z.string().optional(), - dependencies: z.string().array().optional(), - devDependencies: z.string().array().optional(), - registryDependencies: z.string().array().optional(), + author: z + .string() + .min(2, "Author name must be at least 2 characters") + .optional() + .describe("The author of the item. Recommended format: username "), + description: z + .string() + .optional() + .describe("The description of the item. Used to provide a brief overview of the item."), + dependencies: z + .string() + .array() + .optional() + .describe("An array of NPM dependencies required by the registry item."), + devDependencies: z + .string() + .array() + .optional() + .describe("An array of NPM dev dependencies required by the registry item."), + registryDependencies: z.optional(registryDependenciesSchema), }); export type RegistryIndexItem = z.infer; @@ -62,28 +102,63 @@ export const registryBaseColorSchema = z.object({ }); export type CssVars = z.infer; -const registryItemCssVarsSchema = z.object({ - theme: z.optional(colorSchema), - light: z.optional(colorSchema), - dark: z.optional(colorSchema), -}); +const registryItemCssVarsSchema = z + .object({ + theme: z + .optional(colorSchema) + .describe( + "CSS variables for the @theme directive. For Tailwind v4 projects only. Use tailwind for older projects." + ), + light: z.optional(colorSchema).describe("CSS variables for the light theme."), + dark: z.optional(colorSchema).describe("CSS variables for the dark theme."), + }) + .describe( + "The css variables for the registry item. This will be merged with the project's css variables." + ); type CssSchema = { [x: string]: string | CssSchema }; -const registryItemCssSchema: z.ZodType = z.record( - z.string(), - z.lazy(() => z.union([z.string(), registryItemCssSchema])) -); +const registryItemCssSchema: z.ZodType = z + .record( + z + .string() + .describe("Direct CSS string (e.g., 'font-family: sans-serif; line-height: 1.5;')"), + z + .lazy(() => + z.union([ + z + .string() + .describe("CSS property value (e.g., 'blue', 'var(--color-primary)')"), + registryItemCssSchema.describe("CSS property value for nested rule"), + ]) + ) + .describe("CSS properties or nested selectors") + ) + .describe( + "CSS definitions to be added to the project's CSS file. Supports at-rules, selectors, nested rules, utilities, layers, and more." + ); export type RegistryItem = z.infer; /** Schema for registry item endpoints (e.g. `https://example.com/registry/item.json`) */ export const registryItemSchema = z.object({ $schema: z.string().optional(), ...baseIndexItemSchema.shape, - docs: z.string().optional(), - categories: z.string().array().optional(), + docs: z + .string() + .optional() + .describe("The documentation for the registry item. This is a markdown string."), + categories: z + .string() + .array() + .optional() + .describe("The categories of the registry item. This is an array of strings."), css: z.optional(registryItemCssSchema), cssVars: z.optional(registryItemCssVarsSchema), - meta: z.record(z.string(), z.any()).optional(), + meta: z + .record(z.string(), z.any()) + .optional() + .describe( + "Additional metadata for the registry item. This is an object with any key value pairs." + ), files: z.array(registryItemFileSchema), }); @@ -92,8 +167,8 @@ export type Registry = z.infer; /** Schema for `registry.json` */ export const registrySchema = z.object({ $schema: z.string().optional(), - name: z.string(), - homepage: z.string(), + name: z.string().describe("The name of the registry."), + homepage: z.string().describe("The homepage of the registry."), // installs specified versions of dependencies during auto-detection overrideDependencies: z.string().array().optional(), aliases: z @@ -104,19 +179,26 @@ export const registrySchema = z.object({ utils: z.string().optional(), hooks: z.string().optional(), }) - .optional(), + .optional() + .describe("Defines which internal import paths should be transformed during `build`."), items: baseIndexItemSchema .extend({ files: registryItemFileSchema .partial() .extend({ - path: z.string(), + path: z + .string() + .describe("The path to the file relative to the registry root."), type: registryItemFileTypeSchema, }) - .array(), - registryDependencies: z.string().array(), + .array() + .describe( + "An array of files that instructs the `build` command on how to locate and parse the registry files." + ), + registryDependencies: registryDependenciesSchema, cssVars: z.optional(registryItemCssVarsSchema), css: z.optional(registryItemCssSchema), }) - .array(), + .array() + .describe("Defines a custom component registry."), }); From 264d161d1ad6b416bc6744bf2f1697ef5146ed9d Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Fri, 16 May 2025 17:46:02 -0400 Subject: [PATCH 7/8] missed a spot --- packages/registry/src/schemas.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/registry/src/schemas.ts b/packages/registry/src/schemas.ts index 127793b177..2fa9f30222 100644 --- a/packages/registry/src/schemas.ts +++ b/packages/registry/src/schemas.ts @@ -170,7 +170,13 @@ export const registrySchema = z.object({ name: z.string().describe("The name of the registry."), homepage: z.string().describe("The homepage of the registry."), // installs specified versions of dependencies during auto-detection - overrideDependencies: z.string().array().optional(), + overrideDependencies: z + .string() + .array() + .optional() + .describe( + "An array of NPM dependencies that should have their versions overridden during registry `build`." + ), aliases: z .object({ lib: z.string().optional(), @@ -180,7 +186,9 @@ export const registrySchema = z.object({ hooks: z.string().optional(), }) .optional() - .describe("Defines which internal import paths should be transformed during `build`."), + .describe( + "Defines which internal import paths should be transformed during registry `build`." + ), items: baseIndexItemSchema .extend({ files: registryItemFileSchema From 5b06e957dc3b2a746e8c9bd8cbfadfe84add5aa9 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Fri, 16 May 2025 17:50:23 -0400 Subject: [PATCH 8/8] finish it --- sites/docs/src/content/registry/registry-json.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sites/docs/src/content/registry/registry-json.md b/sites/docs/src/content/registry/registry-json.md index 33384da7b7..07ff048dab 100644 --- a/sites/docs/src/content/registry/registry-json.md +++ b/sites/docs/src/content/registry/registry-json.md @@ -157,9 +157,15 @@ Example transformation: "paneforge": "1.0.0-next.1" } } +``` -// With overrideDependencies: ["paneforge@next"] - +When the user installs your component, the latest `@next` version will be used instead of `1.0.0-next.1` -// When the user installs your component, the latest next version will be used instead of 1.0.0-next.1 +```json +{ + "dependencies": { + "paneforge": "1.0.0-next.1", // overrideDependencies: [] + "paneforge": "1.0.0-next.5" // overrideDependencies: ["paneforge@next"] + } +} ```