diff --git a/apps/website/package.json b/apps/website/package.json index 006eef0bb5..9806b21080 100644 --- a/apps/website/package.json +++ b/apps/website/package.json @@ -18,12 +18,12 @@ "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "effect": "^3.17.9", - "fumadocs-core": "15.7.3", + "fumadocs-core": "15.7.5", "fumadocs-docgen": "3.0.0", "fumadocs-mdx": "11.8.1", - "fumadocs-twoslash": "3.1.6", + "fumadocs-twoslash": "3.1.7", "fumadocs-typescript": "4.0.6", - "fumadocs-ui": "15.7.3", + "fumadocs-ui": "15.7.5", "lucide-react": "^0.542.0", "next": "^15.5.2", "next-view-transitions": "^0.3.4", diff --git a/packages/plugins/eslint-plugin-react-dom/src/utils/find-custom-component.ts b/packages/plugins/eslint-plugin-react-dom/src/utils/find-custom-component.ts index 8a44e0e6ed..82c3aa366a 100644 --- a/packages/plugins/eslint-plugin-react-dom/src/utils/find-custom-component.ts +++ b/packages/plugins/eslint-plugin-react-dom/src/utils/find-custom-component.ts @@ -1,10 +1,24 @@ import type { CustomComponentNormalized, CustomComponentPropNormalized } from "@eslint-react/shared"; +/** + * Finds a custom component by name from the provided array of components. + * + * @param name - The name of the component to find + * @param components - Array of normalized custom components to search through + * @returns The matching component if found, undefined otherwise + */ export function findCustomComponent(name: string, components: CustomComponentNormalized[]) { return components .findLast((c) => c.name === name || c.re.test(name)); } +/** + * Finds a custom component prop by its "as" name. + * + * @param name - The name to match against the prop's "as" property + * @param props - Array of normalized custom component props to search through + * @returns The matching prop if found, undefined otherwise + */ export function findCustomComponentProp(name: string, props: CustomComponentPropNormalized[]) { return props .findLast((a) => a.as === name); diff --git a/packages/shared/docs/functions/coerceESLintSettings.md b/packages/shared/docs/functions/coerceESLintSettings.md index 430bacf7c8..b695b3cf9e 100644 --- a/packages/shared/docs/functions/coerceESLintSettings.md +++ b/packages/shared/docs/functions/coerceESLintSettings.md @@ -8,12 +8,16 @@ > **coerceESLintSettings**(`settings`): `PartialDeep`\<`undefined` \| \{ `react-x?`: `unknown`; \}\> +Coerces unknown input to ESLintSettings type + ## Parameters ### settings `unknown` +The settings object to coerce + ## Returns `PartialDeep`\<`undefined` \| \{ `react-x?`: `unknown`; \}\> diff --git a/packages/shared/docs/functions/coerceSettings.md b/packages/shared/docs/functions/coerceSettings.md index e4555af039..a38315091a 100644 --- a/packages/shared/docs/functions/coerceSettings.md +++ b/packages/shared/docs/functions/coerceSettings.md @@ -8,44 +8,41 @@ > **coerceSettings**(`settings`): `object` +Coerces unknown input to ESLintReactSettings type + ## Parameters ### settings `unknown` +The settings object to coerce + ## Returns ### additionalComponents? > `optional` **additionalComponents**: `object`[] -An array of user-defined components - -#### Description - -This is used to inform the ESLint React plugins how to treat these components during checks. +User-defined components configuration +Informs ESLint React how to treat these components during validation #### Example ```ts -`[{ name: "Link", as: "a", attributes: [{ name: "to", as: "href" }, { name: "rel", defaultValue: "noopener noreferrer" }] }]` +[{ name: "Link", as: "a", attributes: [{ name: "to", as: "href" }] }] ``` ### additionalHooks? > `optional` **additionalHooks**: `object` -A object to define additional hooks that are equivalent to the built-in React Hooks. - -#### Description - -ESLint React will recognize these aliases as equivalent to the built-in hooks in all its rules. +Custom hooks that should be treated as equivalent to built-in React Hooks #### Example ```ts -`{ useEffect: ["useIsomorphicLayoutEffect"] }` +{ useEffect: ["useIsomorphicLayoutEffect"] } ``` #### additionalHooks.use? @@ -128,51 +125,49 @@ ESLint React will recognize these aliases as equivalent to the built-in hooks in > `optional` **importSource**: `string` -The source where React is imported from. - -#### Description - -This allows to specify a custom import location for React when not using the official distribution. +The source where React is imported from +Allows specifying a custom import location for React #### Default -`"react"` +```ts +"react" +``` #### Example ```ts -`"@pika/react"` +"@pika/react" ``` ### polymorphicPropName? > `optional` **polymorphicPropName**: `string` -The name of the prop that is used for polymorphic components. - -#### Description - -This is used to determine the type of the component. +The prop name used for polymorphic components +Used to determine the component's type #### Example ```ts -`"as"` +"as" ``` ### version? > `optional` **version**: `string` -React version to use, "detect" means auto detect React version from the project's dependencies. -If `importSource` is specified, an equivalent version of React should be provided here. +React version to use +"detect" means auto-detect React version from project dependencies #### Example ```ts -`"18.3.1"` +"18.3.1" ``` #### Default -`"detect"` +```ts +"detect" +``` diff --git a/packages/shared/docs/functions/decodeESLintSettings.md b/packages/shared/docs/functions/decodeESLintSettings.md index 5fa0a29a73..917f788d01 100644 --- a/packages/shared/docs/functions/decodeESLintSettings.md +++ b/packages/shared/docs/functions/decodeESLintSettings.md @@ -8,12 +8,16 @@ > **decodeESLintSettings**(`settings`): `undefined` \| \{ `react-x?`: `unknown`; \} +Decodes and validates ESLint settings, using defaults if invalid + ## Parameters ### settings `unknown` +The settings object to decode + ## Returns `undefined` \| \{ `react-x?`: `unknown`; \} diff --git a/packages/shared/docs/functions/decodeSettings.md b/packages/shared/docs/functions/decodeSettings.md index 644272ca84..5ba45eb3e8 100644 --- a/packages/shared/docs/functions/decodeSettings.md +++ b/packages/shared/docs/functions/decodeSettings.md @@ -8,44 +8,41 @@ > **decodeSettings**(`settings`): `object` +Decodes and validates ESLint React settings, using defaults if invalid + ## Parameters ### settings `unknown` +The settings object to decode + ## Returns ### additionalComponents? > `optional` **additionalComponents**: `object`[] -An array of user-defined components - -#### Description - -This is used to inform the ESLint React plugins how to treat these components during checks. +User-defined components configuration +Informs ESLint React how to treat these components during validation #### Example ```ts -`[{ name: "Link", as: "a", attributes: [{ name: "to", as: "href" }, { name: "rel", defaultValue: "noopener noreferrer" }] }]` +[{ name: "Link", as: "a", attributes: [{ name: "to", as: "href" }] }] ``` ### additionalHooks? > `optional` **additionalHooks**: `object` -A object to define additional hooks that are equivalent to the built-in React Hooks. - -#### Description - -ESLint React will recognize these aliases as equivalent to the built-in hooks in all its rules. +Custom hooks that should be treated as equivalent to built-in React Hooks #### Example ```ts -`{ useEffect: ["useIsomorphicLayoutEffect"] }` +{ useEffect: ["useIsomorphicLayoutEffect"] } ``` #### additionalHooks.use? @@ -128,51 +125,49 @@ ESLint React will recognize these aliases as equivalent to the built-in hooks in > `optional` **importSource**: `string` -The source where React is imported from. - -#### Description - -This allows to specify a custom import location for React when not using the official distribution. +The source where React is imported from +Allows specifying a custom import location for React #### Default -`"react"` +```ts +"react" +``` #### Example ```ts -`"@pika/react"` +"@pika/react" ``` ### polymorphicPropName? > `optional` **polymorphicPropName**: `string` -The name of the prop that is used for polymorphic components. - -#### Description - -This is used to determine the type of the component. +The prop name used for polymorphic components +Used to determine the component's type #### Example ```ts -`"as"` +"as" ``` ### version? > `optional` **version**: `string` -React version to use, "detect" means auto detect React version from the project's dependencies. -If `importSource` is specified, an equivalent version of React should be provided here. +React version to use +"detect" means auto-detect React version from project dependencies #### Example ```ts -`"18.3.1"` +"18.3.1" ``` #### Default -`"detect"` +```ts +"detect" +``` diff --git a/packages/shared/docs/functions/getSettingsFromContext.md b/packages/shared/docs/functions/getSettingsFromContext.md index 315fcb5e02..ab06e272d3 100644 --- a/packages/shared/docs/functions/getSettingsFromContext.md +++ b/packages/shared/docs/functions/getSettingsFromContext.md @@ -8,12 +8,17 @@ > **getSettingsFromContext**(`context`): [`ESLintReactSettingsNormalized`](../interfaces/ESLintReactSettingsNormalized.md) +Retrieves normalized ESLint React settings from the rule context +Uses caching for performance optimization + ## Parameters ### context `RuleContext` +The ESLint rule context + ## Returns [`ESLintReactSettingsNormalized`](../interfaces/ESLintReactSettingsNormalized.md) diff --git a/packages/shared/docs/functions/isESLintReactSettings.md b/packages/shared/docs/functions/isESLintReactSettings.md index 339a5b32ca..5d52472297 100644 --- a/packages/shared/docs/functions/isESLintReactSettings.md +++ b/packages/shared/docs/functions/isESLintReactSettings.md @@ -8,12 +8,16 @@ > **isESLintReactSettings**(`settings`): `settings is { additionalComponents?: { as?: string; attributes?: { as?: string; defaultValue?: string; name: string }[]; name: string }[]; additionalHooks?: { use?: string[]; useActionState?: string[]; useCallback?: string[]; useContext?: string[]; useDebugValue?: string[]; useDeferredValue?: string[]; useEffect?: string[]; useFormStatus?: string[]; useId?: string[]; useImperativeHandle?: string[]; useInsertionEffect?: string[]; useLayoutEffect?: string[]; useMemo?: string[]; useOptimistic?: string[]; useReducer?: string[]; useRef?: string[]; useState?: string[]; useSyncExternalStore?: string[]; useTransition?: string[] }; importSource?: string; polymorphicPropName?: string; version?: string }` +Checks if the provided settings conform to ESLintReactSettings schema + ## Parameters ### settings `unknown` +The settings object to validate + ## Returns `settings is { additionalComponents?: { as?: string; attributes?: { as?: string; defaultValue?: string; name: string }[]; name: string }[]; additionalHooks?: { use?: string[]; useActionState?: string[]; useCallback?: string[]; useContext?: string[]; useDebugValue?: string[]; useDeferredValue?: string[]; useEffect?: string[]; useFormStatus?: string[]; useId?: string[]; useImperativeHandle?: string[]; useInsertionEffect?: string[]; useLayoutEffect?: string[]; useMemo?: string[]; useOptimistic?: string[]; useReducer?: string[]; useRef?: string[]; useState?: string[]; useSyncExternalStore?: string[]; useTransition?: string[] }; importSource?: string; polymorphicPropName?: string; version?: string }` diff --git a/packages/shared/docs/functions/isESLintSettings.md b/packages/shared/docs/functions/isESLintSettings.md index 95ab7943f2..254da4caaa 100644 --- a/packages/shared/docs/functions/isESLintSettings.md +++ b/packages/shared/docs/functions/isESLintSettings.md @@ -8,12 +8,16 @@ > **isESLintSettings**(`settings`): settings is undefined \| \{ react-x?: unknown \} +Checks if the provided settings conform to ESLintSettings schema + ## Parameters ### settings `unknown` +The settings object to validate + ## Returns settings is undefined \| \{ react-x?: unknown \} diff --git a/packages/shared/docs/functions/normalizeSettings.md b/packages/shared/docs/functions/normalizeSettings.md index 865d58165b..2cda67faa8 100644 --- a/packages/shared/docs/functions/normalizeSettings.md +++ b/packages/shared/docs/functions/normalizeSettings.md @@ -8,6 +8,9 @@ > **normalizeSettings**(`__namedParameters`): `object` +Normalizes ESLint React settings to a consistent internal format +Transforms component definitions and resolves version information + ## Parameters ### \_\_namedParameters @@ -16,32 +19,25 @@ `object`[] = `[]` -An array of user-defined components - -**Description** - -This is used to inform the ESLint React plugins how to treat these components during checks. +User-defined components configuration +Informs ESLint React how to treat these components during validation **Example** ```ts -`[{ name: "Link", as: "a", attributes: [{ name: "to", as: "href" }, { name: "rel", defaultValue: "noopener noreferrer" }] }]` +[{ name: "Link", as: "a", attributes: [{ name: "to", as: "href" }] }] ``` #### additionalHooks? \{ `use?`: `string`[]; `useActionState?`: `string`[]; `useCallback?`: `string`[]; `useContext?`: `string`[]; `useDebugValue?`: `string`[]; `useDeferredValue?`: `string`[]; `useEffect?`: `string`[]; `useFormStatus?`: `string`[]; `useId?`: `string`[]; `useImperativeHandle?`: `string`[]; `useInsertionEffect?`: `string`[]; `useLayoutEffect?`: `string`[]; `useMemo?`: `string`[]; `useOptimistic?`: `string`[]; `useReducer?`: `string`[]; `useRef?`: `string`[]; `useState?`: `string`[]; `useSyncExternalStore?`: `string`[]; `useTransition?`: `string`[]; \} = `{}` -A object to define additional hooks that are equivalent to the built-in React Hooks. - -**Description** - -ESLint React will recognize these aliases as equivalent to the built-in hooks in all its rules. +Custom hooks that should be treated as equivalent to built-in React Hooks **Example** ```ts -`{ useEffect: ["useIsomorphicLayoutEffect"] }` +{ useEffect: ["useIsomorphicLayoutEffect"] } ``` #### additionalHooks.use? @@ -124,54 +120,52 @@ ESLint React will recognize these aliases as equivalent to the built-in hooks in `string` = `"react"` -The source where React is imported from. - -**Description** - -This allows to specify a custom import location for React when not using the official distribution. +The source where React is imported from +Allows specifying a custom import location for React **Default** -`"react"` +```ts +"react" +``` **Example** ```ts -`"@pika/react"` +"@pika/react" ``` #### polymorphicPropName? `string` = `"as"` -The name of the prop that is used for polymorphic components. - -**Description** - -This is used to determine the type of the component. +The prop name used for polymorphic components +Used to determine the component's type **Example** ```ts -`"as"` +"as" ``` #### version? `string` -React version to use, "detect" means auto detect React version from the project's dependencies. -If `importSource` is specified, an equivalent version of React should be provided here. +React version to use +"detect" means auto-detect React version from project dependencies **Example** ```ts -`"18.3.1"` +"18.3.1" ``` **Default** -`"detect"` +```ts +"detect" +``` ## Returns diff --git a/packages/shared/docs/interfaces/CustomComponentNormalized.md b/packages/shared/docs/interfaces/CustomComponentNormalized.md index 30dc026e61..b390c6682d 100644 --- a/packages/shared/docs/interfaces/CustomComponentNormalized.md +++ b/packages/shared/docs/interfaces/CustomComponentNormalized.md @@ -6,6 +6,8 @@ # Interface: CustomComponentNormalized +Normalized representation of a custom component with RegExp for matching + ## Properties ### as diff --git a/packages/shared/docs/interfaces/CustomComponentPropNormalized.md b/packages/shared/docs/interfaces/CustomComponentPropNormalized.md index f86f3eab54..7f4144395c 100644 --- a/packages/shared/docs/interfaces/CustomComponentPropNormalized.md +++ b/packages/shared/docs/interfaces/CustomComponentPropNormalized.md @@ -6,6 +6,8 @@ # Interface: CustomComponentPropNormalized +Normalized representation of a custom component prop + ## Properties ### as diff --git a/packages/shared/docs/interfaces/ESLintReactSettingsNormalized.md b/packages/shared/docs/interfaces/ESLintReactSettingsNormalized.md index 3afb07eefc..959dc331b0 100644 --- a/packages/shared/docs/interfaces/ESLintReactSettingsNormalized.md +++ b/packages/shared/docs/interfaces/ESLintReactSettingsNormalized.md @@ -6,6 +6,8 @@ # Interface: ESLintReactSettingsNormalized +Normalized ESLint React settings with processed values + ## Properties ### additionalHooks diff --git a/packages/shared/docs/variables/CustomComponentPropSchema.md b/packages/shared/docs/variables/CustomComponentPropSchema.md index cb63259515..ec3ddef30b 100644 --- a/packages/shared/docs/variables/CustomComponentPropSchema.md +++ b/packages/shared/docs/variables/CustomComponentPropSchema.md @@ -7,3 +7,5 @@ # Variable: CustomComponentPropSchema > `const` **CustomComponentPropSchema**: `ZodObject`\<\{ `as`: `ZodOptional`\<`ZodString`\>; `defaultValue`: `ZodOptional`\<`ZodString`\>; `name`: `ZodString`; \}, `$strip`\> + +Schema for component prop mapping between user-defined components and host components diff --git a/packages/shared/docs/variables/CustomComponentSchema.md b/packages/shared/docs/variables/CustomComponentSchema.md index a7973b7dbf..b0c1bb915a 100644 --- a/packages/shared/docs/variables/CustomComponentSchema.md +++ b/packages/shared/docs/variables/CustomComponentSchema.md @@ -8,8 +8,6 @@ > `const` **CustomComponentSchema**: `ZodObject`\<\{ `as`: `ZodOptional`\<`ZodString`\>; `attributes`: `ZodOptional`\<`ZodArray`\<`ZodObject`\<\{ `as`: `ZodOptional`\<`ZodString`\>; `defaultValue`: `ZodOptional`\<`ZodString`\>; `name`: `ZodString`; \}, `$strip`\>\>\>; `name`: `ZodString`; \}, `$strip`\> -## Description - -This will provide some key information to the rule before checking for user-defined components. -For example: -Which prop is used as the `href` prop for the user-defined `Link` component that represents the built-in `a` element. +Schema for custom components configuration +Provides key information about user-defined components before validation +Example: Which prop is used as the `href` prop in a custom `Link` component diff --git a/packages/shared/docs/variables/CustomHooksSchema.md b/packages/shared/docs/variables/CustomHooksSchema.md index 77694fca5f..2afb33083a 100644 --- a/packages/shared/docs/variables/CustomHooksSchema.md +++ b/packages/shared/docs/variables/CustomHooksSchema.md @@ -7,3 +7,5 @@ # Variable: CustomHooksSchema > `const` **CustomHooksSchema**: `ZodObject`\<\{ `use`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useActionState`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useCallback`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useContext`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useDebugValue`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useDeferredValue`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useEffect`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useFormStatus`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useId`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useImperativeHandle`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useInsertionEffect`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useLayoutEffect`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useMemo`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useOptimistic`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useReducer`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useRef`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useState`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useSyncExternalStore`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useTransition`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; \}, `$strip`\> + +Schema for custom hooks aliases that should be treated as React Hooks diff --git a/packages/shared/docs/variables/DEFAULT_ESLINT_REACT_SETTINGS.md b/packages/shared/docs/variables/DEFAULT_ESLINT_REACT_SETTINGS.md index 31aac91eb9..d90ee5248c 100644 --- a/packages/shared/docs/variables/DEFAULT_ESLINT_REACT_SETTINGS.md +++ b/packages/shared/docs/variables/DEFAULT_ESLINT_REACT_SETTINGS.md @@ -8,7 +8,7 @@ > `const` **DEFAULT\_ESLINT\_REACT\_SETTINGS**: `object` -The default ESLint settings for "react-x". +Default ESLint React settings ## Type Declaration diff --git a/packages/shared/docs/variables/DEFAULT_ESLINT_SETTINGS.md b/packages/shared/docs/variables/DEFAULT_ESLINT_SETTINGS.md index 4020c9a2e4..5af5a9a1d5 100644 --- a/packages/shared/docs/variables/DEFAULT_ESLINT_SETTINGS.md +++ b/packages/shared/docs/variables/DEFAULT_ESLINT_SETTINGS.md @@ -8,6 +8,8 @@ > `const` **DEFAULT\_ESLINT\_SETTINGS**: `object` +Default ESLint settings with React settings included + ## Type Declaration ### react-x diff --git a/packages/shared/docs/variables/defineSettings.md b/packages/shared/docs/variables/defineSettings.md index 15eb84a730..d578737967 100644 --- a/packages/shared/docs/variables/defineSettings.md +++ b/packages/shared/docs/variables/defineSettings.md @@ -8,7 +8,8 @@ > `const` **defineSettings**: (`settings`) => [`ESLintReactSettings`](../type-aliases/ESLintReactSettings.md) = `identity` -A helper function to define settings for "react-x" with type checking in JavaScript files. +Helper function for defining typed settings for "react-x" in JavaScript files +Provides type checking without runtime transformation ## Parameters @@ -16,10 +17,6 @@ A helper function to define settings for "react-x" with type checking in JavaScr [`ESLintReactSettings`](../type-aliases/ESLintReactSettings.md) -The settings. - ## Returns [`ESLintReactSettings`](../type-aliases/ESLintReactSettings.md) - -The settings. diff --git a/packages/shared/package.json b/packages/shared/package.json index ed29a6f492..47193ffcd5 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -38,7 +38,7 @@ "@eslint-react/kit": "workspace:*", "@typescript-eslint/utils": "^8.41.0", "ts-pattern": "^5.8.0", - "zod": "^4.1.4" + "zod": "^4.1.5" }, "devDependencies": { "@local/configs": "workspace:*", diff --git a/packages/shared/src/settings.ts b/packages/shared/src/settings.ts index cf16c3c5c3..97af7cd572 100644 --- a/packages/shared/src/settings.ts +++ b/packages/shared/src/settings.ts @@ -1,3 +1,4 @@ +/* eslint-disable jsdoc/require-param */ /* eslint-disable perfectionist/sort-objects */ import type { unit } from "@eslint-react/eff"; import { getOrElseUpdate, identity } from "@eslint-react/eff"; @@ -10,68 +11,71 @@ import { z } from "zod/v4"; import { getReactVersion } from "./get-react-version"; +// ===== Schema Definitions ===== + +/** + * Schema for component prop mapping between user-defined components and host components + */ export const CustomComponentPropSchema = z.object({ /** - * The name of the prop in the user-defined component. - * @example - * "to" + * The name of the prop in the user-defined component + * @example "to" */ name: z.string(), + /** - * The name of the prop in the host component. - * @example - * "href" + * The name of the prop in the host component + * @example "href" */ as: z.optional(z.string()), + /** - * Whether the prop is controlled or not in the user-defined component. + * Whether the prop is controlled in the user-defined component * @internal - * @example - * `true` */ controlled: z.optional(z.boolean()), + /** - * The default value of the prop in the user-defined component. - * @example - * `"/"` + * The default value of the prop in the user-defined component + * @example "/", "noopener noreferrer" */ defaultValue: z.optional(z.string()), }); /** - * @description - * This will provide some key information to the rule before checking for user-defined components. - * For example: - * Which prop is used as the `href` prop for the user-defined `Link` component that represents the built-in `a` element. + * Schema for custom components configuration + * Provides key information about user-defined components before validation + * Example: Which prop is used as the `href` prop in a custom `Link` component */ export const CustomComponentSchema = z.object({ /** - * The name of the user-defined component. - * @example - * "Link" + * The name of the user-defined component + * @example "Link" */ name: z.string(), + /** - * The name of the host component that the user-defined component represents. - * @example - * "a" + * The name of the host component that the user-defined component represents + * @example "a" */ as: z.optional(z.string()), + /** - * Attributes mapping between the user-defined component and the host component. - * @example - * `Link` component has a `to` attribute that represents the `href` attribute in the built-in `a` element with a default value of `"/"`. + * Attributes mapping between the user-defined component and the host component + * @example Link's "to" attribute maps to anchor "href" attribute */ attributes: z.optional(z.array(CustomComponentPropSchema)), + /** - * The ESQuery selector to select the component precisely. + * ESQuery selector to precisely select the component * @internal - * @example - * `JSXElement:has(JSXAttribute[name.name='component'][value.value='a'])` */ selector: z.optional(z.string()), }); +/** + * Schema for custom hooks aliases that should be treated as React Hooks + */ export const CustomHooksSchema = z.object({ use: z.optional(z.array(z.string())), useActionState: z.optional(z.array(z.string())), @@ -95,55 +99,63 @@ export const CustomHooksSchema = z.object({ }); /** + * Schema for ESLint React settings configuration * @internal */ export const ESLintReactSettingsSchema = z.object({ /** - * The source where React is imported from. - * @description This allows to specify a custom import location for React when not using the official distribution. - * @default `"react"` - * @example `"@pika/react"` + * The source where React is imported from + * Allows specifying a custom import location for React + * @default "react" + * @example "@pika/react" */ importSource: z.optional(z.string()), + /** - * The name of the prop that is used for polymorphic components. - * @description This is used to determine the type of the component. - * @example `"as"` + * The prop name used for polymorphic components + * Used to determine the component's type + * @example "as" */ polymorphicPropName: z.optional(z.string()), + /** - * @default `true` + * Whether to use strict mode + * @default true * @internal */ strict: z.optional(z.boolean()), + /** - * Check both the shape and the import to determine if an API is from React. - * @default `true` + * Whether to skip import checks when determining if an API is from React + * @default true * @internal */ skipImportCheck: z.optional(z.boolean()), + /** - * React version to use, "detect" means auto detect React version from the project's dependencies. - * If `importSource` is specified, an equivalent version of React should be provided here. - * @example `"18.3.1"` - * @default `"detect"` + * React version to use + * "detect" means auto-detect React version from project dependencies + * @example "18.3.1" + * @default "detect" */ version: z.optional(z.string()), + /** - * A object to define additional hooks that are equivalent to the built-in React Hooks. - * @description ESLint React will recognize these aliases as equivalent to the built-in hooks in all its rules. - * @example `{ useEffect: ["useIsomorphicLayoutEffect"] }` + * Custom hooks that should be treated as equivalent to built-in React Hooks + * @example { useEffect: ["useIsomorphicLayoutEffect"] } */ additionalHooks: z.optional(CustomHooksSchema), + /** - * An array of user-defined components - * @description This is used to inform the ESLint React plugins how to treat these components during checks. - * @example `[{ name: "Link", as: "a", attributes: [{ name: "to", as: "href" }, { name: "rel", defaultValue: "noopener noreferrer" }] }]` + * User-defined components configuration + * Informs ESLint React how to treat these components during validation + * @example [{ name: "Link", as: "a", attributes: [{ name: "to", as: "href" }] }] */ additionalComponents: z.optional(z.array(CustomComponentSchema)), }); /** + * Schema for ESLint settings * @internal */ export const ESLintSettingsSchema = z.optional( @@ -152,26 +164,52 @@ export const ESLintSettingsSchema = z.optional( }), ); -export type CustomComponent = z.infer; +// ===== Type Definitions ===== +export type CustomComponent = z.infer; export type CustomComponentProp = z.infer; - export type CustomHooks = z.infer; - export type ESLintSettings = z.infer; - export type ESLintReactSettings = z.infer; -export function isESLintSettings(settings: unknown): settings is ESLintSettings { - return ESLintSettingsSchema.safeParse(settings).success; +/** + * Normalized representation of a custom component prop + */ +export interface CustomComponentPropNormalized { + name: string; + as: string; + // controlled?: boolean | unit; + defaultValue?: string | unit; } -export function isESLintReactSettings(settings: unknown): settings is ESLintReactSettings { - return ESLintReactSettingsSchema.safeParse(settings).success; +/** + * Normalized representation of a custom component with RegExp for matching + */ +export interface CustomComponentNormalized { + name: string; + as: string; + attributes: CustomComponentPropNormalized[]; + re: { test(s: string): boolean }; + // selector?: string | unit; +} + +/** + * Normalized ESLint React settings with processed values + */ +export interface ESLintReactSettingsNormalized { + additionalHooks: CustomHooks; + components: CustomComponentNormalized[]; + importSource: string; + polymorphicPropName: string | unit; + skipImportCheck: boolean; + strict: boolean; + version: string; } +// ===== Default Values ===== + /** - * The default ESLint settings for "react-x". + * Default ESLint React settings */ export const DEFAULT_ESLINT_REACT_SETTINGS = { version: "detect", @@ -186,39 +224,43 @@ export const DEFAULT_ESLINT_REACT_SETTINGS = { }, } as const satisfies ESLintReactSettings; +/** + * Default ESLint settings with React settings included + */ export const DEFAULT_ESLINT_SETTINGS = { "react-x": DEFAULT_ESLINT_REACT_SETTINGS, } as const satisfies ESLintSettings; -export interface CustomComponentPropNormalized { - name: string; - as: string; - // controlled?: boolean | unit; - defaultValue?: string | unit; -} +// ===== Utility Functions ===== -export interface CustomComponentNormalized { - name: string; - as: string; - attributes: CustomComponentPropNormalized[]; - re: { test(s: string): boolean }; - // selector?: string | unit; +/** + * Checks if the provided settings conform to ESLintSettings schema + * @param settings The settings object to validate + */ +export function isESLintSettings(settings: unknown): settings is ESLintSettings { + return ESLintSettingsSchema.safeParse(settings).success; } -export interface ESLintReactSettingsNormalized { - additionalHooks: CustomHooks; - components: CustomComponentNormalized[]; - importSource: string; - polymorphicPropName: string | unit; - skipImportCheck: boolean; - strict: boolean; - version: string; +/** + * Checks if the provided settings conform to ESLintReactSettings schema + * @param settings The settings object to validate + */ +export function isESLintReactSettings(settings: unknown): settings is ESLintReactSettings { + return ESLintReactSettingsSchema.safeParse(settings).success; } +/** + * Coerces unknown input to ESLintSettings type + * @param settings The settings object to coerce + */ export const coerceESLintSettings = (settings: unknown): PartialDeep => { return settings as PartialDeep; }; +/** + * Decodes and validates ESLint settings, using defaults if invalid + * @param settings The settings object to decode + */ export const decodeESLintSettings = (settings: unknown): ESLintSettings => { if (isESLintSettings(settings)) { return settings; @@ -226,10 +268,18 @@ export const decodeESLintSettings = (settings: unknown): ESLintSettings => { return DEFAULT_ESLINT_SETTINGS; }; +/** + * Coerces unknown input to ESLintReactSettings type + * @param settings The settings object to coerce + */ export const coerceSettings = (settings: unknown): PartialDeep => { return settings as PartialDeep; }; +/** + * Decodes and validates ESLint React settings, using defaults if invalid + * @param settings The settings object to decode + */ export const decodeSettings = (settings: unknown): ESLintReactSettings => { if (isESLintReactSettings(settings)) { return settings; @@ -237,6 +287,10 @@ export const decodeSettings = (settings: unknown): ESLintReactSettings => { return DEFAULT_ESLINT_REACT_SETTINGS; }; +/** + * Normalizes ESLint React settings to a consistent internal format + * Transforms component definitions and resolves version information + */ export const normalizeSettings = ({ additionalComponents = [], additionalHooks = {}, @@ -275,8 +329,14 @@ export const normalizeSettings = ({ } as const satisfies ESLintReactSettingsNormalized; }; +// Cache for storing normalized settings to avoid repeated processing const cache = new Map(); +/** + * Retrieves normalized ESLint React settings from the rule context + * Uses caching for performance optimization + * @param context The ESLint rule context + */ export function getSettingsFromContext(context: RuleContext): ESLintReactSettingsNormalized { const settings = context.settings; return getOrElseUpdate( @@ -287,12 +347,12 @@ export function getSettingsFromContext(context: RuleContext): ESLintReactSetting } /** - * A helper function to define settings for "react-x" with type checking in JavaScript files. - * @param settings The settings. - * @returns The settings. + * Helper function for defining typed settings for "react-x" in JavaScript files + * Provides type checking without runtime transformation */ export const defineSettings: (settings: ESLintReactSettings) => ESLintReactSettings = identity; +// Type declaration augmentation for TypeScript ESLint declare module "@typescript-eslint/utils/ts-eslint" { export interface SharedConfigurationSettings { ["react-x"]?: Partial; diff --git a/packages/utilities/kit/package.json b/packages/utilities/kit/package.json index c1d467fbe6..6e250b5be9 100644 --- a/packages/utilities/kit/package.json +++ b/packages/utilities/kit/package.json @@ -38,7 +38,7 @@ "@eslint-react/eff": "workspace:*", "@typescript-eslint/utils": "^8.41.0", "ts-pattern": "^5.8.0", - "zod": "^4.1.4" + "zod": "^4.1.5" }, "devDependencies": { "@local/configs": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a5c2092f66..739e7770ae 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -300,23 +300,23 @@ importers: specifier: ^3.17.9 version: 3.17.9 fumadocs-core: - specifier: 15.7.3 - version: 15.7.3(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + specifier: 15.7.5 + version: 15.7.5(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) fumadocs-docgen: specifier: 3.0.0 - version: 3.0.0(fumadocs-core@15.7.3(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)) + version: 3.0.0(fumadocs-core@15.7.5(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)) fumadocs-mdx: specifier: 11.8.1 - version: 11.8.1(acorn@8.15.0)(fumadocs-core@15.7.3(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react@19.1.1)(vite@7.1.3(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1)) + version: 11.8.1(acorn@8.15.0)(fumadocs-core@15.7.5(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react@19.1.1)(vite@7.1.3(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1)) fumadocs-twoslash: - specifier: 3.1.6 - version: 3.1.6(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(fumadocs-ui@15.7.3(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.12))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2) + specifier: 3.1.7 + version: 3.1.7(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(fumadocs-ui@15.7.5(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.12))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2) fumadocs-typescript: specifier: 4.0.6 version: 4.0.6(@types/react@19.1.12)(typescript@5.9.2) fumadocs-ui: - specifier: 15.7.3 - version: 15.7.3(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.12) + specifier: 15.7.5 + version: 15.7.5(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.12) lucide-react: specifier: ^0.542.0 version: 0.542.0(react@19.1.1) @@ -1306,8 +1306,8 @@ importers: specifier: ^5.8.0 version: 5.8.0 zod: - specifier: ^4.1.4 - version: 4.1.4 + specifier: ^4.1.5 + version: 4.1.5 devDependencies: '@local/configs': specifier: workspace:* @@ -1377,8 +1377,8 @@ importers: specifier: ^5.8.0 version: 5.8.0 zod: - specifier: ^4.1.4 - version: 4.1.4 + specifier: ^4.1.5 + version: 4.1.5 devDependencies: '@local/configs': specifier: workspace:* @@ -6329,8 +6329,8 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] - fumadocs-core@15.7.3: - resolution: {integrity: sha512-1p2zv81UBpnRAIpRk2nvw92lSz81zwGp3GeDculDhO0hkGwkbcVFsw43b1RNkjBwPO3eA2zIhWVsZiW3k6X4qQ==} + fumadocs-core@15.7.5: + resolution: {integrity: sha512-g3mWu+9+NAurEr0BkHPPnQ8NRkGmLGlxqaND3USse06eVfzAXnThF4S526/Pvv0q+YCnCpaUFg1pdMLJt1Eteg==} peerDependencies: '@mixedbread/sdk': ^0.19.0 '@oramacloud/client': 1.x.x || 2.x.x @@ -6382,8 +6382,8 @@ packages: vite: optional: true - fumadocs-twoslash@3.1.6: - resolution: {integrity: sha512-OwuVRP2olx6qGNINUvu3A4q/XFAGLzkUw51MaNQ9hHEwea6KmxkffCRN6G9cAEkqyWbdxLKf5pQ7NwsbGxe83g==} + fumadocs-twoslash@3.1.7: + resolution: {integrity: sha512-RHO1K6Sh8O8eS9TCQRv9C3ek/TZuUrUqMNtoKBx7D/D5L6OB3Skol+PTltHDzyIrmrHVRkO20tBlqyRxD3awUA==} peerDependencies: '@types/react': ^19.1.12 fumadocs-ui: ^15.0.0 @@ -6401,8 +6401,8 @@ packages: '@types/react': optional: true - fumadocs-ui@15.7.3: - resolution: {integrity: sha512-J8sFB17XVv4Ueo2HfEn8Vs4FhQxx44RlHCXUYqfIxmilPKOih0Y3CFljPN/3E19rPG+VVi3vsIpiuIFtQRj4Mg==} + fumadocs-ui@15.7.5: + resolution: {integrity: sha512-hMYszqW33qbJstS9iasrUhT8R4Iiz5R8zeZzSj+sTMRjSl/zv586Km488hWbTloZVnqjHcHVxjfr7uiKeiXZDg==} peerDependencies: '@types/react': ^19.1.12 next: ^15.5.2 @@ -9458,8 +9458,8 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} - zod@4.1.4: - resolution: {integrity: sha512-2YqJuWkU6IIK9qcE4k1lLLhyZ6zFw7XVRdQGpV97jEIZwTrscUw+DY31Xczd8nwaoksyJUIxCojZXwckJovWxA==} + zod@4.1.5: + resolution: {integrity: sha512-rcUUZqlLJgBC33IT3PNMgsCq6TzLQEG/Ei/KTCU0PedSWRMAXoOUN+4t/0H+Q8bdnLPdqUYnvboJT0bn/229qg==} zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -10700,7 +10700,7 @@ snapshots: '@eslint-react/eff': 2.0.0-next.153 '@typescript-eslint/utils': 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) ts-pattern: 5.8.0 - zod: 4.1.4 + zod: 4.1.5 transitivePeerDependencies: - eslint - supports-color @@ -10712,7 +10712,7 @@ snapshots: '@eslint-react/kit': 2.0.0-next.153(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) '@typescript-eslint/utils': 8.41.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) ts-pattern: 5.8.0 - zod: 4.1.4 + zod: 4.1.5 transitivePeerDependencies: - eslint - supports-color @@ -14812,7 +14812,7 @@ snapshots: fsevents@2.3.3: optional: true - fumadocs-core@15.7.3(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + fumadocs-core@15.7.5(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: '@formatjs/intl-localematcher': 0.6.1 '@orama/orama': 3.1.11 @@ -14839,31 +14839,31 @@ snapshots: transitivePeerDependencies: - supports-color - fumadocs-docgen@3.0.0(fumadocs-core@15.7.3(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)): + fumadocs-docgen@3.0.0(fumadocs-core@15.7.5(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)): dependencies: estree-util-to-js: 2.0.0 estree-util-value-to-estree: 3.4.0 - fumadocs-core: 15.7.3(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + fumadocs-core: 15.7.5(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) npm-to-yarn: 3.0.1 oxc-transform: 0.82.3 unist-util-visit: 5.0.0 - zod: 4.1.4 + zod: 4.1.5 - fumadocs-mdx@11.8.1(acorn@8.15.0)(fumadocs-core@15.7.3(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react@19.1.1)(vite@7.1.3(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1)): + fumadocs-mdx@11.8.1(acorn@8.15.0)(fumadocs-core@15.7.5(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react@19.1.1)(vite@7.1.3(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.43.1)(tsx@4.20.5)(yaml@2.8.1)): dependencies: '@mdx-js/mdx': 3.1.0(acorn@8.15.0) '@standard-schema/spec': 1.0.0 chokidar: 4.0.3 esbuild: 0.25.9 estree-util-value-to-estree: 3.4.0 - fumadocs-core: 15.7.3(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + fumadocs-core: 15.7.5(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) js-yaml: 4.1.0 lru-cache: 11.1.0 picocolors: 1.1.1 tinyexec: 1.0.1 tinyglobby: 0.2.14 unist-util-visit: 5.0.0 - zod: 4.1.4 + zod: 4.1.5 optionalDependencies: next: 15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0) react: 19.1.1 @@ -14872,11 +14872,11 @@ snapshots: - acorn - supports-color - fumadocs-twoslash@3.1.6(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(fumadocs-ui@15.7.3(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.12))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2): + fumadocs-twoslash@3.1.7(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(fumadocs-ui@15.7.5(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.12))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.2): dependencies: '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@shikijs/twoslash': 3.12.0(typescript@5.9.2) - fumadocs-ui: 15.7.3(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.12) + fumadocs-ui: 15.7.5(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.12) mdast-util-from-markdown: 2.0.2 mdast-util-gfm: 3.1.0 mdast-util-to-hast: 13.2.0 @@ -14909,7 +14909,7 @@ snapshots: transitivePeerDependencies: - supports-color - fumadocs-ui@15.7.3(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.12): + fumadocs-ui@15.7.5(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.12): dependencies: '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) @@ -14922,7 +14922,7 @@ snapshots: '@radix-ui/react-slot': 1.2.3(@types/react@19.1.12)(react@19.1.1) '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) class-variance-authority: 0.7.1 - fumadocs-core: 15.7.3(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + fumadocs-core: 15.7.5(@types/react@19.1.12)(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.91.0))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) lodash.merge: 4.6.2 next-themes: 0.4.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1) postcss-selector-parser: 7.1.0 @@ -18549,6 +18549,6 @@ snapshots: zod@3.25.76: {} - zod@4.1.4: {} + zod@4.1.5: {} zwitch@2.0.4: {}