@jfdevelops/react-layout 1.6.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/create-config/create-defined-resource-layout.cjs +18 -14
- package/dist/create-config/create-defined-resource-layout.cjs.map +1 -1
- package/dist/create-config/create-defined-resource-layout.d.cts +9 -5
- package/dist/create-config/create-defined-resource-layout.d.cts.map +1 -1
- package/dist/create-config/create-defined-resource-layout.d.mts +9 -5
- package/dist/create-config/create-defined-resource-layout.d.mts.map +1 -1
- package/dist/create-config/create-defined-resource-layout.mjs +19 -15
- package/dist/create-config/create-defined-resource-layout.mjs.map +1 -1
- package/dist/create-config/define-layout.cjs +66 -39
- package/dist/create-config/define-layout.cjs.map +1 -1
- package/dist/create-config/define-layout.d.cts +0 -5
- package/dist/create-config/define-layout.d.cts.map +1 -1
- package/dist/create-config/define-layout.d.mts +0 -5
- package/dist/create-config/define-layout.d.mts.map +1 -1
- package/dist/create-config/define-layout.mjs +67 -40
- package/dist/create-config/define-layout.mjs.map +1 -1
- package/dist/create-config/for-resources/create-component.d.cts +39 -21
- package/dist/create-config/for-resources/create-component.d.cts.map +1 -1
- package/dist/create-config/for-resources/create-component.d.mts +39 -21
- package/dist/create-config/for-resources/create-component.d.mts.map +1 -1
- package/dist/create-config/for-resources/create-for-resources.cjs +62 -7
- package/dist/create-config/for-resources/create-for-resources.cjs.map +1 -1
- package/dist/create-config/for-resources/create-for-resources.mjs +62 -7
- package/dist/create-config/for-resources/create-for-resources.mjs.map +1 -1
- package/dist/create-config/for-resources/scoped-render.cjs +1 -0
- package/dist/create-config/for-resources/scoped-render.cjs.map +1 -1
- package/dist/create-config/for-resources/scoped-render.d.cts.map +1 -1
- package/dist/create-config/for-resources/scoped-render.d.mts.map +1 -1
- package/dist/create-config/for-resources/scoped-render.mjs +1 -0
- package/dist/create-config/for-resources/scoped-render.mjs.map +1 -1
- package/dist/create-config/index.d.cts +2 -1
- package/dist/create-config/index.d.mts +2 -1
- package/dist/create-config/layout-name.cjs +36 -28
- package/dist/create-config/layout-name.cjs.map +1 -1
- package/dist/create-config/layout-name.d.cts +34 -28
- package/dist/create-config/layout-name.d.cts.map +1 -1
- package/dist/create-config/layout-name.d.mts +34 -28
- package/dist/create-config/layout-name.d.mts.map +1 -1
- package/dist/create-config/layout-name.mjs +36 -28
- package/dist/create-config/layout-name.mjs.map +1 -1
- package/dist/create-config/lazy-resource-layout.cjs +70 -86
- package/dist/create-config/lazy-resource-layout.cjs.map +1 -1
- package/dist/create-config/lazy-resource-layout.d.cts +9 -31
- package/dist/create-config/lazy-resource-layout.d.cts.map +1 -1
- package/dist/create-config/lazy-resource-layout.d.mts +9 -31
- package/dist/create-config/lazy-resource-layout.d.mts.map +1 -1
- package/dist/create-config/lazy-resource-layout.mjs +70 -86
- package/dist/create-config/lazy-resource-layout.mjs.map +1 -1
- package/dist/create-config/preview.cjs +1 -1
- package/dist/create-config/preview.d.cts +2 -0
- package/dist/create-config/preview.d.cts.map +1 -1
- package/dist/create-config/preview.d.mts +2 -0
- package/dist/create-config/preview.d.mts.map +1 -1
- package/dist/create-config/preview.mjs +1 -1
- package/dist/create-config/render-state.cjs +57 -18
- package/dist/create-config/render-state.cjs.map +1 -1
- package/dist/create-config/render-state.d.cts +18 -6
- package/dist/create-config/render-state.d.cts.map +1 -1
- package/dist/create-config/render-state.d.mts +18 -6
- package/dist/create-config/render-state.d.mts.map +1 -1
- package/dist/create-config/render-state.mjs +54 -18
- package/dist/create-config/render-state.mjs.map +1 -1
- package/dist/errors/lazy-resource-error.cjs +37 -0
- package/dist/errors/lazy-resource-error.cjs.map +1 -0
- package/dist/errors/lazy-resource-error.d.cts +26 -0
- package/dist/errors/lazy-resource-error.d.cts.map +1 -0
- package/dist/errors/lazy-resource-error.d.mts +26 -0
- package/dist/errors/lazy-resource-error.d.mts.map +1 -0
- package/dist/errors/lazy-resource-error.mjs +35 -0
- package/dist/errors/lazy-resource-error.mjs.map +1 -0
- package/dist/errors/react-layout-error.cjs +1 -1
- package/dist/errors/react-layout-error.mjs +1 -1
- package/dist/errors/resource-state-error.cjs +4 -1
- package/dist/errors/resource-state-error.cjs.map +1 -1
- package/dist/errors/resource-state-error.d.cts +1 -0
- package/dist/errors/resource-state-error.d.cts.map +1 -1
- package/dist/errors/resource-state-error.d.mts +1 -0
- package/dist/errors/resource-state-error.d.mts.map +1 -1
- package/dist/errors/resource-state-error.mjs +4 -1
- package/dist/errors/resource-state-error.mjs.map +1 -1
- package/dist/index.cjs +6 -2
- package/dist/index.d.cts +7 -4
- package/dist/index.d.mts +7 -4
- package/dist/index.mjs +4 -3
- package/dist/lazy/create-error-component.cjs +17 -0
- package/dist/lazy/create-error-component.cjs.map +1 -0
- package/dist/lazy/create-error-component.mjs +16 -0
- package/dist/lazy/create-error-component.mjs.map +1 -0
- package/dist/lazy/create-lazy-loader.cjs +78 -0
- package/dist/lazy/create-lazy-loader.cjs.map +1 -0
- package/dist/lazy/create-lazy-loader.d.cts +19 -0
- package/dist/lazy/create-lazy-loader.d.cts.map +1 -0
- package/dist/lazy/create-lazy-loader.d.mts +19 -0
- package/dist/lazy/create-lazy-loader.d.mts.map +1 -0
- package/dist/lazy/create-lazy-loader.mjs +78 -0
- package/dist/lazy/create-lazy-loader.mjs.map +1 -0
- package/dist/lazy/fallback-props.cjs +9 -0
- package/dist/lazy/fallback-props.cjs.map +1 -0
- package/dist/lazy/fallback-props.mjs +9 -0
- package/dist/lazy/fallback-props.mjs.map +1 -0
- package/dist/lazy/inspection.cjs +51 -0
- package/dist/lazy/inspection.cjs.map +1 -0
- package/dist/lazy/inspection.d.cts +28 -0
- package/dist/lazy/inspection.d.cts.map +1 -0
- package/dist/lazy/inspection.d.mts +28 -0
- package/dist/lazy/inspection.d.mts.map +1 -0
- package/dist/lazy/inspection.mjs +50 -0
- package/dist/lazy/inspection.mjs.map +1 -0
- package/dist/lazy/lazy-boundary.cjs +55 -0
- package/dist/lazy/lazy-boundary.cjs.map +1 -0
- package/dist/lazy/lazy-boundary.mjs +55 -0
- package/dist/lazy/lazy-boundary.mjs.map +1 -0
- package/dist/lazy/scoped-content.cjs +87 -0
- package/dist/lazy/scoped-content.cjs.map +1 -0
- package/dist/lazy/scoped-content.d.cts +19 -0
- package/dist/lazy/scoped-content.d.cts.map +1 -0
- package/dist/lazy/scoped-content.d.mts +19 -0
- package/dist/lazy/scoped-content.d.mts.map +1 -0
- package/dist/lazy/scoped-content.mjs +86 -0
- package/dist/lazy/scoped-content.mjs.map +1 -0
- package/dist/lazy/types.cjs +10 -0
- package/dist/lazy/types.cjs.map +1 -0
- package/dist/lazy/types.d.cts +39 -0
- package/dist/lazy/types.d.cts.map +1 -0
- package/dist/lazy/types.d.mts +39 -0
- package/dist/lazy/types.d.mts.map +1 -0
- package/dist/lazy/types.mjs +8 -0
- package/dist/lazy/types.mjs.map +1 -0
- package/dist/props.cjs +4 -2
- package/dist/props.cjs.map +1 -1
- package/dist/props.d.cts +6 -50
- package/dist/props.d.cts.map +1 -1
- package/dist/props.d.mts +6 -50
- package/dist/props.d.mts.map +1 -1
- package/dist/props.mjs +5 -2
- package/dist/props.mjs.map +1 -1
- package/dist/resource.cjs.map +1 -1
- package/dist/resource.d.cts +1 -1
- package/dist/resource.d.cts.map +1 -1
- package/dist/resource.d.mts +1 -1
- package/dist/resource.d.mts.map +1 -1
- package/dist/resource.mjs.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-for-resources.mjs","names":[],"sources":["../../../src/create-config/for-resources/create-for-resources.ts"],"sourcesContent":["import {\n createContext,\n createElement,\n type ComponentType,\n type JSX,\n useContext,\n} from 'react';\nimport type { ComposableComponents } from '@jfdevelops/react-layout-composables';\nimport {\n type AnyBuiltPropDefinition,\n validateProps,\n} from '@jfdevelops/react-layout-validator';\nimport type { InPropsDefinition, InPropsObject } from '../../props';\nimport type { LayoutResourceKey, ResourceDefinition } from '../../resource';\nimport { capitalize } from '../../utils/capitalize';\nimport { LayoutConfigurationError } from '../../errors';\nimport type { LayoutIncludeProps } from '../define-layout';\nimport type {\n CapitalizedResource,\n ResourcesLayoutName,\n} from './resource-selection';\nimport type { CreateResourceLayoutForResourcesFn } from './scoped-layout';\nimport {\n isRenderableComponentType,\n reservedScopedComponentNames,\n resolveScopedRenderResult,\n type ScopedRenderResult,\n withScopedCompoundStatics,\n} from './scoped-render';\n\ntype CreateForResourcesOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = {\n createLayoutForResource: (\n defaultName: string | undefined,\n resource: LayoutResourceKey<Resources>,\n ) => unknown;\n createMakeComposableLayout?: () => (\n options: Record<string, unknown>,\n ) => unknown;\n createResourceLayout: (options: Record<string, unknown>) => unknown;\n getComponentPropDefinitions: (\n resource: LayoutResourceKey<Resources>,\n ) => Record<string, AnyBuiltPropDefinition>;\n};\n\nexport function createForResources<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n IncludeProps extends LayoutIncludeProps<Resources, InProps, Composables>,\n CustomProps extends InPropsObject,\n>({\n createLayoutForResource,\n createMakeComposableLayout,\n createResourceLayout,\n getComponentPropDefinitions,\n}: CreateForResourcesOptions<Resources>) {\n return ((...resourcesOrOptions: Array<unknown>) => {\n const firstArgument = resourcesOrOptions[0];\n let resourceOptions: Array<{\n resource: LayoutResourceKey<Resources>;\n name?:\n | string\n | ((\n resource: CapitalizedResource<LayoutResourceKey<Resources>>,\n ) => string);\n }>;\n\n if (typeof firstArgument === 'string') {\n resourceOptions = resourcesOrOptions.map((resource) => ({\n resource: resource as LayoutResourceKey<Resources>,\n }));\n } else if (\n firstArgument !== null &&\n typeof firstArgument === 'object' &&\n 'resources' in firstArgument &&\n Array.isArray(firstArgument.resources)\n ) {\n const { name, resources } = firstArgument as {\n name?: ResourcesLayoutName<LayoutResourceKey<Resources>>;\n resources: Array<LayoutResourceKey<Resources>>;\n };\n resourceOptions = resources.map((resource) => ({\n name: typeof name === 'function' ? name : name?.[resource],\n resource,\n }));\n } else {\n resourceOptions = Object.entries(firstArgument ?? {}).map(\n ([resource, options]) => ({\n ...(options as {\n name?:\n | string\n | ((\n resource: CapitalizedResource<LayoutResourceKey<Resources>>,\n ) => string);\n }),\n resource: resource as LayoutResourceKey<Resources>,\n }),\n );\n }\n\n const defaultNames = new Map(\n resourceOptions.map(({ name, resource }) => [\n resource,\n typeof name === 'function'\n ? name(\n capitalize(resource) as CapitalizedResource<\n LayoutResourceKey<Resources>\n >,\n )\n : name,\n ]),\n );\n\n function scopedCreateResourceLayout(options: Record<string, unknown>) {\n const resource = options.resource as LayoutResourceKey<Resources>;\n\n return createResourceLayout({\n ...options,\n name: options.name ?? defaultNames.get(resource),\n });\n }\n\n function scopedForResource(options: {\n name?: string;\n resource: LayoutResourceKey<Resources>;\n }) {\n return createLayoutForResource(\n options.name ?? defaultNames.get(options.resource),\n options.resource,\n );\n }\n\n type ScopedComponentRenderFn = (\n props: Record<string, unknown>,\n components: Record<string, (props?: never) => JSX.Element>,\n ) => ScopedRenderResult;\n\n type ScopedResourceScopedComponentDefinition = {\n props?: Record<string, AnyBuiltPropDefinition>;\n render: ScopedComponentRenderFn;\n };\n\n type ScopedComponentEntry = {\n [option: string]: unknown;\n name?: string;\n props?: CreateComponentPropsBag;\n components?: Record<string, ScopedResourceScopedComponentDefinition>;\n render: ScopedComponentRenderFn;\n };\n\n type CreateComponentPropsBag = {\n include?: Record<string, true | 'optional'>;\n custom?: Record<string, AnyBuiltPropDefinition>;\n defined?: Record<string, unknown>;\n };\n\n function mergeCreateComponentProps(\n ...bags: Array<CreateComponentPropsBag | undefined>\n ): CreateComponentPropsBag {\n const include: Record<string, true | 'optional'> = {};\n const custom: Record<string, AnyBuiltPropDefinition> = {};\n\n for (const bag of bags) {\n Object.assign(include, bag?.include);\n Object.assign(custom, bag?.custom);\n\n for (const key of Object.keys(bag?.defined ?? {})) {\n include[key] = true;\n }\n }\n\n return { include, custom };\n }\n\n function createComponent(componentOptions: {\n props?: {\n include?: Record<string, true | 'optional'>;\n custom?: Record<string, AnyBuiltPropDefinition>;\n };\n resources?: Record<string, ScopedComponentEntry>;\n render: (\n props: Record<string, unknown>,\n context: Record<string, (props: never) => JSX.Element>,\n ) => ScopedRenderResult;\n }) {\n const mergedProps = mergeCreateComponentProps(\n componentOptions.props,\n ...Object.values(componentOptions.resources ?? {}).map(\n (entry) => entry.props,\n ),\n );\n const include = mergedProps.include ?? {};\n const custom = mergedProps.custom ?? {};\n const selectedResources = new Set(\n resourceOptions.map(({ resource }) => resource),\n );\n const componentPropsContext = createContext<\n Record<string, unknown> | undefined\n >(undefined);\n const definedEntries = new Map<\n LayoutResourceKey<Resources>,\n ScopedComponentEntry\n >();\n\n for (const [key, entry] of Object.entries(\n componentOptions.resources ?? {},\n )) {\n const resource = key as LayoutResourceKey<Resources>;\n\n if (!selectedResources.has(resource)) {\n throw new LayoutConfigurationError(\n `Resource \"${key}\" is not available in this scoped component`,\n );\n }\n\n definedEntries.set(resource, entry);\n }\n\n /** Resolved scoped components, per resource. */\n const resourceScopedComponents = new Map<\n LayoutResourceKey<Resources>,\n Record<string, (props?: never) => JSX.Element>\n >();\n const contextResources = new Map<string, LayoutResourceKey<Resources>>();\n const renderContext: Record<string, (props: never) => JSX.Element> =\n Object.fromEntries(\n [...definedEntries].map(([resource, entry]) => {\n const contextKey = capitalize(resource);\n\n if (contextKey === 'Root') {\n throw new LayoutConfigurationError(\n `Resource \"${resource}\" maps to the reserved render context key \"Root\"`,\n );\n }\n\n const existingResource = contextResources.get(contextKey);\n\n if (existingResource !== undefined) {\n throw new LayoutConfigurationError(\n `Resources \"${existingResource}\" and \"${resource}\" both map to render context key \"${contextKey}\"`,\n );\n }\n\n contextResources.set(contextKey, resource);\n\n /**\n * Built once per resource so every scoped component keeps a stable\n * identity, and shared by the resource render, the render context,\n * and any component bound through `asHOF()`.\n */\n const scopedComponents: Record<\n string,\n (props?: never) => JSX.Element\n > = {};\n\n for (const [name, definition] of Object.entries(\n entry.components ?? {},\n )) {\n if (reservedScopedComponentNames.has(name)) {\n throw new LayoutConfigurationError(\n `Scoped component \"${name}\" for resource \"${resource}\" uses a reserved name`,\n );\n }\n\n const ownPropDefinitions = definition.props ?? {};\n // Last call-site own-props / returned component for this scoped\n // entry. Compound statics re-run `render` with these so\n // `<DataTable variant=\"b\" />` then `<DataTable.Loading />` sees \"b\".\n let cachedOwnProps: Record<string, unknown> = {};\n let cachedReturnedComponent:\n | ComponentType<Record<string, unknown>>\n | undefined;\n\n function ScopedComponent(ownProps?: Record<string, unknown>) {\n const componentProps = useContext(componentPropsContext);\n\n if (componentProps === undefined) {\n throw new LayoutConfigurationError(\n `Scoped component \"${name}\" must be rendered inside its scoped component`,\n );\n }\n\n const resolvedOwnProps = ownProps ?? {};\n cachedOwnProps = resolvedOwnProps;\n\n validateProps(ownPropDefinitions, resolvedOwnProps, {\n layoutName:\n entry.name ??\n defaultNames.get(resource) ??\n capitalize(resource),\n resource,\n });\n\n // Mount a returned component type with call-site props; pass\n // nodes (elements, portals, null) through unchanged.\n const result = definition.render(\n { ...componentProps, ...resolvedOwnProps, resource },\n scopedComponents,\n );\n\n if (isRenderableComponentType(result)) {\n cachedReturnedComponent = result as ComponentType<\n Record<string, unknown>\n >;\n }\n\n return resolveScopedRenderResult(result, resolvedOwnProps);\n }\n\n // Types expose compound statics from the returned component\n // (`DataTable.Loading`); attach matching runtime wrappers.\n scopedComponents[name] = withScopedCompoundStatics(\n ScopedComponent,\n (staticName) => {\n function CompoundStatic(ownProps?: Record<string, unknown>) {\n const componentProps = useContext(componentPropsContext);\n\n if (componentProps === undefined) {\n throw new LayoutConfigurationError(\n `Scoped component \"${name}.${staticName}\" must be rendered inside its scoped component`,\n );\n }\n\n // Prefer the component from the last parent call (same\n // closure as that call's own-props). Fall back to re-running\n // render with cached parent props when needed.\n let result: unknown = cachedReturnedComponent;\n\n if (!isRenderableComponentType(result)) {\n result = definition.render(\n {\n ...componentProps,\n ...cachedOwnProps,\n resource,\n },\n scopedComponents,\n );\n }\n\n if (!isRenderableComponentType(result)) {\n throw new LayoutConfigurationError(\n `Scoped component \"${name}\" must return a component type to use static \"${staticName}\"`,\n );\n }\n\n const staticComponent = (\n result as ComponentType<Record<string, unknown>> &\n Record<string, unknown>\n )[staticName];\n\n if (!isRenderableComponentType(staticComponent)) {\n throw new LayoutConfigurationError(\n `Scoped component \"${name}\" has no component static \"${staticName}\"`,\n );\n }\n\n // Loading's props — those mount the static itself.\n return createElement(staticComponent, ownProps ?? {});\n }\n\n CompoundStatic.displayName = `${name}.${staticName}`;\n return CompoundStatic;\n },\n ) as (props?: never) => JSX.Element;\n }\n\n resourceScopedComponents.set(resource, scopedComponents);\n\n function ResourceRender(ownProps?: Record<string, unknown>) {\n const componentProps = useContext(componentPropsContext);\n\n if (componentProps === undefined) {\n throw new LayoutConfigurationError(\n `Render context component \"${contextKey}\" must be rendered inside its scoped component`,\n );\n }\n\n // Call-site props on `context.Users({ title, heading })` merge into\n // the resource render props and mount a returned component type.\n const callProps = { ...componentProps, ...ownProps, resource };\n return resolveScopedRenderResult(\n entry.render(callProps, scopedComponents),\n ownProps,\n );\n }\n\n return [\n contextKey,\n Object.assign(ResourceRender, scopedComponents),\n ];\n }),\n );\n\n /**\n * Layouts are created once per resource and cached. Creating one during\n * render would hand React a new component type on every pass, remounting\n * the whole subtree.\n */\n const roots = new Map<\n LayoutResourceKey<Resources>,\n (props: Record<string, unknown>) => JSX.Element\n >();\n\n function Root(rootProps: Record<string, unknown>) {\n const componentProps = useContext(componentPropsContext);\n\n if (componentProps === undefined) {\n throw new LayoutConfigurationError(\n 'Render context component \"Root\" must be rendered inside its scoped component',\n );\n }\n\n const resource =\n componentProps.resource as LayoutResourceKey<Resources>;\n let root = roots.get(resource);\n\n if (root === undefined) {\n const entry = definedEntries.get(resource);\n\n if (entry === undefined) {\n throw new LayoutConfigurationError(\n `Render context component \"Root\" requires a \"resources.${resource}\" entry to build the layout for resource \"${resource}\"`,\n );\n }\n\n // Layout option values come from the outer component call site\n // (`<Directory title=\"…\" />`), not from the resource entry.\n const availableDefinitions =\n getComponentPropDefinitions(resource);\n const layoutOptions: Record<string, unknown> = {};\n const defined = entry.props?.defined ?? {};\n\n for (const key of Object.keys(availableDefinitions)) {\n if (key in defined) {\n layoutOptions[key] = defined[key];\n }\n\n const capitalized = capitalize(key);\n if (capitalized in defined) {\n layoutOptions[capitalized] = defined[capitalized];\n }\n\n if (key in componentProps) {\n layoutOptions[key] = componentProps[key];\n }\n\n if (capitalized in componentProps) {\n layoutOptions[capitalized] = componentProps[capitalized];\n }\n }\n\n root = scopedCreateResourceLayout({\n ...layoutOptions,\n namespace: false,\n name:\n entry.name ??\n defaultNames.get(resource) ??\n capitalize(resource),\n resource,\n }) as (props: Record<string, unknown>) => JSX.Element;\n roots.set(resource, root);\n }\n\n const entry = definedEntries.get(resource);\n const definedCustom: Record<string, unknown> = {};\n const forwardedRootProps: Record<string, unknown> = {};\n\n for (const key of Object.keys(getComponentPropDefinitions(resource))) {\n if (key in componentProps) {\n forwardedRootProps[key] = componentProps[key];\n }\n\n const capitalized = capitalize(key);\n if (capitalized in componentProps) {\n forwardedRootProps[capitalized] = componentProps[capitalized];\n }\n }\n\n for (const [key, value] of Object.entries(\n entry?.props?.defined ?? {},\n )) {\n if (key in custom) {\n definedCustom[key] = value;\n }\n }\n\n return createElement(root, {\n ...forwardedRootProps,\n ...definedCustom,\n ...rootProps,\n });\n }\n\n renderContext.Root = Root;\n\n function Component(componentProps: Record<string, unknown>) {\n const componentResource =\n componentProps.resource as LayoutResourceKey<Resources>;\n\n if (!selectedResources.has(componentResource)) {\n throw new LayoutConfigurationError(\n `Resource \"${componentResource}\" is not available in this scoped component`,\n );\n }\n\n const defined =\n definedEntries.get(componentResource)?.props?.defined ?? {};\n const resolvedComponentProps = { ...defined, ...componentProps };\n const availableDefinitions =\n getComponentPropDefinitions(componentResource);\n const definitionsToValidate: Record<string, AnyBuiltPropDefinition> =\n {};\n\n for (const [key, inclusion] of Object.entries(include)) {\n const definition = availableDefinitions[key];\n\n if (!definition) {\n continue;\n }\n\n // Keep declared keys as-is — do not capitalize JSX.Element props.\n if (inclusion === true || key in resolvedComponentProps) {\n definitionsToValidate[key] = definition;\n }\n }\n\n for (const [key, definition] of Object.entries(custom)) {\n if (key === 'children' || key === 'resource') {\n continue;\n }\n\n definitionsToValidate[key] = definition;\n }\n\n validateProps(definitionsToValidate, resolvedComponentProps, {\n layoutName:\n definedEntries.get(componentResource)?.name ??\n defaultNames.get(componentResource) ??\n capitalize(componentResource),\n resource: componentResource,\n });\n\n // Top-level render may return a component type; mount it with the full\n // component props (include/custom + inferred return-type props).\n return createElement(\n componentPropsContext.Provider,\n { value: resolvedComponentProps },\n resolveScopedRenderResult(\n componentOptions.render(resolvedComponentProps, renderContext),\n resolvedComponentProps,\n ),\n );\n }\n\n /**\n * Bound components are created once per resource and cached. Returning a\n * fresh component from the factory would hand React a new component type\n * whenever the caller rebinds, remounting the subtree.\n */\n const boundComponents = new Map<\n LayoutResourceKey<Resources>,\n (props: Record<string, unknown>) => JSX.Element\n >();\n\n function bindResource(resource: LayoutResourceKey<Resources>) {\n if (!selectedResources.has(resource)) {\n throw new LayoutConfigurationError(\n `Resource \"${resource}\" is not available in this scoped component`,\n );\n }\n\n let boundComponent = boundComponents.get(resource);\n\n if (boundComponent === undefined) {\n boundComponent = Object.assign(\n (boundProps: Record<string, unknown>) =>\n createElement(Component, { ...boundProps, resource }),\n {\n displayName: `ScopedResourceComponent(${resource})`,\n props: undefined,\n resource: undefined,\n },\n resourceScopedComponents.get(resource) ?? {},\n );\n boundComponents.set(resource, boundComponent);\n }\n\n return boundComponent;\n }\n\n function asHOF() {\n return bindResource;\n }\n\n return Object.assign(Component, {\n asHOF,\n displayName: 'ScopedResourceComponent',\n props: undefined,\n });\n }\n\n function createComponentSetProps(baseProps: CreateComponentPropsBag) {\n function createWithProps(componentOptions: {\n props?: CreateComponentPropsBag;\n resources?: Record<string, ScopedComponentEntry>;\n render: (\n props: Record<string, unknown>,\n context: Record<string, (props: never) => JSX.Element>,\n ) => ScopedRenderResult;\n }) {\n return createComponent({\n ...componentOptions,\n props: mergeCreateComponentProps(baseProps, componentOptions.props),\n });\n }\n\n createWithProps.createResourceComponents = createResourceComponents;\n\n return createWithProps;\n }\n\n function createResourceComponents(options: {\n resource: LayoutResourceKey<Resources>;\n props?: CreateComponentPropsBag;\n name?: string;\n components?: Record<string, ScopedResourceScopedComponentDefinition>;\n render: ScopedComponentRenderFn;\n }) {\n const { resource, props, ...entry } = options;\n\n if (\n !resourceOptions.some(\n (resourceOption) => resourceOption.resource === resource,\n )\n ) {\n throw new LayoutConfigurationError(\n `Resource \"${resource}\" is not available in this scoped component`,\n );\n }\n\n return { ...entry, props: props ?? {} };\n }\n\n Object.assign(createComponent, {\n setProps: createComponentSetProps,\n });\n\n const scopedExtras: {\n createComponent: typeof createComponent;\n createResourceComponents: typeof createResourceComponents;\n forResource: typeof scopedForResource;\n makeComposable?: (options: Record<string, unknown>) => unknown;\n resources: undefined;\n } = {\n createComponent,\n createResourceComponents,\n forResource: scopedForResource,\n resources: undefined,\n };\n\n if (createMakeComposableLayout) {\n const makeComposableLayout = createMakeComposableLayout();\n\n scopedExtras.makeComposable = (options) => {\n const resource = options.resource as LayoutResourceKey<Resources>;\n\n return makeComposableLayout({\n ...options,\n name: options.name ?? defaultNames.get(resource),\n });\n };\n }\n\n return Object.assign(scopedCreateResourceLayout, scopedExtras);\n }) as unknown as CreateResourceLayoutForResourcesFn<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"create-for-resources.mjs","names":[],"sources":["../../../src/create-config/for-resources/create-for-resources.ts"],"sourcesContent":["import {\n createScopedLazyContent,\n scopedLazySymbol,\n type LazyEnvironment,\n type ScopedLazyContent,\n} from '../../lazy/scoped-content';\nimport { withLazyHandle } from '../../lazy/inspection';\nimport type { LazyHandle } from '../../lazy/types';\nimport {\n createContext,\n createElement,\n type ComponentType,\n type JSX,\n useContext,\n} from 'react';\nimport type { ComposableComponents } from '@jfdevelops/react-layout-composables';\nimport {\n type AnyBuiltPropDefinition,\n validateProps,\n} from '@jfdevelops/react-layout-validator';\nimport type { InPropsDefinition, InPropsObject } from '../../props';\nimport type { LayoutResourceKey, ResourceDefinition } from '../../resource';\nimport { capitalize } from '../../utils/capitalize';\nimport { LayoutConfigurationError } from '../../errors';\nimport type { LayoutIncludeProps } from '../define-layout';\nimport type {\n CapitalizedResource,\n ResourcesLayoutName,\n} from './resource-selection';\nimport type { CreateResourceLayoutForResourcesFn } from './scoped-layout';\nimport {\n isRenderableComponentType,\n reservedScopedComponentNames,\n resolveScopedRenderResult,\n type ScopedRenderResult,\n withScopedCompoundStatics,\n} from './scoped-render';\n\ntype CreateForResourcesOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = {\n lazyEnvironment?: LazyEnvironment;\n createLayoutForResource: (\n defaultName: string | undefined,\n resource: LayoutResourceKey<Resources>,\n ) => unknown;\n createMakeComposableLayout?: () => (\n options: Record<string, unknown>,\n ) => unknown;\n createResourceLayout: (options: Record<string, unknown>) => unknown;\n getComponentPropDefinitions: (\n resource: LayoutResourceKey<Resources>,\n ) => Record<string, AnyBuiltPropDefinition>;\n};\n\nexport function createForResources<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n IncludeProps extends LayoutIncludeProps<Resources, InProps, Composables>,\n CustomProps extends InPropsObject,\n>({\n createLayoutForResource,\n createMakeComposableLayout,\n createResourceLayout,\n getComponentPropDefinitions,\n lazyEnvironment,\n}: CreateForResourcesOptions<Resources>) {\n return ((...resourcesOrOptions: Array<unknown>) => {\n const firstArgument = resourcesOrOptions[0];\n let resourceOptions: Array<{\n resource: LayoutResourceKey<Resources>;\n name?:\n | string\n | ((\n resource: CapitalizedResource<LayoutResourceKey<Resources>>,\n ) => string);\n }>;\n\n if (typeof firstArgument === 'string') {\n resourceOptions = resourcesOrOptions.map((resource) => ({\n resource: resource as LayoutResourceKey<Resources>,\n }));\n } else if (\n firstArgument !== null &&\n typeof firstArgument === 'object' &&\n 'resources' in firstArgument &&\n Array.isArray(firstArgument.resources)\n ) {\n const { name, resources } = firstArgument as {\n name?: ResourcesLayoutName<LayoutResourceKey<Resources>>;\n resources: Array<LayoutResourceKey<Resources>>;\n };\n resourceOptions = resources.map((resource) => ({\n name: typeof name === 'function' ? name : name?.[resource],\n resource,\n }));\n } else {\n resourceOptions = Object.entries(firstArgument ?? {}).map(\n ([resource, options]) => ({\n ...(options as {\n name?:\n | string\n | ((\n resource: CapitalizedResource<LayoutResourceKey<Resources>>,\n ) => string);\n }),\n resource: resource as LayoutResourceKey<Resources>,\n }),\n );\n }\n\n const defaultNames = new Map(\n resourceOptions.map(({ name, resource }) => [\n resource,\n typeof name === 'function'\n ? name(\n capitalize(resource) as CapitalizedResource<\n LayoutResourceKey<Resources>\n >,\n )\n : name,\n ]),\n );\n\n function scopedCreateResourceLayout(options: Record<string, unknown>) {\n const resource = options.resource as LayoutResourceKey<Resources>;\n\n return createResourceLayout({\n ...options,\n name: options.name ?? defaultNames.get(resource),\n });\n }\n\n function scopedForResource(options: {\n name?: string;\n resource: LayoutResourceKey<Resources>;\n }) {\n return createLayoutForResource(\n options.name ?? defaultNames.get(options.resource),\n options.resource,\n );\n }\n\n type ScopedComponentRenderFn = (\n props: Record<string, unknown>,\n components: Record<string, (props?: never) => JSX.Element>,\n ) => ScopedRenderResult;\n\n type ScopedResourceScopedComponentDefinition = {\n props?: Record<string, AnyBuiltPropDefinition>;\n [scopedLazySymbol]?: LazyHandle;\n } & ScopedLazyContent<ScopedComponentRenderFn>;\n\n type ScopedComponentEntry = {\n [option: string]: unknown;\n name?: string;\n props?: CreateComponentPropsBag;\n components?: Record<string, ScopedResourceScopedComponentDefinition>;\n render: ScopedComponentRenderFn;\n [scopedLazySymbol]?: LazyHandle;\n };\n\n type CreateComponentPropsBag = {\n include?: Record<string, true | 'optional'>;\n custom?: Record<string, AnyBuiltPropDefinition>;\n defined?: Record<string, unknown>;\n };\n\n function normalizeContent<\n T extends {\n render?: ScopedComponentRenderFn;\n lazy?: unknown;\n fallback?: React.ReactNode;\n [scopedLazySymbol]?: LazyHandle;\n },\n >(\n definition: T,\n resource: string,\n label: string,\n ): T & {\n render: ScopedComponentRenderFn;\n [scopedLazySymbol]?: LazyHandle;\n } {\n if (definition.lazy !== undefined && definition.render !== undefined)\n throw new LayoutConfigurationError(\n `Scoped content \"${label}\" must define render or lazy, never both`,\n );\n if (definition[scopedLazySymbol])\n return definition as T & {\n render: ScopedComponentRenderFn;\n [scopedLazySymbol]?: LazyHandle;\n };\n if (definition.lazy === undefined) {\n if (typeof definition.render !== 'function')\n throw new LayoutConfigurationError(\n `Scoped content \"${label}\" requires render or lazy`,\n );\n return definition as T & {\n render: ScopedComponentRenderFn;\n [scopedLazySymbol]?: LazyHandle;\n };\n }\n const Content = createScopedLazyContent(\n definition as Parameters<typeof createScopedLazyContent>[0],\n resource,\n label,\n lazyEnvironment,\n );\n const result = {\n ...definition,\n lazy: undefined,\n render: (\n callProps: Record<string, unknown>,\n context: Record<string, (props?: never) => JSX.Element>,\n ) => createElement(Content, { callProps, context }),\n [scopedLazySymbol]: Content,\n };\n return withLazyHandle(result, Content) as T & {\n render: ScopedComponentRenderFn;\n [scopedLazySymbol]?: LazyHandle;\n };\n }\n\n function aggregateHandle(handles: LazyHandle[]): LazyHandle {\n let imports: Promise<void>[] = [];\n let pending: Promise<void> | undefined;\n return {\n preload() {\n const next = handles.map((handle) => handle.preload());\n if (\n !pending ||\n next.some((promise, index) => promise !== imports[index])\n ) {\n imports = next;\n pending = Promise.all(next).then(() => undefined);\n }\n return pending;\n },\n get status() {\n if (handles.some((handle) => handle.status === 'error'))\n return 'error';\n if (handles.some((handle) => handle.status === 'loading'))\n return 'loading';\n if (handles.some((handle) => handle.status === 'unresolved'))\n return 'unresolved';\n return 'resolved';\n },\n };\n }\n\n function mergeCreateComponentProps(\n ...bags: Array<CreateComponentPropsBag | undefined>\n ): CreateComponentPropsBag {\n const include: Record<string, true | 'optional'> = {};\n const custom: Record<string, AnyBuiltPropDefinition> = {};\n\n for (const bag of bags) {\n Object.assign(include, bag?.include);\n Object.assign(custom, bag?.custom);\n\n for (const key of Object.keys(bag?.defined ?? {})) {\n include[key] = true;\n }\n }\n\n return { include, custom };\n }\n\n function createComponent(componentOptions: {\n props?: {\n include?: Record<string, true | 'optional'>;\n custom?: Record<string, AnyBuiltPropDefinition>;\n };\n resources?: Record<string, ScopedComponentEntry>;\n render?: ScopedComponentRenderFn;\n lazy?: Parameters<typeof createScopedLazyContent>[0]['lazy'];\n fallback?: React.ReactNode;\n }) {\n const mergedProps = mergeCreateComponentProps(\n componentOptions.props,\n ...Object.values(componentOptions.resources ?? {}).map(\n (entry) => entry.props,\n ),\n );\n const include = mergedProps.include ?? {};\n const custom = mergedProps.custom ?? {};\n const selectedResources = new Set(\n resourceOptions.map(({ resource }) => resource),\n );\n const topLevelContent = new Map(\n [...selectedResources].map((resource) => [\n resource,\n normalizeContent(componentOptions, resource, `${resource}:content`),\n ]),\n );\n const componentPropsContext = createContext<\n Record<string, unknown> | undefined\n >(undefined);\n const definedEntries = new Map<\n LayoutResourceKey<Resources>,\n ScopedComponentEntry\n >();\n\n for (const [key, entry] of Object.entries(\n componentOptions.resources ?? {},\n )) {\n const resource = key as LayoutResourceKey<Resources>;\n\n if (!selectedResources.has(resource)) {\n throw new LayoutConfigurationError(\n `Resource \"${key}\" is not available in this scoped component`,\n );\n }\n\n const normalized = normalizeContent(entry, resource, resource);\n normalized.components = Object.fromEntries(\n Object.entries(entry.components ?? {}).map(([name, definition]) => [\n name,\n normalizeContent(definition, resource, `${resource}.${name}`),\n ]),\n );\n definedEntries.set(resource, normalized);\n }\n\n /** Resolved scoped components, per resource. */\n const resourceScopedComponents = new Map<\n LayoutResourceKey<Resources>,\n Record<string, (props?: never) => JSX.Element>\n >();\n const contextResources = new Map<string, LayoutResourceKey<Resources>>();\n const renderContext: Record<string, (props: never) => JSX.Element> =\n Object.fromEntries(\n [...definedEntries].map(([resource, entry]) => {\n const contextKey = capitalize(resource);\n\n if (contextKey === 'Root') {\n throw new LayoutConfigurationError(\n `Resource \"${resource}\" maps to the reserved render context key \"Root\"`,\n );\n }\n\n const existingResource = contextResources.get(contextKey);\n\n if (existingResource !== undefined) {\n throw new LayoutConfigurationError(\n `Resources \"${existingResource}\" and \"${resource}\" both map to render context key \"${contextKey}\"`,\n );\n }\n\n contextResources.set(contextKey, resource);\n\n /**\n * Built once per resource so every scoped component keeps a stable\n * identity, and shared by the resource render, the render context,\n * and any component bound through `asHOF()`.\n */\n const scopedComponents: Record<\n string,\n (props?: never) => JSX.Element\n > = {};\n\n for (const [name, definition] of Object.entries(\n entry.components ?? {},\n )) {\n if (reservedScopedComponentNames.has(name)) {\n throw new LayoutConfigurationError(\n `Scoped component \"${name}\" for resource \"${resource}\" uses a reserved name`,\n );\n }\n\n const ownPropDefinitions = definition.props ?? {};\n // Last call-site own-props / returned component for this scoped\n // entry. Compound statics re-run `render` with these so\n // `<DataTable variant=\"b\" />` then `<DataTable.Loading />` sees \"b\".\n let cachedOwnProps: Record<string, unknown> = {};\n let cachedReturnedComponent:\n | ComponentType<Record<string, unknown>>\n | undefined;\n\n function ScopedComponent(ownProps?: Record<string, unknown>) {\n const componentProps = useContext(componentPropsContext);\n\n if (componentProps === undefined) {\n throw new LayoutConfigurationError(\n `Scoped component \"${name}\" must be rendered inside its scoped component`,\n );\n }\n\n const resolvedOwnProps = ownProps ?? {};\n cachedOwnProps = resolvedOwnProps;\n\n validateProps(ownPropDefinitions, resolvedOwnProps, {\n layoutName:\n entry.name ??\n defaultNames.get(resource) ??\n capitalize(resource),\n resource,\n });\n\n // Mount a returned component type with call-site props; pass\n // nodes (elements, portals, null) through unchanged.\n const result = definition.render!(\n { ...componentProps, ...resolvedOwnProps, resource },\n scopedComponents,\n );\n\n if (isRenderableComponentType(result)) {\n cachedReturnedComponent = result as ComponentType<\n Record<string, unknown>\n >;\n }\n\n return resolveScopedRenderResult(result, resolvedOwnProps);\n }\n\n // Types expose compound statics from the returned component\n // (`DataTable.Loading`); attach matching runtime wrappers.\n if (definition[scopedLazySymbol])\n withLazyHandle(ScopedComponent, definition[scopedLazySymbol]);\n scopedComponents[name] = withScopedCompoundStatics(\n ScopedComponent,\n (staticName) => {\n function CompoundStatic(ownProps?: Record<string, unknown>) {\n const componentProps = useContext(componentPropsContext);\n\n if (componentProps === undefined) {\n throw new LayoutConfigurationError(\n `Scoped component \"${name}.${staticName}\" must be rendered inside its scoped component`,\n );\n }\n\n // Prefer the component from the last parent call (same\n // closure as that call's own-props). Fall back to re-running\n // render with cached parent props when needed.\n let result: unknown = cachedReturnedComponent;\n\n if (!isRenderableComponentType(result)) {\n result = definition.render!(\n {\n ...componentProps,\n ...cachedOwnProps,\n resource,\n },\n scopedComponents,\n );\n }\n\n if (!isRenderableComponentType(result)) {\n throw new LayoutConfigurationError(\n `Scoped component \"${name}\" must return a component type to use static \"${staticName}\"`,\n );\n }\n\n const staticComponent = (\n result as ComponentType<Record<string, unknown>> &\n Record<string, unknown>\n )[staticName];\n\n if (!isRenderableComponentType(staticComponent)) {\n throw new LayoutConfigurationError(\n `Scoped component \"${name}\" has no component static \"${staticName}\"`,\n );\n }\n\n // Loading's props — those mount the static itself.\n return createElement(staticComponent, ownProps ?? {});\n }\n\n CompoundStatic.displayName = `${name}.${staticName}`;\n return CompoundStatic;\n },\n ) as (props?: never) => JSX.Element;\n }\n\n resourceScopedComponents.set(resource, scopedComponents);\n\n function ResourceRender(ownProps?: Record<string, unknown>) {\n const componentProps = useContext(componentPropsContext);\n\n if (componentProps === undefined) {\n throw new LayoutConfigurationError(\n `Render context component \"${contextKey}\" must be rendered inside its scoped component`,\n );\n }\n\n // Call-site props on `context.Users({ title, heading })` merge into\n // the resource render props and mount a returned component type.\n const callProps = { ...componentProps, ...ownProps, resource };\n return resolveScopedRenderResult(\n entry.render(callProps, scopedComponents),\n ownProps,\n );\n }\n\n return [\n contextKey,\n withLazyHandle(\n Object.assign(ResourceRender, scopedComponents),\n aggregateHandle([\n ...(entry[scopedLazySymbol] ? [entry[scopedLazySymbol]] : []),\n ...Object.values(entry.components ?? {}).flatMap(\n (definition) =>\n definition[scopedLazySymbol]\n ? [definition[scopedLazySymbol]]\n : [],\n ),\n ]),\n ),\n ];\n }),\n );\n\n /**\n * Layouts are created once per resource and cached. Creating one during\n * render would hand React a new component type on every pass, remounting\n * the whole subtree.\n */\n const roots = new Map<\n LayoutResourceKey<Resources>,\n (props: Record<string, unknown>) => JSX.Element\n >();\n\n function Root(rootProps: Record<string, unknown>) {\n const componentProps = useContext(componentPropsContext);\n\n if (componentProps === undefined) {\n throw new LayoutConfigurationError(\n 'Render context component \"Root\" must be rendered inside its scoped component',\n );\n }\n\n const resource =\n componentProps.resource as LayoutResourceKey<Resources>;\n let root = roots.get(resource);\n\n if (root === undefined) {\n const entry = definedEntries.get(resource);\n\n if (entry === undefined) {\n throw new LayoutConfigurationError(\n `Render context component \"Root\" requires a \"resources.${resource}\" entry to build the layout for resource \"${resource}\"`,\n );\n }\n\n // Layout option values come from the outer component call site\n // (`<Directory title=\"…\" />`), not from the resource entry.\n const availableDefinitions = getComponentPropDefinitions(resource);\n const layoutOptions: Record<string, unknown> = {};\n const defined = entry.props?.defined ?? {};\n\n for (const key of Object.keys(availableDefinitions)) {\n if (key in defined) {\n layoutOptions[key] = defined[key];\n }\n\n const capitalized = capitalize(key);\n if (capitalized in defined) {\n layoutOptions[capitalized] = defined[capitalized];\n }\n\n if (key in componentProps) {\n layoutOptions[key] = componentProps[key];\n }\n\n if (capitalized in componentProps) {\n layoutOptions[capitalized] = componentProps[capitalized];\n }\n }\n\n root = scopedCreateResourceLayout({\n ...layoutOptions,\n namespace: false,\n name:\n entry.name ?? defaultNames.get(resource) ?? capitalize(resource),\n resource,\n }) as (props: Record<string, unknown>) => JSX.Element;\n roots.set(resource, root);\n }\n\n const entry = definedEntries.get(resource);\n const definedCustom: Record<string, unknown> = {};\n const forwardedRootProps: Record<string, unknown> = {};\n\n for (const key of Object.keys(getComponentPropDefinitions(resource))) {\n if (key in componentProps) {\n forwardedRootProps[key] = componentProps[key];\n }\n\n const capitalized = capitalize(key);\n if (capitalized in componentProps) {\n forwardedRootProps[capitalized] = componentProps[capitalized];\n }\n }\n\n for (const [key, value] of Object.entries(\n entry?.props?.defined ?? {},\n )) {\n if (key in custom) {\n definedCustom[key] = value;\n }\n }\n\n return createElement(root, {\n ...forwardedRootProps,\n ...definedCustom,\n ...rootProps,\n });\n }\n\n renderContext.Root = Root;\n\n function Component(componentProps: Record<string, unknown>) {\n const componentResource =\n componentProps.resource as LayoutResourceKey<Resources>;\n\n if (!selectedResources.has(componentResource)) {\n throw new LayoutConfigurationError(\n `Resource \"${componentResource}\" is not available in this scoped component`,\n );\n }\n\n const defined =\n definedEntries.get(componentResource)?.props?.defined ?? {};\n const resolvedComponentProps = { ...defined, ...componentProps };\n const availableDefinitions =\n getComponentPropDefinitions(componentResource);\n const definitionsToValidate: Record<string, AnyBuiltPropDefinition> =\n {};\n\n for (const [key, inclusion] of Object.entries(include)) {\n const definition = availableDefinitions[key];\n\n if (!definition) {\n continue;\n }\n\n // Keep declared keys as-is — do not capitalize JSX.Element props.\n if (inclusion === true || key in resolvedComponentProps) {\n definitionsToValidate[key] = definition;\n }\n }\n\n for (const [key, definition] of Object.entries(custom)) {\n if (key === 'children' || key === 'resource') {\n continue;\n }\n\n definitionsToValidate[key] = definition;\n }\n\n validateProps(definitionsToValidate, resolvedComponentProps, {\n layoutName:\n definedEntries.get(componentResource)?.name ??\n defaultNames.get(componentResource) ??\n capitalize(componentResource),\n resource: componentResource,\n });\n\n // Top-level render may return a component type; mount it with the full\n // component props (include/custom + inferred return-type props).\n return createElement(\n componentPropsContext.Provider,\n { value: resolvedComponentProps },\n resolveScopedRenderResult(\n topLevelContent\n .get(componentResource)!\n .render(\n resolvedComponentProps,\n renderContext as Record<string, (props?: never) => JSX.Element>,\n ),\n resolvedComponentProps,\n ),\n );\n }\n\n /**\n * Bound components are created once per resource and cached. Returning a\n * fresh component from the factory would hand React a new component type\n * whenever the caller rebinds, remounting the subtree.\n */\n const boundComponents = new Map<\n LayoutResourceKey<Resources>,\n (props: Record<string, unknown>) => JSX.Element\n >();\n\n function bindResource(resource: LayoutResourceKey<Resources>) {\n if (!selectedResources.has(resource)) {\n throw new LayoutConfigurationError(\n `Resource \"${resource}\" is not available in this scoped component`,\n );\n }\n\n let boundComponent = boundComponents.get(resource);\n\n if (boundComponent === undefined) {\n boundComponent = Object.assign(\n (boundProps: Record<string, unknown>) =>\n createElement(Component, { ...boundProps, resource }),\n {\n displayName: `ScopedResourceComponent(${resource})`,\n props: undefined,\n resource: undefined,\n },\n resourceScopedComponents.get(resource) ?? {},\n );\n if (createMakeComposableLayout) {\n Object.assign(boundComponent, {\n makeComposable: (options: Record<string, unknown> = {}) =>\n scopedExtras.makeComposable?.({ ...options, resource }),\n });\n }\n const renderResource = renderContext[\n capitalize(resource)\n ] as unknown as LazyHandle;\n const ownContent = topLevelContent.get(resource)?.[scopedLazySymbol];\n withLazyHandle(\n boundComponent,\n aggregateHandle([\n ...(renderResource ? [renderResource] : []),\n ...(ownContent ? [ownContent] : []),\n ]),\n );\n boundComponents.set(resource, boundComponent);\n }\n\n return boundComponent;\n }\n\n function asHOF() {\n return bindResource;\n }\n\n withLazyHandle(\n Component,\n aggregateHandle([\n ...(Object.values(renderContext).filter(\n (value) => 'preload' in value,\n ) as unknown as LazyHandle[]),\n ...[...topLevelContent.values()].flatMap((entry) =>\n entry[scopedLazySymbol] ? [entry[scopedLazySymbol]] : [],\n ),\n ]),\n );\n return Object.assign(Component, {\n asHOF,\n displayName: 'ScopedResourceComponent',\n props: undefined,\n });\n }\n\n function createComponentSetProps(baseProps: CreateComponentPropsBag) {\n function createWithProps(componentOptions: {\n props?: CreateComponentPropsBag;\n resources?: Record<string, ScopedComponentEntry>;\n render: (\n props: Record<string, unknown>,\n context: Record<string, (props: never) => JSX.Element>,\n ) => ScopedRenderResult;\n }) {\n return createComponent({\n ...componentOptions,\n props: mergeCreateComponentProps(baseProps, componentOptions.props),\n });\n }\n\n createWithProps.createResourceComponents = createResourceComponents;\n\n return createWithProps;\n }\n\n function createResourceComponents(options: {\n resource: LayoutResourceKey<Resources>;\n props?: CreateComponentPropsBag;\n name?: string;\n components?: Record<string, ScopedResourceScopedComponentDefinition>;\n render?: ScopedComponentRenderFn;\n lazy?: Parameters<typeof createScopedLazyContent>[0]['lazy'];\n fallback?: React.ReactNode;\n }) {\n const { resource, props, ...entry } = options;\n\n if (\n !resourceOptions.some(\n (resourceOption) => resourceOption.resource === resource,\n )\n ) {\n throw new LayoutConfigurationError(\n `Resource \"${resource}\" is not available in this scoped component`,\n );\n }\n\n const normalized = normalizeContent(entry, resource, String(resource));\n const components = Object.fromEntries(\n Object.entries(normalized.components ?? {}).map(\n ([name, definition]) => [\n name,\n normalizeContent(definition, resource, `${resource}.${name}`),\n ],\n ),\n );\n const result = { ...normalized, components, props: props ?? {} };\n return withLazyHandle(\n result,\n aggregateHandle([\n ...(normalized[scopedLazySymbol]\n ? [normalized[scopedLazySymbol]]\n : []),\n ...Object.values(components).flatMap((definition) =>\n definition[scopedLazySymbol] ? [definition[scopedLazySymbol]] : [],\n ),\n ]),\n );\n }\n\n Object.assign(createComponent, {\n setProps: createComponentSetProps,\n });\n\n const scopedExtras: {\n createComponent: typeof createComponent;\n createResourceComponents: typeof createResourceComponents;\n forResource: typeof scopedForResource;\n makeComposable?: (options: Record<string, unknown>) => unknown;\n resources: undefined;\n } = {\n createComponent,\n createResourceComponents,\n forResource: scopedForResource,\n resources: undefined,\n };\n\n if (createMakeComposableLayout) {\n const makeComposableLayout = createMakeComposableLayout();\n\n scopedExtras.makeComposable = (options) => {\n const resource = options.resource as LayoutResourceKey<Resources>;\n\n return makeComposableLayout({\n ...options,\n name: options.name ?? defaultNames.get(resource),\n });\n };\n }\n\n return Object.assign(scopedCreateResourceLayout, scopedExtras);\n }) as unknown as CreateResourceLayoutForResourcesFn<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scoped-render.cjs","names":[],"sources":["../../../src/create-config/for-resources/scoped-render.ts"],"sourcesContent":["import {\n createElement,\n isValidElement,\n type ComponentType,\n type JSX,\n type ReactNode,\n} from 'react';\n\n/**\n * Names a scoped component cannot use. Scoped components are attached to\n * function objects, so they collide with the component's own statics and with\n * non-writable `Function.prototype` properties. `__proto__` is reserved so\n * assignment cannot hit the prototype setter on a normal object.\n */\nexport const reservedScopedComponentNames = new Set([\n '__proto__',\n 'apply',\n 'arguments',\n 'bind',\n 'call',\n 'caller',\n 'displayName',\n 'length',\n 'name',\n 'props',\n 'prototype',\n 'resource',\n]);\n\n/**\n * Values a createComponent / scoped-component `render` may return.\n *\n * Alongside rendered nodes, a component type is allowed — the type constituent\n * of a React element — so factories like `createDataTable(columns)` can be\n * returned directly and mounted with the call-site props.\n *\n * At runtime, `resolveScopedRenderResult` distinguishes component types from\n * nodes (including portals). Getting that wrong mounts a portal via\n * `createElement` and blows up with an invalid-element-type error.\n */\n// Returned components declare their own props; a concrete props parameter would\n// be contravariant and reject the factories callers actually return.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- see above\nexport type ScopedRenderResult = ReactNode | ComponentType<any>;\n\n/**\n * `$$typeof` tags for object component wrappers that `createElement` accepts\n * as `type` (forwardRef, memo, lazy).\n *\n * Do not treat \"any object with `$$typeof`\" as a component: portals also have\n * `$$typeof` (`Symbol.for('react.portal')`) and `isValidElement(portal)` is\n * false, so a naive check would mis-classify them.\n */\nconst reactForwardRefType = Symbol.for('react.forward_ref');\nconst reactMemoType = Symbol.for('react.memo');\nconst reactLazyType = Symbol.for('react.lazy');\n\n/**\n * True when `value` can be passed as the `type` argument to `createElement`.\n *\n * Functions always qualify. Object wrappers qualify only for the forwardRef /\n * memo / lazy tags above — not portals or other React nodes that happen to\n * carry `$$typeof`.\n */\nexport function isRenderableComponentType(\n value: unknown,\n): value is ComponentType<Record<string, unknown>> {\n if (typeof value === 'function') {\n return true;\n }\n\n if (\n typeof value !== 'object' ||\n value === null ||\n Array.isArray(value) ||\n isValidElement(value) ||\n !('$$typeof' in value)\n ) {\n return false;\n }\n\n const typeTag = (value as { $$typeof: unknown }).$$typeof;\n\n return (\n typeTag === reactForwardRefType ||\n typeTag === reactMemoType ||\n typeTag === reactLazyType\n );\n}\n\n/**\n * If `render` returned a component type, mount it with `props`; otherwise\n * return the node as-is (elements, portals, null, etc.).\n */\nexport function resolveScopedRenderResult(\n result: ScopedRenderResult,\n props: Record<string, unknown> = {},\n): JSX.Element {\n if (isRenderableComponentType(result)) {\n return createElement(result, props);\n }\n\n return result as JSX.Element;\n}\n\n/**\n * Runtime counterpart of `ScopedComponentCompoundStaticKey` — keys that must\n * not be treated as compound component statics on a scoped wrapper.\n */\nconst reservedScopedCompoundStaticKeys = new Set<PropertyKey>([\n 'apply',\n 'arguments',\n 'bind',\n 'call',\n 'caller',\n 'childContextTypes',\n 'contextTypes',\n 'defaultProps',\n 'displayName',\n 'length',\n 'name',\n 'propTypes',\n 'prototype',\n 'toLocaleString',\n 'toString',\n 'valueOf',\n '$$typeof',\n]);\n\ntype ScopedComponentWrapper = ((\n props?: Record<string, unknown>,\n) => JSX.Element) &\n Record<string, unknown>;\n\n/**\n * Exposes compound statics (e.g. `DataTable.Loading`) on a scoped wrapper so\n * runtime matches `ScopedComponentCompoundStatics`.\n *\n * Why a Proxy: JSX reads `components.DataTable.Loading` while building the\n * element tree — before `DataTable` itself renders — so statics cannot be\n * copied only after the first `render` call. Property access lazily creates a\n * stable wrapper component that re-runs the scoped `render` under context and\n * mounts the matching static from the returned component type.\n */\nexport function withScopedCompoundStatics(\n wrapper: (props?: Record<string, unknown>) => JSX.Element,\n createCompoundStatic: (\n staticName: string,\n ) => (ownProps?: Record<string, unknown>) => JSX.Element,\n): ScopedComponentWrapper {\n return new Proxy(wrapper as ScopedComponentWrapper, {\n get(target, property, receiver) {\n if (\n typeof property === 'symbol' ||\n reservedScopedCompoundStaticKeys.has(property) ||\n property in target\n ) {\n return Reflect.get(target, property, receiver);\n }\n\n // Cache on the target so repeated `.Loading` access keeps one identity.\n const CompoundStatic = createCompoundStatic(property);\n target[property] = CompoundStatic;\n return CompoundStatic;\n },\n });\n}\n"],"mappings":";;;;;;;;;AAcA,MAAa,+BAA+B,IAAI,IAAI;CAClD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;;;;;;;;;AA0BD,MAAM,sBAAsB,OAAO,IAAI,mBAAmB;AAC1D,MAAM,gBAAgB,OAAO,IAAI,YAAY;AAC7C,MAAM,gBAAgB,OAAO,IAAI,YAAY;;;;;;;;AAS7C,SAAgB,0BACd,OACiD;CACjD,IAAI,OAAO,UAAU,YACnB,OAAO;CAGT,IACE,OAAO,UAAU,YACjB,UAAU,QACV,MAAM,QAAQ,KAAK,+BACJ,KAAK,KACpB,EAAE,cAAc,QAEhB,OAAO;CAGT,MAAM,UAAW,MAAgC;CAEjD,OACE,YAAY,uBACZ,YAAY,iBACZ,YAAY;AAEhB;;;;;AAMA,SAAgB,0BACd,QACA,QAAiC,CAAC,GACrB;CACb,IAAI,0BAA0B,MAAM,GAClC,gCAAqB,QAAQ,KAAK;CAGpC,OAAO;AACT;;;;;AAMA,MAAM,mCAAmC,IAAI,IAAiB;CAC5D;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;;;;;;;;;;;AAiBD,SAAgB,0BACd,SACA,sBAGwB;CACxB,OAAO,IAAI,MAAM,SAAmC,EAClD,IAAI,QAAQ,UAAU,UAAU;EAC9B,IACE,OAAO,aAAa,YACpB,iCAAiC,IAAI,QAAQ,KAC7C,YAAY,QAEZ,OAAO,QAAQ,IAAI,QAAQ,UAAU,QAAQ;EAI/C,MAAM,iBAAiB,qBAAqB,QAAQ;EACpD,OAAO,YAAY;EACnB,OAAO;CACT,EACF,CAAC;AACH"}
|
|
1
|
+
{"version":3,"file":"scoped-render.cjs","names":[],"sources":["../../../src/create-config/for-resources/scoped-render.ts"],"sourcesContent":["import {\n createElement,\n isValidElement,\n type ComponentType,\n type JSX,\n type ReactNode,\n} from 'react';\n\n/**\n * Names a scoped component cannot use. Scoped components are attached to\n * function objects, so they collide with the component's own statics and with\n * non-writable `Function.prototype` properties. `__proto__` is reserved so\n * assignment cannot hit the prototype setter on a normal object.\n */\nexport const reservedScopedComponentNames = new Set([\n '__proto__',\n 'apply',\n 'arguments',\n 'bind',\n 'call',\n 'caller',\n 'displayName',\n 'length',\n 'makeComposable',\n 'name',\n 'props',\n 'prototype',\n 'resource',\n]);\n\n/**\n * Values a createComponent / scoped-component `render` may return.\n *\n * Alongside rendered nodes, a component type is allowed — the type constituent\n * of a React element — so factories like `createDataTable(columns)` can be\n * returned directly and mounted with the call-site props.\n *\n * At runtime, `resolveScopedRenderResult` distinguishes component types from\n * nodes (including portals). Getting that wrong mounts a portal via\n * `createElement` and blows up with an invalid-element-type error.\n */\n// Returned components declare their own props; a concrete props parameter would\n// be contravariant and reject the factories callers actually return.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- see above\nexport type ScopedRenderResult = ReactNode | ComponentType<any>;\n\n/**\n * `$$typeof` tags for object component wrappers that `createElement` accepts\n * as `type` (forwardRef, memo, lazy).\n *\n * Do not treat \"any object with `$$typeof`\" as a component: portals also have\n * `$$typeof` (`Symbol.for('react.portal')`) and `isValidElement(portal)` is\n * false, so a naive check would mis-classify them.\n */\nconst reactForwardRefType = Symbol.for('react.forward_ref');\nconst reactMemoType = Symbol.for('react.memo');\nconst reactLazyType = Symbol.for('react.lazy');\n\n/**\n * True when `value` can be passed as the `type` argument to `createElement`.\n *\n * Functions always qualify. Object wrappers qualify only for the forwardRef /\n * memo / lazy tags above — not portals or other React nodes that happen to\n * carry `$$typeof`.\n */\nexport function isRenderableComponentType(\n value: unknown,\n): value is ComponentType<Record<string, unknown>> {\n if (typeof value === 'function') {\n return true;\n }\n\n if (\n typeof value !== 'object' ||\n value === null ||\n Array.isArray(value) ||\n isValidElement(value) ||\n !('$$typeof' in value)\n ) {\n return false;\n }\n\n const typeTag = (value as { $$typeof: unknown }).$$typeof;\n\n return (\n typeTag === reactForwardRefType ||\n typeTag === reactMemoType ||\n typeTag === reactLazyType\n );\n}\n\n/**\n * If `render` returned a component type, mount it with `props`; otherwise\n * return the node as-is (elements, portals, null, etc.).\n */\nexport function resolveScopedRenderResult(\n result: ScopedRenderResult,\n props: Record<string, unknown> = {},\n): JSX.Element {\n if (isRenderableComponentType(result)) {\n return createElement(result, props);\n }\n\n return result as JSX.Element;\n}\n\n/**\n * Runtime counterpart of `ScopedComponentCompoundStaticKey` — keys that must\n * not be treated as compound component statics on a scoped wrapper.\n */\nconst reservedScopedCompoundStaticKeys = new Set<PropertyKey>([\n 'apply',\n 'arguments',\n 'bind',\n 'call',\n 'caller',\n 'childContextTypes',\n 'contextTypes',\n 'defaultProps',\n 'displayName',\n 'length',\n 'name',\n 'propTypes',\n 'prototype',\n 'toLocaleString',\n 'toString',\n 'valueOf',\n '$$typeof',\n]);\n\ntype ScopedComponentWrapper = ((\n props?: Record<string, unknown>,\n) => JSX.Element) &\n Record<string, unknown>;\n\n/**\n * Exposes compound statics (e.g. `DataTable.Loading`) on a scoped wrapper so\n * runtime matches `ScopedComponentCompoundStatics`.\n *\n * Why a Proxy: JSX reads `components.DataTable.Loading` while building the\n * element tree — before `DataTable` itself renders — so statics cannot be\n * copied only after the first `render` call. Property access lazily creates a\n * stable wrapper component that re-runs the scoped `render` under context and\n * mounts the matching static from the returned component type.\n */\nexport function withScopedCompoundStatics(\n wrapper: (props?: Record<string, unknown>) => JSX.Element,\n createCompoundStatic: (\n staticName: string,\n ) => (ownProps?: Record<string, unknown>) => JSX.Element,\n): ScopedComponentWrapper {\n return new Proxy(wrapper as ScopedComponentWrapper, {\n get(target, property, receiver) {\n if (\n typeof property === 'symbol' ||\n reservedScopedCompoundStaticKeys.has(property) ||\n property in target\n ) {\n return Reflect.get(target, property, receiver);\n }\n\n // Cache on the target so repeated `.Loading` access keeps one identity.\n const CompoundStatic = createCompoundStatic(property);\n target[property] = CompoundStatic;\n return CompoundStatic;\n },\n });\n}\n"],"mappings":";;;;;;;;;AAcA,MAAa,+BAA+B,IAAI,IAAI;CAClD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;;;;;;;;;AA0BD,MAAM,sBAAsB,OAAO,IAAI,mBAAmB;AAC1D,MAAM,gBAAgB,OAAO,IAAI,YAAY;AAC7C,MAAM,gBAAgB,OAAO,IAAI,YAAY;;;;;;;;AAS7C,SAAgB,0BACd,OACiD;CACjD,IAAI,OAAO,UAAU,YACnB,OAAO;CAGT,IACE,OAAO,UAAU,YACjB,UAAU,QACV,MAAM,QAAQ,KAAK,+BACJ,KAAK,KACpB,EAAE,cAAc,QAEhB,OAAO;CAGT,MAAM,UAAW,MAAgC;CAEjD,OACE,YAAY,uBACZ,YAAY,iBACZ,YAAY;AAEhB;;;;;AAMA,SAAgB,0BACd,QACA,QAAiC,CAAC,GACrB;CACb,IAAI,0BAA0B,MAAM,GAClC,gCAAqB,QAAQ,KAAK;CAGpC,OAAO;AACT;;;;;AAMA,MAAM,mCAAmC,IAAI,IAAiB;CAC5D;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;;;;;;;;;;;AAiBD,SAAgB,0BACd,SACA,sBAGwB;CACxB,OAAO,IAAI,MAAM,SAAmC,EAClD,IAAI,QAAQ,UAAU,UAAU;EAC9B,IACE,OAAO,aAAa,YACpB,iCAAiC,IAAI,QAAQ,KAC7C,YAAY,QAEZ,OAAO,QAAQ,IAAI,QAAQ,UAAU,QAAQ;EAI/C,MAAM,iBAAiB,qBAAqB,QAAQ;EACpD,OAAO,YAAY;EACnB,OAAO;CACT,EACF,CAAC;AACH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scoped-render.d.cts","names":[],"sources":["../../../src/create-config/for-resources/scoped-render.ts"],"mappings":";;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"scoped-render.d.cts","names":[],"sources":["../../../src/create-config/for-resources/scoped-render.ts"],"mappings":";;;;;;;;;;;;;;KA4CY,kBAAA,GAAqB,SAAA,GAAY,aAAa"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scoped-render.d.mts","names":[],"sources":["../../../src/create-config/for-resources/scoped-render.ts"],"mappings":";;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"scoped-render.d.mts","names":[],"sources":["../../../src/create-config/for-resources/scoped-render.ts"],"mappings":";;;;;;;;;;;;;;KA4CY,kBAAA,GAAqB,SAAA,GAAY,aAAa"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scoped-render.mjs","names":[],"sources":["../../../src/create-config/for-resources/scoped-render.ts"],"sourcesContent":["import {\n createElement,\n isValidElement,\n type ComponentType,\n type JSX,\n type ReactNode,\n} from 'react';\n\n/**\n * Names a scoped component cannot use. Scoped components are attached to\n * function objects, so they collide with the component's own statics and with\n * non-writable `Function.prototype` properties. `__proto__` is reserved so\n * assignment cannot hit the prototype setter on a normal object.\n */\nexport const reservedScopedComponentNames = new Set([\n '__proto__',\n 'apply',\n 'arguments',\n 'bind',\n 'call',\n 'caller',\n 'displayName',\n 'length',\n 'name',\n 'props',\n 'prototype',\n 'resource',\n]);\n\n/**\n * Values a createComponent / scoped-component `render` may return.\n *\n * Alongside rendered nodes, a component type is allowed — the type constituent\n * of a React element — so factories like `createDataTable(columns)` can be\n * returned directly and mounted with the call-site props.\n *\n * At runtime, `resolveScopedRenderResult` distinguishes component types from\n * nodes (including portals). Getting that wrong mounts a portal via\n * `createElement` and blows up with an invalid-element-type error.\n */\n// Returned components declare their own props; a concrete props parameter would\n// be contravariant and reject the factories callers actually return.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- see above\nexport type ScopedRenderResult = ReactNode | ComponentType<any>;\n\n/**\n * `$$typeof` tags for object component wrappers that `createElement` accepts\n * as `type` (forwardRef, memo, lazy).\n *\n * Do not treat \"any object with `$$typeof`\" as a component: portals also have\n * `$$typeof` (`Symbol.for('react.portal')`) and `isValidElement(portal)` is\n * false, so a naive check would mis-classify them.\n */\nconst reactForwardRefType = Symbol.for('react.forward_ref');\nconst reactMemoType = Symbol.for('react.memo');\nconst reactLazyType = Symbol.for('react.lazy');\n\n/**\n * True when `value` can be passed as the `type` argument to `createElement`.\n *\n * Functions always qualify. Object wrappers qualify only for the forwardRef /\n * memo / lazy tags above — not portals or other React nodes that happen to\n * carry `$$typeof`.\n */\nexport function isRenderableComponentType(\n value: unknown,\n): value is ComponentType<Record<string, unknown>> {\n if (typeof value === 'function') {\n return true;\n }\n\n if (\n typeof value !== 'object' ||\n value === null ||\n Array.isArray(value) ||\n isValidElement(value) ||\n !('$$typeof' in value)\n ) {\n return false;\n }\n\n const typeTag = (value as { $$typeof: unknown }).$$typeof;\n\n return (\n typeTag === reactForwardRefType ||\n typeTag === reactMemoType ||\n typeTag === reactLazyType\n );\n}\n\n/**\n * If `render` returned a component type, mount it with `props`; otherwise\n * return the node as-is (elements, portals, null, etc.).\n */\nexport function resolveScopedRenderResult(\n result: ScopedRenderResult,\n props: Record<string, unknown> = {},\n): JSX.Element {\n if (isRenderableComponentType(result)) {\n return createElement(result, props);\n }\n\n return result as JSX.Element;\n}\n\n/**\n * Runtime counterpart of `ScopedComponentCompoundStaticKey` — keys that must\n * not be treated as compound component statics on a scoped wrapper.\n */\nconst reservedScopedCompoundStaticKeys = new Set<PropertyKey>([\n 'apply',\n 'arguments',\n 'bind',\n 'call',\n 'caller',\n 'childContextTypes',\n 'contextTypes',\n 'defaultProps',\n 'displayName',\n 'length',\n 'name',\n 'propTypes',\n 'prototype',\n 'toLocaleString',\n 'toString',\n 'valueOf',\n '$$typeof',\n]);\n\ntype ScopedComponentWrapper = ((\n props?: Record<string, unknown>,\n) => JSX.Element) &\n Record<string, unknown>;\n\n/**\n * Exposes compound statics (e.g. `DataTable.Loading`) on a scoped wrapper so\n * runtime matches `ScopedComponentCompoundStatics`.\n *\n * Why a Proxy: JSX reads `components.DataTable.Loading` while building the\n * element tree — before `DataTable` itself renders — so statics cannot be\n * copied only after the first `render` call. Property access lazily creates a\n * stable wrapper component that re-runs the scoped `render` under context and\n * mounts the matching static from the returned component type.\n */\nexport function withScopedCompoundStatics(\n wrapper: (props?: Record<string, unknown>) => JSX.Element,\n createCompoundStatic: (\n staticName: string,\n ) => (ownProps?: Record<string, unknown>) => JSX.Element,\n): ScopedComponentWrapper {\n return new Proxy(wrapper as ScopedComponentWrapper, {\n get(target, property, receiver) {\n if (\n typeof property === 'symbol' ||\n reservedScopedCompoundStaticKeys.has(property) ||\n property in target\n ) {\n return Reflect.get(target, property, receiver);\n }\n\n // Cache on the target so repeated `.Loading` access keeps one identity.\n const CompoundStatic = createCompoundStatic(property);\n target[property] = CompoundStatic;\n return CompoundStatic;\n },\n });\n}\n"],"mappings":";;;;;;;;;AAcA,MAAa,+BAA+B,IAAI,IAAI;CAClD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;;;;;;;;;AA0BD,MAAM,sBAAsB,OAAO,IAAI,mBAAmB;AAC1D,MAAM,gBAAgB,OAAO,IAAI,YAAY;AAC7C,MAAM,gBAAgB,OAAO,IAAI,YAAY;;;;;;;;AAS7C,SAAgB,0BACd,OACiD;CACjD,IAAI,OAAO,UAAU,YACnB,OAAO;CAGT,IACE,OAAO,UAAU,YACjB,UAAU,QACV,MAAM,QAAQ,KAAK,KACnB,eAAe,KAAK,KACpB,EAAE,cAAc,QAEhB,OAAO;CAGT,MAAM,UAAW,MAAgC;CAEjD,OACE,YAAY,uBACZ,YAAY,iBACZ,YAAY;AAEhB;;;;;AAMA,SAAgB,0BACd,QACA,QAAiC,CAAC,GACrB;CACb,IAAI,0BAA0B,MAAM,GAClC,OAAO,cAAc,QAAQ,KAAK;CAGpC,OAAO;AACT;;;;;AAMA,MAAM,mCAAmC,IAAI,IAAiB;CAC5D;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;;;;;;;;;;;AAiBD,SAAgB,0BACd,SACA,sBAGwB;CACxB,OAAO,IAAI,MAAM,SAAmC,EAClD,IAAI,QAAQ,UAAU,UAAU;EAC9B,IACE,OAAO,aAAa,YACpB,iCAAiC,IAAI,QAAQ,KAC7C,YAAY,QAEZ,OAAO,QAAQ,IAAI,QAAQ,UAAU,QAAQ;EAI/C,MAAM,iBAAiB,qBAAqB,QAAQ;EACpD,OAAO,YAAY;EACnB,OAAO;CACT,EACF,CAAC;AACH"}
|
|
1
|
+
{"version":3,"file":"scoped-render.mjs","names":[],"sources":["../../../src/create-config/for-resources/scoped-render.ts"],"sourcesContent":["import {\n createElement,\n isValidElement,\n type ComponentType,\n type JSX,\n type ReactNode,\n} from 'react';\n\n/**\n * Names a scoped component cannot use. Scoped components are attached to\n * function objects, so they collide with the component's own statics and with\n * non-writable `Function.prototype` properties. `__proto__` is reserved so\n * assignment cannot hit the prototype setter on a normal object.\n */\nexport const reservedScopedComponentNames = new Set([\n '__proto__',\n 'apply',\n 'arguments',\n 'bind',\n 'call',\n 'caller',\n 'displayName',\n 'length',\n 'makeComposable',\n 'name',\n 'props',\n 'prototype',\n 'resource',\n]);\n\n/**\n * Values a createComponent / scoped-component `render` may return.\n *\n * Alongside rendered nodes, a component type is allowed — the type constituent\n * of a React element — so factories like `createDataTable(columns)` can be\n * returned directly and mounted with the call-site props.\n *\n * At runtime, `resolveScopedRenderResult` distinguishes component types from\n * nodes (including portals). Getting that wrong mounts a portal via\n * `createElement` and blows up with an invalid-element-type error.\n */\n// Returned components declare their own props; a concrete props parameter would\n// be contravariant and reject the factories callers actually return.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- see above\nexport type ScopedRenderResult = ReactNode | ComponentType<any>;\n\n/**\n * `$$typeof` tags for object component wrappers that `createElement` accepts\n * as `type` (forwardRef, memo, lazy).\n *\n * Do not treat \"any object with `$$typeof`\" as a component: portals also have\n * `$$typeof` (`Symbol.for('react.portal')`) and `isValidElement(portal)` is\n * false, so a naive check would mis-classify them.\n */\nconst reactForwardRefType = Symbol.for('react.forward_ref');\nconst reactMemoType = Symbol.for('react.memo');\nconst reactLazyType = Symbol.for('react.lazy');\n\n/**\n * True when `value` can be passed as the `type` argument to `createElement`.\n *\n * Functions always qualify. Object wrappers qualify only for the forwardRef /\n * memo / lazy tags above — not portals or other React nodes that happen to\n * carry `$$typeof`.\n */\nexport function isRenderableComponentType(\n value: unknown,\n): value is ComponentType<Record<string, unknown>> {\n if (typeof value === 'function') {\n return true;\n }\n\n if (\n typeof value !== 'object' ||\n value === null ||\n Array.isArray(value) ||\n isValidElement(value) ||\n !('$$typeof' in value)\n ) {\n return false;\n }\n\n const typeTag = (value as { $$typeof: unknown }).$$typeof;\n\n return (\n typeTag === reactForwardRefType ||\n typeTag === reactMemoType ||\n typeTag === reactLazyType\n );\n}\n\n/**\n * If `render` returned a component type, mount it with `props`; otherwise\n * return the node as-is (elements, portals, null, etc.).\n */\nexport function resolveScopedRenderResult(\n result: ScopedRenderResult,\n props: Record<string, unknown> = {},\n): JSX.Element {\n if (isRenderableComponentType(result)) {\n return createElement(result, props);\n }\n\n return result as JSX.Element;\n}\n\n/**\n * Runtime counterpart of `ScopedComponentCompoundStaticKey` — keys that must\n * not be treated as compound component statics on a scoped wrapper.\n */\nconst reservedScopedCompoundStaticKeys = new Set<PropertyKey>([\n 'apply',\n 'arguments',\n 'bind',\n 'call',\n 'caller',\n 'childContextTypes',\n 'contextTypes',\n 'defaultProps',\n 'displayName',\n 'length',\n 'name',\n 'propTypes',\n 'prototype',\n 'toLocaleString',\n 'toString',\n 'valueOf',\n '$$typeof',\n]);\n\ntype ScopedComponentWrapper = ((\n props?: Record<string, unknown>,\n) => JSX.Element) &\n Record<string, unknown>;\n\n/**\n * Exposes compound statics (e.g. `DataTable.Loading`) on a scoped wrapper so\n * runtime matches `ScopedComponentCompoundStatics`.\n *\n * Why a Proxy: JSX reads `components.DataTable.Loading` while building the\n * element tree — before `DataTable` itself renders — so statics cannot be\n * copied only after the first `render` call. Property access lazily creates a\n * stable wrapper component that re-runs the scoped `render` under context and\n * mounts the matching static from the returned component type.\n */\nexport function withScopedCompoundStatics(\n wrapper: (props?: Record<string, unknown>) => JSX.Element,\n createCompoundStatic: (\n staticName: string,\n ) => (ownProps?: Record<string, unknown>) => JSX.Element,\n): ScopedComponentWrapper {\n return new Proxy(wrapper as ScopedComponentWrapper, {\n get(target, property, receiver) {\n if (\n typeof property === 'symbol' ||\n reservedScopedCompoundStaticKeys.has(property) ||\n property in target\n ) {\n return Reflect.get(target, property, receiver);\n }\n\n // Cache on the target so repeated `.Loading` access keeps one identity.\n const CompoundStatic = createCompoundStatic(property);\n target[property] = CompoundStatic;\n return CompoundStatic;\n },\n });\n}\n"],"mappings":";;;;;;;;;AAcA,MAAa,+BAA+B,IAAI,IAAI;CAClD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;;;;;;;;;AA0BD,MAAM,sBAAsB,OAAO,IAAI,mBAAmB;AAC1D,MAAM,gBAAgB,OAAO,IAAI,YAAY;AAC7C,MAAM,gBAAgB,OAAO,IAAI,YAAY;;;;;;;;AAS7C,SAAgB,0BACd,OACiD;CACjD,IAAI,OAAO,UAAU,YACnB,OAAO;CAGT,IACE,OAAO,UAAU,YACjB,UAAU,QACV,MAAM,QAAQ,KAAK,KACnB,eAAe,KAAK,KACpB,EAAE,cAAc,QAEhB,OAAO;CAGT,MAAM,UAAW,MAAgC;CAEjD,OACE,YAAY,uBACZ,YAAY,iBACZ,YAAY;AAEhB;;;;;AAMA,SAAgB,0BACd,QACA,QAAiC,CAAC,GACrB;CACb,IAAI,0BAA0B,MAAM,GAClC,OAAO,cAAc,QAAQ,KAAK;CAGpC,OAAO;AACT;;;;;AAMA,MAAM,mCAAmC,IAAI,IAAiB;CAC5D;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;;;;;;;;;;;AAiBD,SAAgB,0BACd,SACA,sBAGwB;CACxB,OAAO,IAAI,MAAM,SAAmC,EAClD,IAAI,QAAQ,UAAU,UAAU;EAC9B,IACE,OAAO,aAAa,YACpB,iCAAiC,IAAI,QAAQ,KAC7C,YAAY,QAEZ,OAAO,QAAQ,IAAI,QAAQ,UAAU,QAAQ;EAI/C,MAAM,iBAAiB,qBAAqB,QAAQ;EACpD,OAAO,YAAY;EACnB,OAAO;CACT,EACF,CAAC;AACH"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LazyResourceErrorComponent, LazyResourceLoadingComponent, LazyResourceStates } from "../lazy/types.cjs";
|
|
1
2
|
import { AsStateComposable, StateComposable, StateComposableOptions } from "./state-composable.cjs";
|
|
2
3
|
import { AnyRenderStateDefinition, CreateLayoutBuildingBlocks, CreateLayoutBuildingBlocksArguments, CreateLayoutBuildingBlocksResult, CreateRenderState, CreateRenderStateBuilderArguments, CreateRenderStateBuilderResult, CreateRenderStateFromState, DeferredRenderState, DefineLayoutComposables, LayoutComposablesDefinition, LazyRenderState, RenderStateCallProps, RenderStateCallback, RenderStateComposablesDefinition, RenderStateContext, RenderStateFragment, RenderStateName, RenderStateOverloads, RenderStateProps, RenderStateReferences, TypedRenderStateCallback } from "./render-state.cjs";
|
|
3
4
|
import { BaseResourceConfigComponents, ResourceConfig, ResourceConfigComponentKey, ResourceConfigComponents, ResourceConfigInput, ResourceConfigMap, SharedResourceConfigOptions, SubResourceConfig, SubResourceConfigComponentsFor } from "./types.cjs";
|
|
@@ -9,7 +10,7 @@ import { IsSubResourceKey, IsSubResourceKeyOptions, IsSubResourceKeyResult } fro
|
|
|
9
10
|
import { ComponentTypes, CreateResourceConfigFn, CreateResourceConfigForResource, CreatedResourceConfig, GetComponent, GetComponentAtBound, GetComponentForResource, GetComponentForResourceOptions, GetComponentOptions, GetComponentOptionsForResource, ResourceConfigFragment, ResourceConfigPath, ResourceFromGetComponentBound, SubResourceFromGetComponentBound, ValidateForResourceBound } from "./get-component.cjs";
|
|
10
11
|
import { CreateResourceLinkConfig, CreateResourceLinkGroupInput, CreateResourceLinkGroupOptions, CreateResourceLinkOptions, CreateResourceLinksFn, CreateResourceLinksWithGroups, CreateResourceLinksWithGroupsFn, CreateResourceLinksWithGroupsResult, CreateResourceMap, CreateResourceMapFn, CreatedResourceHref, CreatedResourceLink, CreatedResourceLinkBase, CreatedResourceMap, DefineResourceIconFn, DefineResourceIconInputHelpers, DefineResourceIconInputResult, FindResolvedResourceGroupResult, FindResourceGroupResult, InferHashFromResourceLinkHref, ResolveResourceIconInput, ResolvedResourceLinksWithGroups, ResolvedResourceLinksWithGroupsResult, ResourceAnchorLinkFn, ResourceIcon, ResourceIconFn, ResourceLinkHref, ValidateResource } from "./create-resource-links.cjs";
|
|
11
12
|
import { ContextualInlineRenderState, ContextualInlineRenderStates, CreateResourceLayoutFn, CreateResourceLayoutMakeComposableOptions, CreateResourceLayoutWithLayoutOptions, CreateViewMapBuiltInRenderStatesOptions, CreateViewMapFunctionRenderOptions, CreateViewMapInlineRenderStatesOptions, CreateViewMapOptions, CreateViewMapRenderStatesOptions, DefineResourceLayout, DefineResourceLayoutFn, DefineResourceLayoutForResources, DefineResourceLayoutForResourcesFactory, DefineResourceLayoutWithLayoutFn, DefineResourcesFn, DefinedResourceLayout, DefinedResourceLayoutWithShell, LayoutDefinition, LayoutIncludeProps, LayoutRenderResourcesAccessor, LayoutResourcesAccessor, ResourceLayoutProvider, ResourceLayoutProviderProps, ResourceLayoutShellComponent, ResourceLayoutShellProps, ResourceSelection, ShellLayoutDefinition, ShellRenderContext, TypedBuiltInRenderStates, TypedInlineRenderState, defineResourceLayout } from "./define-layout.cjs";
|
|
12
|
-
import {
|
|
13
|
+
import { LazyResourceLayoutComponent, LazyResourceLayoutOptions } from "./lazy-resource-layout.cjs";
|
|
13
14
|
import { BoundDefineResourceLayout, CreateDefinedResourceLayoutOptions, CreateDefinedResourceLayoutResult, DefineLazyDefaults, DefinedResourceLayoutInput, NonEmptyResources, createDefinedResourceLayout } from "./create-defined-resource-layout.cjs";
|
|
14
15
|
import { ResourceLayoutShellPublisher } from "./shell-context.cjs";
|
|
15
16
|
import { LayoutPreviewProps, defineLayoutPreview } from "./preview.cjs";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LazyResourceErrorComponent, LazyResourceLoadingComponent, LazyResourceStates } from "../lazy/types.mjs";
|
|
1
2
|
import { AsStateComposable, StateComposable, StateComposableOptions } from "./state-composable.mjs";
|
|
2
3
|
import { AnyRenderStateDefinition, CreateLayoutBuildingBlocks, CreateLayoutBuildingBlocksArguments, CreateLayoutBuildingBlocksResult, CreateRenderState, CreateRenderStateBuilderArguments, CreateRenderStateBuilderResult, CreateRenderStateFromState, DeferredRenderState, DefineLayoutComposables, LayoutComposablesDefinition, LazyRenderState, RenderStateCallProps, RenderStateCallback, RenderStateComposablesDefinition, RenderStateContext, RenderStateFragment, RenderStateName, RenderStateOverloads, RenderStateProps, RenderStateReferences, TypedRenderStateCallback } from "./render-state.mjs";
|
|
3
4
|
import { BaseResourceConfigComponents, ResourceConfig, ResourceConfigComponentKey, ResourceConfigComponents, ResourceConfigInput, ResourceConfigMap, SharedResourceConfigOptions, SubResourceConfig, SubResourceConfigComponentsFor } from "./types.mjs";
|
|
@@ -9,7 +10,7 @@ import { IsSubResourceKey, IsSubResourceKeyOptions, IsSubResourceKeyResult } fro
|
|
|
9
10
|
import { ComponentTypes, CreateResourceConfigFn, CreateResourceConfigForResource, CreatedResourceConfig, GetComponent, GetComponentAtBound, GetComponentForResource, GetComponentForResourceOptions, GetComponentOptions, GetComponentOptionsForResource, ResourceConfigFragment, ResourceConfigPath, ResourceFromGetComponentBound, SubResourceFromGetComponentBound, ValidateForResourceBound } from "./get-component.mjs";
|
|
10
11
|
import { CreateResourceLinkConfig, CreateResourceLinkGroupInput, CreateResourceLinkGroupOptions, CreateResourceLinkOptions, CreateResourceLinksFn, CreateResourceLinksWithGroups, CreateResourceLinksWithGroupsFn, CreateResourceLinksWithGroupsResult, CreateResourceMap, CreateResourceMapFn, CreatedResourceHref, CreatedResourceLink, CreatedResourceLinkBase, CreatedResourceMap, DefineResourceIconFn, DefineResourceIconInputHelpers, DefineResourceIconInputResult, FindResolvedResourceGroupResult, FindResourceGroupResult, InferHashFromResourceLinkHref, ResolveResourceIconInput, ResolvedResourceLinksWithGroups, ResolvedResourceLinksWithGroupsResult, ResourceAnchorLinkFn, ResourceIcon, ResourceIconFn, ResourceLinkHref, ValidateResource } from "./create-resource-links.mjs";
|
|
11
12
|
import { ContextualInlineRenderState, ContextualInlineRenderStates, CreateResourceLayoutFn, CreateResourceLayoutMakeComposableOptions, CreateResourceLayoutWithLayoutOptions, CreateViewMapBuiltInRenderStatesOptions, CreateViewMapFunctionRenderOptions, CreateViewMapInlineRenderStatesOptions, CreateViewMapOptions, CreateViewMapRenderStatesOptions, DefineResourceLayout, DefineResourceLayoutFn, DefineResourceLayoutForResources, DefineResourceLayoutForResourcesFactory, DefineResourceLayoutWithLayoutFn, DefineResourcesFn, DefinedResourceLayout, DefinedResourceLayoutWithShell, LayoutDefinition, LayoutIncludeProps, LayoutRenderResourcesAccessor, LayoutResourcesAccessor, ResourceLayoutProvider, ResourceLayoutProviderProps, ResourceLayoutShellComponent, ResourceLayoutShellProps, ResourceSelection, ShellLayoutDefinition, ShellRenderContext, TypedBuiltInRenderStates, TypedInlineRenderState, defineResourceLayout } from "./define-layout.mjs";
|
|
12
|
-
import {
|
|
13
|
+
import { LazyResourceLayoutComponent, LazyResourceLayoutOptions } from "./lazy-resource-layout.mjs";
|
|
13
14
|
import { BoundDefineResourceLayout, CreateDefinedResourceLayoutOptions, CreateDefinedResourceLayoutResult, DefineLazyDefaults, DefinedResourceLayoutInput, NonEmptyResources, createDefinedResourceLayout } from "./create-defined-resource-layout.mjs";
|
|
14
15
|
import { ResourceLayoutShellPublisher } from "./shell-context.mjs";
|
|
15
16
|
import { LayoutPreviewProps, defineLayoutPreview } from "./preview.mjs";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
const require_layout_configuration_error = require('../errors/layout-configuration-error.cjs');
|
|
1
2
|
const require_invalid_part = require('../errors/invalid-part.cjs');
|
|
2
3
|
const require_invalid_part_type = require('../errors/invalid-part-type.cjs');
|
|
3
|
-
const require_layout_configuration_error = require('../errors/layout-configuration-error.cjs');
|
|
4
4
|
|
|
5
5
|
//#region src/create-config/layout-name.ts
|
|
6
6
|
const layoutNamePattern = Symbol("layoutNamePattern");
|
|
@@ -31,8 +31,9 @@ function validatePartValues(definitions, values) {
|
|
|
31
31
|
return Object.fromEntries(supplied);
|
|
32
32
|
}
|
|
33
33
|
function createNamingFactory(definitions, definition) {
|
|
34
|
-
|
|
35
|
-
const
|
|
34
|
+
if (definition === null || typeof definition !== "object" || typeof definition.pattern !== "function") throw new require_layout_configuration_error.LayoutConfigurationError("Naming configuration must be an object containing a pattern function.");
|
|
35
|
+
const { pattern } = definition;
|
|
36
|
+
const strict = definition.strict !== false;
|
|
36
37
|
const defaults = Object.fromEntries(Object.keys(definitions).map((key) => [key, ""]));
|
|
37
38
|
function name(parts) {
|
|
38
39
|
if (strict && typeof parts !== "function") validatePartValues(definitions, parts);
|
|
@@ -60,11 +61,11 @@ function createNamingFactory(definitions, definition) {
|
|
|
60
61
|
*
|
|
61
62
|
* Choose the form that matches the values your convention needs:
|
|
62
63
|
*
|
|
63
|
-
* - `defineLayoutName(pattern)` provides the string parts `prefix`,
|
|
64
|
+
* - `defineLayoutName({ pattern })` provides the string parts `prefix`,
|
|
64
65
|
* `beforeSuffix`, and `append` for common naming variations.
|
|
65
|
-
* - `defineLayoutName.defineParts(...names).namingFn(pattern)` provides custom
|
|
66
|
+
* - `defineLayoutName.defineParts(...names).namingFn({ pattern })` provides custom
|
|
66
67
|
* string parts when domain-specific names make the pattern clearer.
|
|
67
|
-
* - `defineLayoutName.defineParts(schema).namingFn(pattern)` declares each
|
|
68
|
+
* - `defineLayoutName.defineParts(schema).namingFn({ pattern })` declares each
|
|
68
69
|
* part as `'string'` or `'number'` when supplied values need different types.
|
|
69
70
|
*
|
|
70
71
|
* The pattern controls where parts appear; their names do not impose an order.
|
|
@@ -81,29 +82,32 @@ function createNamingFactory(definitions, definition) {
|
|
|
81
82
|
* in namingFn to accept unchecked part keys and values in both TypeScript
|
|
82
83
|
* and runtime calls. Unchecked conventions return string names.
|
|
83
84
|
*
|
|
84
|
-
* @param definition -
|
|
85
|
-
*
|
|
85
|
+
* @param definition - An object containing the naming pattern and optional
|
|
86
|
+
* strict-checking policy.
|
|
86
87
|
* @returns A function accepting optional part values or a context callback.
|
|
87
88
|
* Calling it with no arguments leaves every declared part empty.
|
|
88
89
|
*
|
|
89
90
|
* @example
|
|
90
91
|
* Use the default string parts for a shared convention with occasional variants.
|
|
91
92
|
* ```tsx
|
|
92
|
-
* const layoutName = defineLayoutName(
|
|
93
|
-
*
|
|
94
|
-
*
|
|
93
|
+
* const layoutName = defineLayoutName({
|
|
94
|
+
* pattern: ({ resource, capitalize }, parts) =>
|
|
95
|
+
* `${parts.prefix}${capitalize(resource)}${parts.beforeSuffix}Layout${
|
|
96
|
+
* parts.append
|
|
97
|
+
* }`
|
|
98
|
+
* });
|
|
95
99
|
* const factory = createDefinedResourceLayout({
|
|
96
100
|
* resources: ['users'],
|
|
97
|
-
* name: layoutName()
|
|
101
|
+
* name: layoutName()
|
|
98
102
|
* });
|
|
99
103
|
* const { createResourceLayout } = factory.defineResourceLayout({
|
|
100
|
-
* render: () => <div
|
|
104
|
+
* render: () => <div />
|
|
101
105
|
* });
|
|
102
106
|
* const Users = createResourceLayout({ resource: 'users' });
|
|
103
107
|
* // Users.displayName is typed as 'UsersLayout'.
|
|
104
108
|
* const AdminUsers = createResourceLayout({
|
|
105
109
|
* resource: 'users',
|
|
106
|
-
* name: layoutName({ prefix: 'Admin', beforeSuffix: 'Detail' })
|
|
110
|
+
* name: layoutName({ prefix: 'Admin', beforeSuffix: 'Detail' })
|
|
107
111
|
* });
|
|
108
112
|
* // AdminUsers.displayName is typed as 'AdminUsersDetailLayout'.
|
|
109
113
|
* ```
|
|
@@ -114,13 +118,14 @@ function createNamingFactory(definitions, definition) {
|
|
|
114
118
|
* ```ts
|
|
115
119
|
* const pageName = defineLayoutName
|
|
116
120
|
* .defineParts('section', 'variant')
|
|
117
|
-
* .namingFn(
|
|
118
|
-
*
|
|
119
|
-
*
|
|
121
|
+
* .namingFn({
|
|
122
|
+
* pattern: ({ resource, capitalize }, parts) =>
|
|
123
|
+
* `${parts.section}${capitalize(resource)}${parts.variant}Page`
|
|
124
|
+
* });
|
|
120
125
|
* const adminPage = pageName({ section: 'Admin', variant: 'Detail' });
|
|
121
126
|
* // Used for 'users', this produces 'AdminUsersDetailPage'.
|
|
122
127
|
* const resourcePage = pageName(({ resource }) => ({
|
|
123
|
-
* section: resource === 'users' ? 'Admin' : 'Public'
|
|
128
|
+
* section: resource === 'users' ? 'Admin' : 'Public'
|
|
124
129
|
* }));
|
|
125
130
|
* // Used for 'users', this produces 'AdminUsersPage'.
|
|
126
131
|
* // Other resources receive the 'Public' section instead.
|
|
@@ -132,9 +137,10 @@ function createNamingFactory(definitions, definition) {
|
|
|
132
137
|
* ```ts
|
|
133
138
|
* const versionedName = defineLayoutName
|
|
134
139
|
* .defineParts({ section: 'string', version: 'number' })
|
|
135
|
-
* .namingFn(
|
|
136
|
-
*
|
|
137
|
-
*
|
|
140
|
+
* .namingFn({
|
|
141
|
+
* pattern: ({ resource, capitalize }, parts) =>
|
|
142
|
+
* `${parts.section}${capitalize(resource)}V${parts.version}`
|
|
143
|
+
* });
|
|
138
144
|
* const adminV2 = versionedName({ section: 'Admin', version: 2 });
|
|
139
145
|
* // Used for 'users', this produces 'AdminUsersV2'.
|
|
140
146
|
* // versionedName({ version: '2' }) is rejected: version must be a number.
|
|
@@ -146,11 +152,12 @@ function createNamingFactory(definitions, definition) {
|
|
|
146
152
|
* ```ts
|
|
147
153
|
* const formattedName = defineLayoutName
|
|
148
154
|
* .defineParts({ version: 'number' })
|
|
149
|
-
* .namingFn(
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
155
|
+
* .namingFn({
|
|
156
|
+
* pattern: ({ resource, capitalize }, parts) => {
|
|
157
|
+
* const version =
|
|
158
|
+
* typeof parts.version === 'number' ? parts.version.toFixed(0) : '';
|
|
159
|
+
* return `${capitalize(resource)}V${version}`;
|
|
160
|
+
* }
|
|
154
161
|
* });
|
|
155
162
|
* ```
|
|
156
163
|
*
|
|
@@ -161,8 +168,9 @@ function createNamingFactory(definitions, definition) {
|
|
|
161
168
|
* const externalName = defineLayoutName
|
|
162
169
|
* .defineParts({ version: 'number' })
|
|
163
170
|
* .namingFn({
|
|
164
|
-
* pattern: ({ resource }, parts) =>
|
|
165
|
-
*
|
|
171
|
+
* pattern: ({ resource }, parts) =>
|
|
172
|
+
* `${resource}${parts.version}${parts.extra}`,
|
|
173
|
+
* strict: false
|
|
166
174
|
* });
|
|
167
175
|
* const legacy = externalName({ version: 'legacy', extra: true });
|
|
168
176
|
* ```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout-name.cjs","names":["LayoutConfigurationError","InvalidPartError","InvalidPartTypeError"],"sources":["../../src/create-config/layout-name.ts"],"sourcesContent":["import { capitalize } from '../utils/capitalize';\nimport {\n InvalidPartError,\n InvalidPartTypeError,\n LayoutConfigurationError\n} from '../errors';\n/**\n * Each slot has a distinct type identity, so ordinary text cannot become a slot.\n */\ndeclare const layoutNamePlaceholder: unique symbol;\ntype NamePlaceholder<\n Key extends string,\n Value extends string | number = string\n> = Value & {\n readonly [layoutNamePlaceholder]: Key;\n};\ntype PatternNameContext = Omit<\n LayoutNameContext<NamePlaceholder<'resource'>>,\n 'capitalize'\n> & {\n capitalize: <T extends string>(\n value: T\n ) => T extends NamePlaceholder<'resource'>\n ? NamePlaceholder<'capitalizedResource'>\n : Capitalize<T>;\n};\nexport interface LayoutNameContext<\n Resource extends string = string,\n State extends string = string\n> {\n resource: Resource;\n states: readonly State[];\n capitalize: typeof capitalize;\n}\nexport interface LayoutNameParts {\n prefix?: string;\n beforeSuffix?: string;\n append?: string;\n}\n/**\n * Value kinds accepted by a declared naming part.\n */\nexport type LayoutNamePartType = 'string' | 'number';\n\n/**\n * Declares each naming part and the value kind accepted at call sites.\n */\nexport type LayoutNamePartDefinitions = Readonly<\n Record<string, LayoutNamePartType>\n>;\n\n/**\n * Defines the naming pattern and strict-checking policy. Strict defaults to true.\n */\nexport interface LayoutNameOptions<\n Definitions extends LayoutNamePartDefinitions,\n Pattern extends string,\n Strict extends boolean = true\n> {\n /**\n * Combines the naming context and part placeholders into a name.\n */\n pattern: NamingPattern<Definitions, Pattern, Strict>;\n /**\n * Set to false to skip part type checking and runtime validation.\n */\n strict?: Strict;\n}\n\n/**\n * Part values are intentionally unchecked when strict is false.\n */\ntype UncheckedNamingParts<Definitions extends LayoutNamePartDefinitions> =\n {\n [Key in keyof Definitions]?: any;\n } & Record<string, any>;\n\ntype PartValue<Type extends LayoutNamePartType> = Type extends 'number'\n ? number\n : string;\n\n/**\n * Optional values for declared naming parts. Omitted slots render as empty text.\n */\nexport type LayoutNamePartValues<\n Definitions extends LayoutNamePartDefinitions\n> = {\n [Key in keyof Definitions]?: PartValue<Definitions[Key]>;\n};\n\ntype PatternParts<Definitions extends LayoutNamePartDefinitions> = {\n [Key in keyof Definitions & string]: NamePlaceholder<\n `part:${Key}`,\n PartValue<Definitions[Key]> | ''\n >;\n};\ntype PartText<Value> = Value extends string | number ? `${Value}` : '';\ntype Part<Parts, Key extends keyof Parts> = PartText<Parts[Key]>;\ntype ResourcePlaceholderValues<Resource extends string> = {\n resource: Resource;\n capitalizedResource: Capitalize<Resource>;\n};\ntype PlaceholderValues<\n Resource extends string,\n Parts\n> = ResourcePlaceholderValues<Resource> & {\n [Key in keyof Parts & string as `part:${Key}`]: ResolvePattern<\n Part<Parts, Key>,\n ResourcePlaceholderValues<Resource>\n >;\n};\ntype MatchPlaceholder<Pattern extends string, Values> = {\n [Key in keyof Values & string]: Pattern extends\n | NamePlaceholder<Key>\n | `${NamePlaceholder<Key>}`\n | `${NamePlaceholder<Key, number>}`\n ? [Extract<Values[Key], string>, '']\n : Pattern extends `${NamePlaceholder<Key>}${infer Rest}`\n ? [Extract<Values[Key], string>, Rest]\n : Pattern extends `${NamePlaceholder<Key, number>}${infer Rest}`\n ? [Extract<Values[Key], string>, Rest]\n : never;\n}[keyof Values & string];\ntype ResolvePattern<\n Pattern extends string,\n Values,\n Result extends string = ''\n> = [MatchPlaceholder<Pattern, Values>] extends [never]\n ? Pattern extends `${infer First}${infer Rest}`\n ? ResolvePattern<Rest, Values, `${Result}${First}`>\n : `${Result}${Pattern}`\n : MatchPlaceholder<Pattern, Values> extends [\n infer Value extends string,\n infer Rest extends string\n ]\n ? ResolvePattern<Rest, Values, `${Result}${Value}`>\n : never;\nexport type ResolveNamePattern<\n Pattern extends string,\n Resource extends string,\n Parts = {}\n> = ResolvePattern<Pattern, PlaceholderValues<Resource, Parts>>;\nexport const layoutNamePattern: unique symbol = Symbol(\n 'layoutNamePattern'\n);\nexport interface LayoutNameResolver<\n Pattern extends string = string,\n Parts = {}\n> {\n (context: LayoutNameContext): string;\n readonly [layoutNamePattern]: { pattern: Pattern; parts: Parts };\n}\n/**\n * Computes a layout name from its resource and available render states.\n */\nexport type LayoutNameCallback<\n Resource extends string = string,\n States extends string = string,\n Name extends string = string\n> = (context: LayoutNameContext<Resource, States>) => Name;\n\nexport type LayoutNameInput<\n Resource extends string = string,\n States extends string = string,\n Name extends string = string\n> = Name | LayoutNameCallback<Resource, States, Name>;\nexport type ResolvedLayoutName<Naming, Resource extends string> = [\n Naming\n] extends [undefined]\n ? `${Capitalize<Resource>}Layout`\n : Naming extends LayoutNameResolver<infer Pattern, infer Parts>\n ? ResolveNamePattern<Pattern, Resource, Parts>\n : Naming extends (...args: any[]) => infer Result\n ? Extract<Result, string>\n : Naming extends string\n ? Naming\n : `${Capitalize<Resource>}Layout`;\ntype NamingPartsInput<\n Definitions extends LayoutNamePartDefinitions,\n Parts extends LayoutNamePartValues<Definitions>\n> = {\n [Key in keyof (LayoutNamePartValues<Definitions> &\n Parts)]: Key extends keyof Definitions\n ? (LayoutNamePartValues<Definitions> & Parts)[Key]\n : never;\n};\n\ntype NamingPartsCallback<\n Definitions extends LayoutNamePartDefinitions,\n Parts extends LayoutNamePartValues<Definitions>\n> = (context: PatternNameContext) => NamingPartsInput<Definitions, Parts>;\n\ntype ResolvedParts<\n Definitions extends LayoutNamePartDefinitions,\n Parts\n> = {\n [Key in keyof Definitions]: Key extends keyof Parts ? Parts[Key] : '';\n};\n\ntype NamingPattern<\n Definitions extends LayoutNamePartDefinitions,\n Pattern extends string,\n Strict extends boolean = true\n> = (\n context: PatternNameContext,\n parts: [Strict] extends [false]\n ? UncheckedNamingParts<Definitions>\n : PatternParts<Definitions>\n) => Pattern;\n\ntype NamingDefinition<\n Definitions extends LayoutNamePartDefinitions,\n Pattern extends string,\n Strict extends boolean\n> =\n | NamingPattern<Definitions, Pattern, Strict>\n | LayoutNameOptions<Definitions, Pattern, Strict>;\n\n/**\n * Supplies optional part values while preserving their literal types in names.\n */\ninterface CheckedLayoutNameFactory<\n Definitions extends LayoutNamePartDefinitions,\n Pattern extends string\n> {\n /**\n * Supplies values for declared parts without coercing their types.\n * Fixed values are checked immediately; callback results are checked when\n * the layout name is resolved for a resource.\n *\n * @throws {InvalidPartError} A supplied part has not been declared.\n * @throws {InvalidPartTypeError} A supplied value has the wrong kind.\n */\n <const Parts extends LayoutNamePartValues<Definitions> = {}>(\n parts?:\n | NamingPartsInput<Definitions, Parts>\n | NamingPartsCallback<Definitions, Parts>\n ): LayoutNameResolver<Pattern, ResolvedParts<Definitions, Parts>>;\n}\n\ninterface UncheckedLayoutNameFactory<\n Definitions extends LayoutNamePartDefinitions\n> {\n (\n parts?:\n | UncheckedNamingParts<Definitions>\n | ((\n context: PatternNameContext\n ) => UncheckedNamingParts<Definitions>)\n ): LayoutNameResolver<string>;\n}\n\n/**\n * Supplies optional naming parts. Strict conventions preserve literal names;\n * unchecked conventions accept arbitrary keys and values and return string names.\n */\nexport type LayoutNameFactory<\n Definitions extends LayoutNamePartDefinitions,\n Pattern extends string,\n Strict extends boolean = true\n> = [Strict] extends [false]\n ? UncheckedLayoutNameFactory<Definitions>\n : CheckedLayoutNameFactory<Definitions, Pattern>;\n\ninterface DefinedLayoutNameParts<\n Definitions extends LayoutNamePartDefinitions\n> {\n /**\n * Defines the naming pattern and optional strict-checking policy.\n * Strict defaults to true; false accepts unchecked part keys and values.\n */\n namingFn<\n const Pattern extends string,\n const Strict extends boolean = true\n >(\n definition: NamingDefinition<Definitions, Pattern, Strict>\n ): LayoutNameFactory<Definitions, Pattern, Strict>;\n}\n\nconst defaultPartDefinitions = {\n prefix: 'string',\n beforeSuffix: 'string',\n append: 'string'\n} satisfies { [Key in keyof LayoutNameParts]-?: 'string' };\n\nfunction validatePartValues(\n definitions: LayoutNamePartDefinitions,\n values: unknown\n): Record<string, string | number> {\n if (values === undefined) return {};\n if (\n values === null ||\n typeof values !== 'object' ||\n Array.isArray(values)\n ) {\n throw new LayoutConfigurationError(\n 'Naming part values must be an object.'\n );\n }\n\n const supplied: Array<[string, string | number]> = [];\n for (const part of Reflect.ownKeys(values)) {\n if (typeof part !== 'string' || !Object.hasOwn(definitions, part)) {\n throw new InvalidPartError({\n part: String(part),\n validParts: Object.keys(definitions)\n });\n }\n const value: unknown = Reflect.get(values, part);\n if (value === undefined) continue;\n\n const expectedType = definitions[part];\n if (\n (expectedType === 'string' && typeof value === 'string') ||\n (expectedType === 'number' && typeof value === 'number')\n ) {\n supplied.push([part, value]);\n } else {\n throw new InvalidPartTypeError({\n part,\n expectedType,\n receivedType:\n value === null\n ? 'null'\n : Array.isArray(value)\n ? 'array'\n : typeof value\n });\n }\n }\n return Object.fromEntries(supplied);\n}\n\nfunction createNamingFactory<\n Definitions extends LayoutNamePartDefinitions,\n const Pattern extends string,\n Strict extends boolean = true\n>(\n definitions: Definitions,\n definition: NamingDefinition<Definitions, Pattern, Strict>\n): LayoutNameFactory<Definitions, Pattern, Strict> {\n const pattern =\n typeof definition === 'function' ? definition : definition.pattern;\n const strict =\n typeof definition === 'function' || definition.strict !== false;\n const defaults = Object.fromEntries(\n Object.keys(definitions).map((key) => [key, ''])\n );\n function name<\n const Parts extends LayoutNamePartValues<Definitions> = {}\n >(\n parts?:\n | NamingPartsInput<Definitions, Parts>\n | NamingPartsCallback<Definitions, Parts>\n ): LayoutNameResolver<Pattern, ResolvedParts<Definitions, Parts>> {\n if (strict && typeof parts !== 'function')\n validatePartValues(definitions, parts);\n const resolver = ((context: LayoutNameContext) => {\n const values =\n typeof parts === 'function'\n ? parts(context as unknown as PatternNameContext)\n : parts;\n const supplied = strict\n ? validatePartValues(definitions, values)\n : Object.fromEntries(\n Object.entries(values ?? {}).filter(\n ([, value]) => value !== undefined\n )\n );\n return pattern(\n context as unknown as PatternNameContext,\n {\n ...defaults,\n ...supplied\n } as [Strict] extends [false]\n ? UncheckedNamingParts<Definitions>\n : PatternParts<Definitions>\n );\n }) as unknown as LayoutNameResolver<\n Pattern,\n ResolvedParts<Definitions, Parts>\n >;\n Object.defineProperty(resolver, layoutNamePattern, { value: {} });\n return resolver;\n }\n return name as LayoutNameFactory<Definitions, Pattern, Strict>;\n}\n\n/**\n * Defines a reusable layout naming convention that preserves resource-specific\n * literal names in TypeScript. Define the pattern once, then supply optional\n * part values wherever the convention is used.\n *\n * Omit `name` entirely when the generated name, such as `UsersLayout`, is enough.\n * Use this helper when several layouts share a naming rule or need variations\n * while retaining exact component `displayName` types.\n *\n * Choose the form that matches the values your convention needs:\n *\n * - `defineLayoutName(pattern)` provides the string parts `prefix`,\n * `beforeSuffix`, and `append` for common naming variations.\n * - `defineLayoutName.defineParts(...names).namingFn(pattern)` provides custom\n * string parts when domain-specific names make the pattern clearer.\n * - `defineLayoutName.defineParts(schema).namingFn(pattern)` declares each\n * part as `'string'` or `'number'` when supplied values need different types.\n *\n * The pattern controls where parts appear; their names do not impose an order.\n * Part values are optional and omitted values render as empty text. Supply an\n * object for fixed values, or a callback when values depend on the resource.\n * Numeric placeholders can also be empty text inside the pattern. Narrow them\n * with `typeof value === 'number'` before using number-only methods.\n * Supplied keys and value kinds are also validated at runtime. Unknown parts\n * throw InvalidPartError; incorrect value kinds throw InvalidPartTypeError.\n * Each returned naming resolver can be passed to a factory, definition, or\n * component creation call through its `name` option.\n *\n * Strict checking defaults to true. Use `{ pattern, strict: false }` here or\n * in namingFn to accept unchecked part keys and values in both TypeScript\n * and runtime calls. Unchecked conventions return string names.\n *\n * @param definition - A pattern callback, or an object containing the pattern\n * and optional strict-checking policy.\n * @returns A function accepting optional part values or a context callback.\n * Calling it with no arguments leaves every declared part empty.\n *\n * @example\n * Use the default string parts for a shared convention with occasional variants.\n * ```tsx\n * const layoutName = defineLayoutName(({ resource, capitalize }, parts) =>\n * `${parts.prefix}${capitalize(resource)}${parts.beforeSuffix}Layout${parts.append}`,\n * );\n * const factory = createDefinedResourceLayout({\n * resources: ['users'],\n * name: layoutName(),\n * });\n * const { createResourceLayout } = factory.defineResourceLayout({\n * render: () => <div />,\n * });\n * const Users = createResourceLayout({ resource: 'users' });\n * // Users.displayName is typed as 'UsersLayout'.\n * const AdminUsers = createResourceLayout({\n * resource: 'users',\n * name: layoutName({ prefix: 'Admin', beforeSuffix: 'Detail' }),\n * });\n * // AdminUsers.displayName is typed as 'AdminUsersDetailLayout'.\n * ```\n *\n * @example\n * Declare custom string parts when their names describe your application's\n * conventions more clearly than prefix, beforeSuffix, and append.\n * ```ts\n * const pageName = defineLayoutName\n * .defineParts('section', 'variant')\n * .namingFn(({ resource, capitalize }, parts) =>\n * `${parts.section}${capitalize(resource)}${parts.variant}Page`,\n * );\n * const adminPage = pageName({ section: 'Admin', variant: 'Detail' });\n * // Used for 'users', this produces 'AdminUsersDetailPage'.\n * const resourcePage = pageName(({ resource }) => ({\n * section: resource === 'users' ? 'Admin' : 'Public',\n * }));\n * // Used for 'users', this produces 'AdminUsersPage'.\n * // Other resources receive the 'Public' section instead.\n * ```\n *\n * @example\n * Use a schema when a part should accept a number instead of a string.\n * Supplied keys are suggested by the editor and checked against the schema.\n * ```ts\n * const versionedName = defineLayoutName\n * .defineParts({ section: 'string', version: 'number' })\n * .namingFn(({ resource, capitalize }, parts) =>\n * `${parts.section}${capitalize(resource)}V${parts.version}`,\n * );\n * const adminV2 = versionedName({ section: 'Admin', version: 2 });\n * // Used for 'users', this produces 'AdminUsersV2'.\n * // versionedName({ version: '2' }) is rejected: version must be a number.\n * ```\n *\n * @example\n * Guard optional numeric values before formatting them with number methods.\n * Plain interpolation, as above, already handles empty values.\n * ```ts\n * const formattedName = defineLayoutName\n * .defineParts({ version: 'number' })\n * .namingFn(({ resource, capitalize }, parts) => {\n * const version = typeof parts.version === 'number'\n * ? parts.version.toFixed(0)\n * : '';\n * return `${capitalize(resource)}V${version}`;\n * });\n * ```\n *\n * @example\n * Opt out of part checking when a convention intentionally accepts external\n * keys and mixed value types. The resulting displayName is typed as string.\n * ```ts\n * const externalName = defineLayoutName\n * .defineParts({ version: 'number' })\n * .namingFn({\n * pattern: ({ resource }, parts) => `${resource}${parts.version}${parts.extra}`,\n * strict: false,\n * });\n * const legacy = externalName({ version: 'legacy', extra: true });\n * ```\n */\nexport function defineLayoutName<\n const Pattern extends string,\n const Strict extends boolean = true\n>(\n definition: NamingDefinition<\n typeof defaultPartDefinitions,\n Pattern,\n Strict\n >\n): LayoutNameFactory<typeof defaultPartDefinitions, Pattern, Strict> {\n return createNamingFactory(defaultPartDefinitions, definition);\n}\n\n/**\n * Declares string placeholders from their names.\n * Call namingFn on the result to define how those slots form a layout name.\n */\nfunction defineParts<const Keys extends readonly string[]>(\n ...keys: Keys\n): DefinedLayoutNameParts<{ [Key in Keys[number]]: 'string' }>;\n/**\n * Declares placeholders with string or number values from a part schema.\n * Call namingFn on the result to define how those slots form a layout name.\n */\nfunction defineParts<const Definitions extends LayoutNamePartDefinitions>(\n definitions: Definitions\n): DefinedLayoutNameParts<Definitions>;\nfunction defineParts(\n ...input: string[] | [LayoutNamePartDefinitions]\n): DefinedLayoutNameParts<LayoutNamePartDefinitions> {\n const definitions =\n typeof input[0] === 'object'\n ? input[0]\n : Object.fromEntries(input.map((key) => [key, 'string']));\n return {\n namingFn(definition) {\n return createNamingFactory(definitions, definition);\n }\n };\n}\n\ndefineLayoutName.defineParts = defineParts;\n"],"mappings":";;;;;AA8IA,MAAa,oBAAmC,OAC9C,mBACF;AAuIA,MAAM,yBAAyB;CAC7B,QAAQ;CACR,cAAc;CACd,QAAQ;AACV;AAEA,SAAS,mBACP,aACA,QACiC;CACjC,IAAI,WAAW,QAAW,OAAO,CAAC;CAClC,IACE,WAAW,QACX,OAAO,WAAW,YAClB,MAAM,QAAQ,MAAM,GAEpB,MAAM,IAAIA,4DACR,uCACF;CAGF,MAAM,WAA6C,CAAC;CACpD,KAAK,MAAM,QAAQ,QAAQ,QAAQ,MAAM,GAAG;EAC1C,IAAI,OAAO,SAAS,YAAY,CAAC,OAAO,OAAO,aAAa,IAAI,GAC9D,MAAM,IAAIC,sCAAiB;GACzB,MAAM,OAAO,IAAI;GACjB,YAAY,OAAO,KAAK,WAAW;EACrC,CAAC;EAEH,MAAM,QAAiB,QAAQ,IAAI,QAAQ,IAAI;EAC/C,IAAI,UAAU,QAAW;EAEzB,MAAM,eAAe,YAAY;EACjC,IACG,iBAAiB,YAAY,OAAO,UAAU,YAC9C,iBAAiB,YAAY,OAAO,UAAU,UAE/C,SAAS,KAAK,CAAC,MAAM,KAAK,CAAC;OAE3B,MAAM,IAAIC,+CAAqB;GAC7B;GACA;GACA,cACE,UAAU,OACN,SACA,MAAM,QAAQ,KAAK,IACnB,UACA,OAAO;EACf,CAAC;CAEL;CACA,OAAO,OAAO,YAAY,QAAQ;AACpC;AAEA,SAAS,oBAKP,aACA,YACiD;CACjD,MAAM,UACJ,OAAO,eAAe,aAAa,aAAa,WAAW;CAC7D,MAAM,SACJ,OAAO,eAAe,cAAc,WAAW,WAAW;CAC5D,MAAM,WAAW,OAAO,YACtB,OAAO,KAAK,WAAW,EAAE,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC,CACjD;CACA,SAAS,KAGP,OAGgE;EAChE,IAAI,UAAU,OAAO,UAAU,YAC7B,mBAAmB,aAAa,KAAK;EACvC,MAAM,aAAa,YAA+B;GAChD,MAAM,SACJ,OAAO,UAAU,aACb,MAAM,OAAwC,IAC9C;GACN,MAAM,WAAW,SACb,mBAAmB,aAAa,MAAM,IACtC,OAAO,YACL,OAAO,QAAQ,UAAU,CAAC,CAAC,EAAE,QAC1B,GAAG,WAAW,UAAU,MAC3B,CACF;GACJ,OAAO,QACL,SACA;IACE,GAAG;IACH,GAAG;GACL,CAGF;EACF;EAIA,OAAO,eAAe,UAAU,mBAAmB,EAAE,OAAO,CAAC,EAAE,CAAC;EAChE,OAAO;CACT;CACA,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwHA,SAAgB,iBAId,YAKmE;CACnE,OAAO,oBAAoB,wBAAwB,UAAU;AAC/D;AAgBA,SAAS,YACP,GAAG,OACgD;CACnD,MAAM,cACJ,OAAO,MAAM,OAAO,WAChB,MAAM,KACN,OAAO,YAAY,MAAM,KAAK,QAAQ,CAAC,KAAK,QAAQ,CAAC,CAAC;CAC5D,OAAO,EACL,SAAS,YAAY;EACnB,OAAO,oBAAoB,aAAa,UAAU;CACpD,EACF;AACF;AAEA,iBAAiB,cAAc"}
|
|
1
|
+
{"version":3,"file":"layout-name.cjs","names":["LayoutConfigurationError","InvalidPartError","InvalidPartTypeError"],"sources":["../../src/create-config/layout-name.ts"],"sourcesContent":["import { capitalize } from '../utils/capitalize';\nimport {\n InvalidPartError,\n InvalidPartTypeError,\n LayoutConfigurationError\n} from '../errors';\n/**\n * Each slot has a distinct type identity, so ordinary text cannot become a slot.\n */\ndeclare const layoutNamePlaceholder: unique symbol;\ntype NamePlaceholder<\n Key extends string,\n Value extends string | number = string\n> = Value & {\n readonly [layoutNamePlaceholder]: Key;\n};\ntype PatternNameContext = Omit<\n LayoutNameContext<NamePlaceholder<'resource'>>,\n 'capitalize'\n> & {\n capitalize: <T extends string>(\n value: T\n ) => T extends NamePlaceholder<'resource'>\n ? NamePlaceholder<'capitalizedResource'>\n : Capitalize<T>;\n};\nexport interface LayoutNameContext<\n Resource extends string = string,\n State extends string = string\n> {\n resource: Resource;\n states: readonly State[];\n capitalize: typeof capitalize;\n}\nexport interface LayoutNameParts {\n prefix?: string;\n beforeSuffix?: string;\n append?: string;\n}\n/**\n * Value kinds accepted by a declared naming part.\n */\nexport type LayoutNamePartType = 'string' | 'number';\n\n/**\n * Declares each naming part and the value kind accepted at call sites.\n */\nexport type LayoutNamePartDefinitions = Readonly<\n Record<string, LayoutNamePartType>\n>;\n\n/**\n * Defines the naming pattern and strict-checking policy. Strict defaults to true.\n */\nexport interface LayoutNameOptions<\n Definitions extends LayoutNamePartDefinitions,\n Pattern extends string,\n Strict extends boolean = true\n> {\n /**\n * Combines the naming context and part placeholders into a name.\n */\n pattern: NamingPattern<Definitions, Pattern, Strict>;\n /**\n * Set to false to skip part type checking and runtime validation.\n */\n strict?: Strict;\n}\n\n/**\n * Part values are intentionally unchecked when strict is false.\n */\ntype UncheckedNamingParts<Definitions extends LayoutNamePartDefinitions> =\n {\n [Key in keyof Definitions]?: any;\n } & Record<string, any>;\n\ntype PartValue<Type extends LayoutNamePartType> = Type extends 'number'\n ? number\n : string;\n\n/**\n * Optional values for declared naming parts. Omitted slots render as empty text.\n */\nexport type LayoutNamePartValues<\n Definitions extends LayoutNamePartDefinitions\n> = {\n [Key in keyof Definitions]?: PartValue<Definitions[Key]>;\n};\n\ntype PatternParts<Definitions extends LayoutNamePartDefinitions> = {\n [Key in keyof Definitions & string]: NamePlaceholder<\n `part:${Key}`,\n PartValue<Definitions[Key]> | ''\n >;\n};\ntype PartText<Value> = Value extends string | number ? `${Value}` : '';\ntype Part<Parts, Key extends keyof Parts> = PartText<Parts[Key]>;\ntype ResourcePlaceholderValues<Resource extends string> = {\n resource: Resource;\n capitalizedResource: Capitalize<Resource>;\n};\ntype PlaceholderValues<\n Resource extends string,\n Parts\n> = ResourcePlaceholderValues<Resource> & {\n [Key in keyof Parts & string as `part:${Key}`]: ResolvePattern<\n Part<Parts, Key>,\n ResourcePlaceholderValues<Resource>\n >;\n};\ntype MatchPlaceholder<Pattern extends string, Values> = {\n [Key in keyof Values & string]: Pattern extends\n | NamePlaceholder<Key>\n | `${NamePlaceholder<Key>}`\n | `${NamePlaceholder<Key, number>}`\n ? [Extract<Values[Key], string>, '']\n : Pattern extends `${NamePlaceholder<Key>}${infer Rest}`\n ? [Extract<Values[Key], string>, Rest]\n : Pattern extends `${NamePlaceholder<Key, number>}${infer Rest}`\n ? [Extract<Values[Key], string>, Rest]\n : never;\n}[keyof Values & string];\ntype ResolvePattern<\n Pattern extends string,\n Values,\n Result extends string = ''\n> = [MatchPlaceholder<Pattern, Values>] extends [never]\n ? Pattern extends `${infer First}${infer Rest}`\n ? ResolvePattern<Rest, Values, `${Result}${First}`>\n : `${Result}${Pattern}`\n : MatchPlaceholder<Pattern, Values> extends [\n infer Value extends string,\n infer Rest extends string\n ]\n ? ResolvePattern<Rest, Values, `${Result}${Value}`>\n : never;\nexport type ResolveNamePattern<\n Pattern extends string,\n Resource extends string,\n Parts = {}\n> = ResolvePattern<Pattern, PlaceholderValues<Resource, Parts>>;\nexport const layoutNamePattern: unique symbol = Symbol(\n 'layoutNamePattern'\n);\nexport interface LayoutNameResolver<\n Pattern extends string = string,\n Parts = {}\n> {\n (context: LayoutNameContext): string;\n readonly [layoutNamePattern]: { pattern: Pattern; parts: Parts };\n}\n/**\n * Computes a layout name from its resource and available render states.\n */\nexport type LayoutNameCallback<\n Resource extends string = string,\n States extends string = string,\n Name extends string = string\n> = (context: LayoutNameContext<Resource, States>) => Name;\n\nexport type LayoutNameInput<\n Resource extends string = string,\n States extends string = string,\n Name extends string = string\n> = Name | LayoutNameCallback<Resource, States, Name>;\nexport type ResolvedLayoutName<Naming, Resource extends string> = [\n Naming\n] extends [undefined]\n ? `${Capitalize<Resource>}Layout`\n : Naming extends LayoutNameResolver<infer Pattern, infer Parts>\n ? ResolveNamePattern<Pattern, Resource, Parts>\n : Naming extends (...args: any[]) => infer Result\n ? Extract<Result, string>\n : Naming extends string\n ? Naming\n : `${Capitalize<Resource>}Layout`;\ntype NamingPartsInput<\n Definitions extends LayoutNamePartDefinitions,\n Parts extends LayoutNamePartValues<Definitions>\n> = {\n [Key in keyof (LayoutNamePartValues<Definitions> &\n Parts)]: Key extends keyof Definitions\n ? (LayoutNamePartValues<Definitions> & Parts)[Key]\n : never;\n};\n\ntype NamingPartsCallback<\n Definitions extends LayoutNamePartDefinitions,\n Parts extends LayoutNamePartValues<Definitions>\n> = (context: PatternNameContext) => NamingPartsInput<Definitions, Parts>;\n\ntype ResolvedParts<\n Definitions extends LayoutNamePartDefinitions,\n Parts\n> = {\n [Key in keyof Definitions]: Key extends keyof Parts ? Parts[Key] : '';\n};\n\ntype NamingPattern<\n Definitions extends LayoutNamePartDefinitions,\n Pattern extends string,\n Strict extends boolean = true\n> = (\n context: PatternNameContext,\n parts: [Strict] extends [false]\n ? UncheckedNamingParts<Definitions>\n : PatternParts<Definitions>\n) => Pattern;\n\n/**\n * Supplies optional part values while preserving their literal types in names.\n */\ninterface CheckedLayoutNameFactory<\n Definitions extends LayoutNamePartDefinitions,\n Pattern extends string\n> {\n /**\n * Supplies values for declared parts without coercing their types.\n * Fixed values are checked immediately; callback results are checked when\n * the layout name is resolved for a resource.\n *\n * @throws {InvalidPartError} A supplied part has not been declared.\n * @throws {InvalidPartTypeError} A supplied value has the wrong kind.\n */\n <const Parts extends LayoutNamePartValues<Definitions> = {}>(\n parts?:\n | NamingPartsInput<Definitions, Parts>\n | NamingPartsCallback<Definitions, Parts>\n ): LayoutNameResolver<Pattern, ResolvedParts<Definitions, Parts>>;\n}\n\ninterface UncheckedLayoutNameFactory<\n Definitions extends LayoutNamePartDefinitions\n> {\n (\n parts?:\n | UncheckedNamingParts<Definitions>\n | ((\n context: PatternNameContext\n ) => UncheckedNamingParts<Definitions>)\n ): LayoutNameResolver<string>;\n}\n\n/**\n * Supplies optional naming parts. Strict conventions preserve literal names;\n * unchecked conventions accept arbitrary keys and values and return string names.\n */\nexport type LayoutNameFactory<\n Definitions extends LayoutNamePartDefinitions,\n Pattern extends string,\n Strict extends boolean = true\n> = [Strict] extends [false]\n ? UncheckedLayoutNameFactory<Definitions>\n : CheckedLayoutNameFactory<Definitions, Pattern>;\n\ninterface DefinedLayoutNameParts<\n Definitions extends LayoutNamePartDefinitions\n> {\n /**\n * Defines the naming pattern and optional strict-checking policy.\n * Strict defaults to true; false accepts unchecked part keys and values.\n */\n namingFn<\n const Pattern extends string,\n const Strict extends boolean = true\n >(\n definition: LayoutNameOptions<Definitions, Pattern, Strict>\n ): LayoutNameFactory<Definitions, Pattern, Strict>;\n}\n\nconst defaultPartDefinitions = {\n prefix: 'string',\n beforeSuffix: 'string',\n append: 'string'\n} satisfies { [Key in keyof LayoutNameParts]-?: 'string' };\n\nfunction validatePartValues(\n definitions: LayoutNamePartDefinitions,\n values: unknown\n): Record<string, string | number> {\n if (values === undefined) return {};\n if (\n values === null ||\n typeof values !== 'object' ||\n Array.isArray(values)\n ) {\n throw new LayoutConfigurationError(\n 'Naming part values must be an object.'\n );\n }\n\n const supplied: Array<[string, string | number]> = [];\n for (const part of Reflect.ownKeys(values)) {\n if (typeof part !== 'string' || !Object.hasOwn(definitions, part)) {\n throw new InvalidPartError({\n part: String(part),\n validParts: Object.keys(definitions)\n });\n }\n const value: unknown = Reflect.get(values, part);\n if (value === undefined) continue;\n\n const expectedType = definitions[part];\n if (\n (expectedType === 'string' && typeof value === 'string') ||\n (expectedType === 'number' && typeof value === 'number')\n ) {\n supplied.push([part, value]);\n } else {\n throw new InvalidPartTypeError({\n part,\n expectedType,\n receivedType:\n value === null\n ? 'null'\n : Array.isArray(value)\n ? 'array'\n : typeof value\n });\n }\n }\n return Object.fromEntries(supplied);\n}\n\nfunction createNamingFactory<\n Definitions extends LayoutNamePartDefinitions,\n const Pattern extends string,\n Strict extends boolean = true\n>(\n definitions: Definitions,\n definition: LayoutNameOptions<Definitions, Pattern, Strict>\n): LayoutNameFactory<Definitions, Pattern, Strict> {\n if (\n definition === null ||\n typeof definition !== 'object' ||\n typeof definition.pattern !== 'function'\n ) {\n throw new LayoutConfigurationError(\n 'Naming configuration must be an object containing a pattern function.'\n );\n }\n const { pattern } = definition;\n const strict = definition.strict !== false;\n const defaults = Object.fromEntries(\n Object.keys(definitions).map((key) => [key, ''])\n );\n function name<\n const Parts extends LayoutNamePartValues<Definitions> = {}\n >(\n parts?:\n | NamingPartsInput<Definitions, Parts>\n | NamingPartsCallback<Definitions, Parts>\n ): LayoutNameResolver<Pattern, ResolvedParts<Definitions, Parts>> {\n if (strict && typeof parts !== 'function')\n validatePartValues(definitions, parts);\n const resolver = ((context: LayoutNameContext) => {\n const values =\n typeof parts === 'function'\n ? parts(context as unknown as PatternNameContext)\n : parts;\n const supplied = strict\n ? validatePartValues(definitions, values)\n : Object.fromEntries(\n Object.entries(values ?? {}).filter(\n ([, value]) => value !== undefined\n )\n );\n return pattern(\n context as unknown as PatternNameContext,\n {\n ...defaults,\n ...supplied\n } as [Strict] extends [false]\n ? UncheckedNamingParts<Definitions>\n : PatternParts<Definitions>\n );\n }) as unknown as LayoutNameResolver<\n Pattern,\n ResolvedParts<Definitions, Parts>\n >;\n Object.defineProperty(resolver, layoutNamePattern, { value: {} });\n return resolver;\n }\n return name as LayoutNameFactory<Definitions, Pattern, Strict>;\n}\n\n/**\n * Defines a reusable layout naming convention that preserves resource-specific\n * literal names in TypeScript. Define the pattern once, then supply optional\n * part values wherever the convention is used.\n *\n * Omit `name` entirely when the generated name, such as `UsersLayout`, is enough.\n * Use this helper when several layouts share a naming rule or need variations\n * while retaining exact component `displayName` types.\n *\n * Choose the form that matches the values your convention needs:\n *\n * - `defineLayoutName({ pattern })` provides the string parts `prefix`,\n * `beforeSuffix`, and `append` for common naming variations.\n * - `defineLayoutName.defineParts(...names).namingFn({ pattern })` provides custom\n * string parts when domain-specific names make the pattern clearer.\n * - `defineLayoutName.defineParts(schema).namingFn({ pattern })` declares each\n * part as `'string'` or `'number'` when supplied values need different types.\n *\n * The pattern controls where parts appear; their names do not impose an order.\n * Part values are optional and omitted values render as empty text. Supply an\n * object for fixed values, or a callback when values depend on the resource.\n * Numeric placeholders can also be empty text inside the pattern. Narrow them\n * with `typeof value === 'number'` before using number-only methods.\n * Supplied keys and value kinds are also validated at runtime. Unknown parts\n * throw InvalidPartError; incorrect value kinds throw InvalidPartTypeError.\n * Each returned naming resolver can be passed to a factory, definition, or\n * component creation call through its `name` option.\n *\n * Strict checking defaults to true. Use `{ pattern, strict: false }` here or\n * in namingFn to accept unchecked part keys and values in both TypeScript\n * and runtime calls. Unchecked conventions return string names.\n *\n * @param definition - An object containing the naming pattern and optional\n * strict-checking policy.\n * @returns A function accepting optional part values or a context callback.\n * Calling it with no arguments leaves every declared part empty.\n *\n * @example\n * Use the default string parts for a shared convention with occasional variants.\n * ```tsx\n * const layoutName = defineLayoutName({\n * pattern: ({ resource, capitalize }, parts) =>\n * `${parts.prefix}${capitalize(resource)}${parts.beforeSuffix}Layout${\n * parts.append\n * }`\n * });\n * const factory = createDefinedResourceLayout({\n * resources: ['users'],\n * name: layoutName()\n * });\n * const { createResourceLayout } = factory.defineResourceLayout({\n * render: () => <div />\n * });\n * const Users = createResourceLayout({ resource: 'users' });\n * // Users.displayName is typed as 'UsersLayout'.\n * const AdminUsers = createResourceLayout({\n * resource: 'users',\n * name: layoutName({ prefix: 'Admin', beforeSuffix: 'Detail' })\n * });\n * // AdminUsers.displayName is typed as 'AdminUsersDetailLayout'.\n * ```\n *\n * @example\n * Declare custom string parts when their names describe your application's\n * conventions more clearly than prefix, beforeSuffix, and append.\n * ```ts\n * const pageName = defineLayoutName\n * .defineParts('section', 'variant')\n * .namingFn({\n * pattern: ({ resource, capitalize }, parts) =>\n * `${parts.section}${capitalize(resource)}${parts.variant}Page`\n * });\n * const adminPage = pageName({ section: 'Admin', variant: 'Detail' });\n * // Used for 'users', this produces 'AdminUsersDetailPage'.\n * const resourcePage = pageName(({ resource }) => ({\n * section: resource === 'users' ? 'Admin' : 'Public'\n * }));\n * // Used for 'users', this produces 'AdminUsersPage'.\n * // Other resources receive the 'Public' section instead.\n * ```\n *\n * @example\n * Use a schema when a part should accept a number instead of a string.\n * Supplied keys are suggested by the editor and checked against the schema.\n * ```ts\n * const versionedName = defineLayoutName\n * .defineParts({ section: 'string', version: 'number' })\n * .namingFn({\n * pattern: ({ resource, capitalize }, parts) =>\n * `${parts.section}${capitalize(resource)}V${parts.version}`\n * });\n * const adminV2 = versionedName({ section: 'Admin', version: 2 });\n * // Used for 'users', this produces 'AdminUsersV2'.\n * // versionedName({ version: '2' }) is rejected: version must be a number.\n * ```\n *\n * @example\n * Guard optional numeric values before formatting them with number methods.\n * Plain interpolation, as above, already handles empty values.\n * ```ts\n * const formattedName = defineLayoutName\n * .defineParts({ version: 'number' })\n * .namingFn({\n * pattern: ({ resource, capitalize }, parts) => {\n * const version =\n * typeof parts.version === 'number' ? parts.version.toFixed(0) : '';\n * return `${capitalize(resource)}V${version}`;\n * }\n * });\n * ```\n *\n * @example\n * Opt out of part checking when a convention intentionally accepts external\n * keys and mixed value types. The resulting displayName is typed as string.\n * ```ts\n * const externalName = defineLayoutName\n * .defineParts({ version: 'number' })\n * .namingFn({\n * pattern: ({ resource }, parts) =>\n * `${resource}${parts.version}${parts.extra}`,\n * strict: false\n * });\n * const legacy = externalName({ version: 'legacy', extra: true });\n * ```\n */\nexport function defineLayoutName<\n const Pattern extends string,\n const Strict extends boolean = true\n>(\n definition: LayoutNameOptions<\n typeof defaultPartDefinitions,\n Pattern,\n Strict\n >\n): LayoutNameFactory<typeof defaultPartDefinitions, Pattern, Strict> {\n return createNamingFactory(defaultPartDefinitions, definition);\n}\n\n/**\n * Declares string placeholders from their names.\n * Call namingFn on the result to define how those slots form a layout name.\n */\nfunction defineParts<const Keys extends readonly string[]>(\n ...keys: Keys\n): DefinedLayoutNameParts<{ [Key in Keys[number]]: 'string' }>;\n/**\n * Declares placeholders with string or number values from a part schema.\n * Call namingFn on the result to define how those slots form a layout name.\n */\nfunction defineParts<const Definitions extends LayoutNamePartDefinitions>(\n definitions: Definitions\n): DefinedLayoutNameParts<Definitions>;\nfunction defineParts(\n ...input: string[] | [LayoutNamePartDefinitions]\n): DefinedLayoutNameParts<LayoutNamePartDefinitions> {\n const definitions =\n typeof input[0] === 'object'\n ? input[0]\n : Object.fromEntries(input.map((key) => [key, 'string']));\n return {\n namingFn(definition) {\n return createNamingFactory(definitions, definition);\n }\n };\n}\n\ndefineLayoutName.defineParts = defineParts;\n"],"mappings":";;;;;AA8IA,MAAa,oBAAmC,OAC9C,mBACF;AA+HA,MAAM,yBAAyB;CAC7B,QAAQ;CACR,cAAc;CACd,QAAQ;AACV;AAEA,SAAS,mBACP,aACA,QACiC;CACjC,IAAI,WAAW,QAAW,OAAO,CAAC;CAClC,IACE,WAAW,QACX,OAAO,WAAW,YAClB,MAAM,QAAQ,MAAM,GAEpB,MAAM,IAAIA,4DACR,uCACF;CAGF,MAAM,WAA6C,CAAC;CACpD,KAAK,MAAM,QAAQ,QAAQ,QAAQ,MAAM,GAAG;EAC1C,IAAI,OAAO,SAAS,YAAY,CAAC,OAAO,OAAO,aAAa,IAAI,GAC9D,MAAM,IAAIC,sCAAiB;GACzB,MAAM,OAAO,IAAI;GACjB,YAAY,OAAO,KAAK,WAAW;EACrC,CAAC;EAEH,MAAM,QAAiB,QAAQ,IAAI,QAAQ,IAAI;EAC/C,IAAI,UAAU,QAAW;EAEzB,MAAM,eAAe,YAAY;EACjC,IACG,iBAAiB,YAAY,OAAO,UAAU,YAC9C,iBAAiB,YAAY,OAAO,UAAU,UAE/C,SAAS,KAAK,CAAC,MAAM,KAAK,CAAC;OAE3B,MAAM,IAAIC,+CAAqB;GAC7B;GACA;GACA,cACE,UAAU,OACN,SACA,MAAM,QAAQ,KAAK,IACnB,UACA,OAAO;EACf,CAAC;CAEL;CACA,OAAO,OAAO,YAAY,QAAQ;AACpC;AAEA,SAAS,oBAKP,aACA,YACiD;CACjD,IACE,eAAe,QACf,OAAO,eAAe,YACtB,OAAO,WAAW,YAAY,YAE9B,MAAM,IAAIF,4DACR,uEACF;CAEF,MAAM,EAAE,YAAY;CACpB,MAAM,SAAS,WAAW,WAAW;CACrC,MAAM,WAAW,OAAO,YACtB,OAAO,KAAK,WAAW,EAAE,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC,CACjD;CACA,SAAS,KAGP,OAGgE;EAChE,IAAI,UAAU,OAAO,UAAU,YAC7B,mBAAmB,aAAa,KAAK;EACvC,MAAM,aAAa,YAA+B;GAChD,MAAM,SACJ,OAAO,UAAU,aACb,MAAM,OAAwC,IAC9C;GACN,MAAM,WAAW,SACb,mBAAmB,aAAa,MAAM,IACtC,OAAO,YACL,OAAO,QAAQ,UAAU,CAAC,CAAC,EAAE,QAC1B,GAAG,WAAW,UAAU,MAC3B,CACF;GACJ,OAAO,QACL,SACA;IACE,GAAG;IACH,GAAG;GACL,CAGF;EACF;EAIA,OAAO,eAAe,UAAU,mBAAmB,EAAE,OAAO,CAAC,EAAE,CAAC;EAChE,OAAO;CACT;CACA,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+HA,SAAgB,iBAId,YAKmE;CACnE,OAAO,oBAAoB,wBAAwB,UAAU;AAC/D;AAgBA,SAAS,YACP,GAAG,OACgD;CACnD,MAAM,cACJ,OAAO,MAAM,OAAO,WAChB,MAAM,KACN,OAAO,YAAY,MAAM,KAAK,QAAQ,CAAC,KAAK,QAAQ,CAAC,CAAC;CAC5D,OAAO,EACL,SAAS,YAAY;EACnB,OAAO,oBAAoB,aAAa,UAAU;CACpD,EACF;AACF;AAEA,iBAAiB,cAAc"}
|