@jfdevelops/react-layout 0.2.0 → 0.3.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/define-layout.cjs +144 -0
- package/dist/create-config/define-layout.cjs.map +1 -0
- package/dist/create-config/define-layout.d.cts +106 -0
- package/dist/create-config/define-layout.d.cts.map +1 -0
- package/dist/create-config/define-layout.d.mts +106 -0
- package/dist/create-config/define-layout.d.mts.map +1 -0
- package/dist/create-config/define-layout.mjs +144 -0
- package/dist/create-config/define-layout.mjs.map +1 -0
- package/dist/create-config/get-component.cjs +52 -0
- package/dist/create-config/get-component.cjs.map +1 -0
- package/dist/create-config/get-component.d.cts +62 -0
- package/dist/create-config/get-component.d.cts.map +1 -0
- package/dist/create-config/get-component.d.mts +62 -0
- package/dist/create-config/get-component.d.mts.map +1 -0
- package/dist/create-config/get-component.mjs +51 -0
- package/dist/create-config/get-component.mjs.map +1 -0
- package/dist/create-config/index.d.cts +3 -0
- package/dist/create-config/index.d.mts +3 -0
- package/dist/create-config/types.d.cts +42 -0
- package/dist/create-config/types.d.cts.map +1 -0
- package/dist/create-config/types.d.mts +42 -0
- package/dist/create-config/types.d.mts.map +1 -0
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/props.d.cts +2 -2
- package/dist/props.d.cts.map +1 -1
- package/dist/props.d.mts +2 -2
- package/dist/props.d.mts.map +1 -1
- package/dist/resource.cjs.map +1 -1
- package/dist/resource.d.cts +22 -2
- package/dist/resource.d.cts.map +1 -1
- package/dist/resource.d.mts +22 -2
- package/dist/resource.d.mts.map +1 -1
- package/dist/resource.mjs.map +1 -1
- package/dist/utils.cjs +5 -0
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +2 -1
- package/dist/utils.d.cts.map +1 -1
- package/dist/utils.d.mts +2 -1
- package/dist/utils.d.mts.map +1 -1
- package/dist/utils.mjs +5 -1
- package/dist/utils.mjs.map +1 -1
- package/dist/validators/validate-props.cjs +3 -1
- package/dist/validators/validate-props.cjs.map +1 -1
- package/dist/validators/validate-props.mjs +3 -1
- package/dist/validators/validate-props.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/create-config.cjs +0 -101
- package/dist/create-config.cjs.map +0 -1
- package/dist/create-config.d.cts +0 -67
- package/dist/create-config.d.cts.map +0 -1
- package/dist/create-config.d.mts +0 -67
- package/dist/create-config.d.mts.map +0 -1
- package/dist/create-config.mjs +0 -101
- package/dist/create-config.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-layout.mjs","names":[],"sources":["../../src/create-config/define-layout.tsx"],"sourcesContent":["import type { JSX } from 'react';\nimport {\n type ComposableComponents,\n type ComposableNameContext,\n type CreateLayoutComposable,\n MakeComposable,\n makeComposable,\n MakeComposableOptions,\n resolveLayoutComposables,\n} from '../composable';\nimport {\n type AnyBuiltPropDefinition,\n createPrimitivePropBuilder,\n createProp,\n type ResolveLayoutProps,\n type ResolveProps,\n validateProps,\n} from '../validators';\nimport {\n IncludedProps,\n InferredInProps,\n InPropsDefinition,\n InPropsObject,\n LayoutRenderProps,\n} from '../props';\nimport {\n normalizeResources,\n toResourceEnum,\n type LayoutResourceKey,\n type ResourceDefinition,\n} from '../resource';\nimport {\n BaseComponent,\n functionalUpdate,\n pick,\n resolvePropDefinitionValues,\n Show,\n Updater,\n} from '../utils';\nimport { capitalize } from '../utils/capitalize';\nimport {\n type CreateResourceConfigFn,\n createResourceConfig,\n} from './get-component';\n\ntype LayoutProps<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n IncludeProps extends IncludedProps<InferredInProps<Resources, Options>> = {},\n CustomProps extends InPropsObject = {},\n> = {\n /**\n * Props to include in the layout.\n */\n include?: IncludeProps;\n /**\n * Custom props that the layout will receive.\n */\n custom?: CustomProps;\n};\n\ntype LayoutRenderContext<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Composables extends ComposableComponents,\n> = {\n composables: LayoutRenderComposables<Composables>;\n inProps: Record<string, unknown>;\n resource: LayoutResourceKey<Resources>;\n name: string;\n};\ntype LayoutRenderComposables<Composables extends ComposableComponents> = [\n keyof Composables,\n] extends [never]\n ? undefined\n : Composables;\n\ntype SplitLayoutInPropDefinition<\n Props extends InPropsObject = {},\n Content = unknown,\n> = {\n props?: Props;\n render: ((props: ResolveProps<Props>) => Content) | Content;\n};\n\nfunction isBuiltPropDefinition(\n value: unknown,\n): value is AnyBuiltPropDefinition {\n return typeof value === 'function' && value !== null && 'visibility' in value;\n}\n\nfunction isSplitLayoutInPropDefinition(\n value: unknown,\n): value is SplitLayoutInPropDefinition {\n return (\n value !== null &&\n typeof value === 'object' &&\n 'render' in value &&\n (value as { render?: unknown }).render !== undefined\n );\n}\n\nfunction isJSXElementDefinition(\n definition: unknown,\n): definition is AnyBuiltPropDefinition & { type: 'JSX.Element' } {\n return (\n isBuiltPropDefinition(definition) &&\n 'type' in definition &&\n definition.type === 'JSX.Element'\n );\n}\n\nfunction toLayoutRenderPropKey(\n includeKey: string,\n definition: unknown,\n) {\n return isJSXElementDefinition(definition)\n ? capitalize(includeKey)\n : includeKey;\n}\n\nfunction readLayoutOptionValue(\n includeKey: string,\n definition: unknown,\n sources: Record<string, unknown>,\n) {\n const layoutOptionKeys = isJSXElementDefinition(definition)\n ? [capitalize(includeKey), includeKey]\n : [includeKey, capitalize(includeKey)];\n\n for (const key of layoutOptionKeys) {\n if (key in sources) {\n return sources[key];\n }\n }\n\n return undefined;\n}\n\nfunction splitLayoutInProps(inProps: Record<string, unknown>) {\n const resolvedInProps: Record<string, AnyBuiltPropDefinition> = {};\n const splitInProps: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(inProps)) {\n if (isBuiltPropDefinition(value)) {\n resolvedInProps[key] = value;\n continue;\n }\n\n if (isSplitLayoutInPropDefinition(value)) {\n splitInProps[key] = value.render;\n\n if (value.props && typeof value.props === 'object') {\n Object.assign(resolvedInProps, value.props);\n }\n }\n }\n\n return {\n resolvedInProps,\n splitInProps,\n };\n}\n\nfunction resolveLayoutOptionDefaults(\n defaults: Record<string, unknown>,\n options: Record<string, unknown>,\n) {\n const resolved = { ...options };\n\n for (const [key, defaultValue] of Object.entries(defaults)) {\n if (key in options) {\n if (typeof defaultValue === 'function') {\n resolved[key] = options[key];\n } else {\n resolved[key] = functionalUpdate(\n defaultValue,\n options[key] as Updater<unknown>,\n );\n }\n }\n }\n\n return resolved;\n}\n\ntype CreateViewMapOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n IncludeProps extends IncludedProps<InferredInProps<Resources, Options>> = {},\n CustomProps extends InPropsObject = {},\n Composables extends ComposableComponents = {},\n> = {\n /**\n * An array of valid resource names to support.\n */\n resources: Resources;\n /**\n * The options that are passed into the created resource layout.\n */\n options: Options;\n layout: {\n /**\n * The props to pass to the layout.\n */\n props?: LayoutProps<Resources, Options, IncludeProps, CustomProps>;\n /**\n * Components used to compose the layout. Invoked per layout instance with\n * a scoped `create` that resolves composable `name` callbacks using the\n * layout's `resource` and `name`.\n */\n composables?: (\n create: CreateLayoutComposable<LayoutResourceKey<Resources>>,\n ) => Composables;\n /**\n * The render function for the layout.\n */\n render: (\n props: LayoutRenderProps<Resources, Options, IncludeProps, CustomProps>,\n context: LayoutRenderContext<Resources, Composables>,\n ) => JSX.Element;\n };\n};\n\ntype ResourceLayoutComposition<\n Name extends string,\n Composables extends ComposableComponents,\n> = [keyof Composables] extends [never]\n ? {}\n : {\n makeComposable: MakeComposable<Composables, Name>;\n };\ntype ResourceLayoutComponent<\n Name extends string,\n Props extends InPropsObject = {},\n Composables extends ComposableComponents = {},\n> = ResourceLayoutComposition<Name, Composables> &\n BaseComponent<Name, ResolveProps<Props>> & {\n (props: Show<ResolveProps<Props>>): JSX.Element;\n };\n\ntype LayoutPropDefaults = Record<string, unknown>;\n\ntype LayoutPropsForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n> = ResolveLayoutProps<InferredInProps<Resources, InProps>>;\n\ntype CreateTimeLayoutPropWithDefault<\n LayoutProps extends LayoutPropDefaults,\n K extends keyof LayoutProps,\n> = LayoutProps[K] extends (...args: unknown[]) => unknown\n ? LayoutProps[K]\n : Updater<LayoutProps[K]>;\n\ntype ResolveLayoutPropsWithDefaults<\n LayoutProps extends LayoutPropDefaults,\n Defaults extends LayoutPropDefaults,\n> = Omit<LayoutProps, keyof Defaults> & {\n [K in keyof Defaults & keyof LayoutProps]?: CreateTimeLayoutPropWithDefault<\n LayoutProps,\n K\n >;\n};\n\ntype CreateResourceLayoutOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Props extends InPropsObject = {},\n> = LayoutPropsForResource<Resources, InProps> & {\n name: Name;\n resource: Resource;\n props?: Props;\n};\ntype CreateLayoutForResourceOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n> = {\n name?: Name;\n resource: Resource;\n};\ntype CreatedLayoutForResourceOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Props extends InPropsObject = {},\n Defaults extends LayoutPropDefaults = {},\n> = ResolveLayoutPropsWithDefaults<\n LayoutPropsForResource<Resources, InProps>,\n Defaults\n> & {\n props?: Props;\n};\ntype CreatedLayoutForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n CustomProps extends InPropsObject = {},\n Composables extends ComposableComponents = {},\n Defaults extends LayoutPropDefaults = {},\n> = <OverrideName extends string = Name, Props extends InPropsObject = {}>(\n options: CreatedLayoutForResourceOptions<\n Resources,\n InProps,\n Props,\n Defaults\n > & {\n name?: OverrideName;\n },\n) => ResourceLayoutComponent<OverrideName, CustomProps, Composables>;\n\ntype SetDefaultPropsForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n> = Partial<LayoutPropsForResource<Resources, InProps>>;\n\ntype ResolvedSetDefaultProps<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Defaults extends SetDefaultPropsForResource<Resources, InProps>,\n> = {\n [K in keyof Defaults &\n keyof LayoutPropsForResource<Resources, InProps>]: LayoutPropsForResource<\n Resources,\n InProps\n >[K];\n};\n\ntype SetDefaultPropForResourceFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n CustomProps extends InPropsObject = {},\n Composables extends ComposableComponents = {},\n> = <const Defaults extends SetDefaultPropsForResource<Resources, InProps>>(\n /**\n * Default values for layout props. Each prop can only be set once.\n */\n defaults: Defaults,\n) => CreatedLayoutForResource<\n Resources,\n InProps,\n Name,\n Resource,\n CustomProps,\n Composables,\n ResolvedSetDefaultProps<Resources, InProps, Defaults>\n>;\n\ntype CreateLayoutForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n IncludeProps extends IncludedProps<InferredInProps<Resources, InProps>> = {},\n CustomProps extends InPropsObject = {},\n Composables extends ComposableComponents = {},\n> = <Name extends string, Resource extends LayoutResourceKey<Resources>>(\n options: CreateLayoutForResourceOptions<Resources, Name, Resource>,\n) => CreatedLayoutForResource<\n Resources,\n InProps,\n Name,\n Resource,\n CustomProps,\n Composables\n> & {\n /**\n * Set default values for layout props in a single call.\n */\n setDefaults: SetDefaultPropForResourceFn<\n Resources,\n InProps,\n Name,\n Resource,\n CustomProps,\n Composables\n >;\n};\ntype CreateResourceLayoutFnImpl<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n IncludeProps extends IncludedProps<InferredInProps<Resources, InProps>> = {},\n CustomProps extends InPropsObject = {},\n Composables extends ComposableComponents = {},\n> = <\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Props extends InPropsObject = {},\n>(\n options: CreateResourceLayoutOptions<\n Resources,\n InProps,\n Name,\n Resource,\n Props\n >,\n) => ResourceLayoutComponent<Name, CustomProps, Composables>;\nexport interface CreateResourceLayoutFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n IncludeProps extends IncludedProps<InferredInProps<Resources, InProps>> = {},\n CustomProps extends InPropsObject = {},\n Composables extends ComposableComponents = {},\n> extends CreateResourceLayoutFnImpl<\n Resources,\n InProps,\n IncludeProps,\n CustomProps,\n Composables\n> {\n /**\n * A function to create a resource layout for a specific resource.\n */\n forResource: CreateLayoutForResource<\n Resources,\n InProps,\n IncludeProps,\n CustomProps,\n Composables\n >;\n}\n\ntype DefinedResourceLayout<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n IncludeProps extends IncludedProps<InferredInProps<Resources, InProps>> = {},\n CustomProps extends InPropsObject = {},\n Composables extends ComposableComponents = {},\n> = {\n createResourceConfig: CreateResourceConfigFn<Resources>;\n createResourceLayout: CreateResourceLayoutFn<\n Resources,\n InProps,\n IncludeProps,\n CustomProps,\n Composables\n >;\n};\n\nexport function defineResourceLayout<\n const Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n IncludeProps extends IncludedProps<InferredInProps<Resources, InProps>> = {},\n CustomProps extends InPropsObject = {},\n Composables extends ComposableComponents = {},\n>(\n options: CreateViewMapOptions<\n Resources,\n InProps,\n IncludeProps,\n CustomProps,\n Composables\n >,\n) {\n const { options: inProps, resources, layout } = options;\n const normalizedResources = normalizeResources(resources);\n const resourcesEnum = createPrimitivePropBuilder('string').enum(\n toResourceEnum(normalizedResources),\n );\n const definedResourceLayout: CreateResourceLayoutFnImpl<\n Resources,\n InProps,\n IncludeProps,\n CustomProps,\n Composables\n > = (layoutOptions) => {\n const {\n name,\n props: instancePropDefinitions,\n ...layoutOptionProps\n } = layoutOptions;\n const createComposableLayout =\n makeComposable<\n LayoutRenderProps<Resources, InProps, IncludeProps, CustomProps>\n >();\n const nameProp = createProp.string().literal(name);\n const rawResolvedOptions =\n typeof inProps === 'function'\n ? inProps({\n resource: resourcesEnum,\n name: nameProp,\n })\n : inProps;\n const { resolvedInProps, splitInProps } = splitLayoutInProps({\n ...(rawResolvedOptions as Record<string, unknown>),\n ...(instancePropDefinitions as Record<string, unknown> | undefined),\n ...layoutOptionProps,\n });\n const { composables, render, props: layoutProps } = layout;\n const customLayoutProps = layoutProps?.custom;\n const includeLayoutProps = layoutProps?.include;\n const resolvedLayoutProps = {\n ...customLayoutProps,\n };\n const layoutContext: ComposableNameContext<\n LayoutResourceKey<Resources>,\n typeof name\n > = {\n resource: layoutOptions.resource,\n name,\n capitalize,\n };\n const resolvedComposables = composables\n ? resolveLayoutComposables(composables, layoutContext)\n : undefined;\n const mergedRenderContext = {\n composables: resolvedComposables as LayoutRenderComposables<Composables>,\n resource: layoutContext.resource,\n name: layoutContext.name,\n inProps: splitInProps,\n } as LayoutRenderContext<Resources, Composables>;\n\n function Component(props: Show<ResolveProps<CustomProps>>) {\n const validatedProps = validateProps(resolvedLayoutProps, props);\n const includedPropKeys = Object.keys(includeLayoutProps ?? {});\n const includedPropDefinitions = pick(\n resolvedInProps,\n includedPropKeys,\n ) as Record<string, unknown>;\n const includedPropValues = {\n ...resolvePropDefinitionValues(includedPropDefinitions),\n } as Record<string, unknown>;\n\n for (const key of includedPropKeys) {\n const definition = resolvedInProps[key];\n const layoutOptionValue = readLayoutOptionValue(\n key,\n definition,\n layoutOptionProps,\n );\n const splitValue = key in splitInProps ? splitInProps[key] : undefined;\n const value = layoutOptionValue ?? splitValue;\n\n if (value !== undefined) {\n includedPropValues[key] = value;\n }\n }\n\n const validatedIncludedProps = validateProps(\n includedPropDefinitions as Record<string, AnyBuiltPropDefinition>,\n includedPropValues,\n );\n const layoutRenderIncludedProps = Object.fromEntries(\n includedPropKeys.flatMap((key) => {\n if (!(key in validatedIncludedProps)) {\n return [];\n }\n\n return [\n [\n toLayoutRenderPropKey(key, resolvedInProps[key]),\n validatedIncludedProps[key as keyof typeof validatedIncludedProps],\n ],\n ];\n }),\n );\n const layoutRenderProps = {\n ...validatedProps,\n ...layoutRenderIncludedProps,\n } as unknown as LayoutRenderProps<\n Resources,\n InProps,\n IncludeProps,\n CustomProps\n >;\n\n return <>{render(layoutRenderProps, mergedRenderContext)}</>;\n }\n\n function createComposition<LayoutName extends string>(\n compositionOptions: MakeComposableOptions<Composables, LayoutName>,\n ) {\n if (!compositionOptions.components) {\n return {} as ResourceLayoutComposition<LayoutName, Composables>;\n }\n\n return {\n makeComposable: createComposableLayout(compositionOptions),\n };\n }\n\n return Object.assign(Component, {\n displayName: name,\n props: undefined as unknown as ResolveProps<CustomProps>,\n ...createComposition({\n components: resolvedComposables as Composables | undefined,\n name,\n }),\n });\n };\n function createLayoutForResource<\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Defaults extends LayoutPropDefaults,\n >(\n defaultName: Name | undefined,\n resource: Resource,\n defaults: Record<string, unknown>,\n ) {\n return (({ name, ...rest }) =>\n definedResourceLayout({\n ...defaults,\n name: name ?? defaultName,\n resource,\n ...resolveLayoutOptionDefaults(defaults, rest),\n } as never) as never) as CreatedLayoutForResource<\n Resources,\n InProps,\n Name,\n Resource,\n CustomProps,\n Composables,\n Defaults\n >;\n }\n\n function createLayoutForResourceBuilder<\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n >(\n defaultName: Name | undefined,\n resource: Resource,\n ): CreatedLayoutForResource<\n Resources,\n InProps,\n Name,\n Resource,\n CustomProps,\n Composables\n > & {\n setDefaults: SetDefaultPropForResourceFn<\n Resources,\n InProps,\n Name,\n Resource,\n CustomProps,\n Composables\n >;\n } {\n const createLayout = createLayoutForResource(defaultName, resource, {});\n\n const setDefaults = ((defaults) =>\n createLayoutForResource(defaultName, resource, defaults)) as SetDefaultPropForResourceFn<\n Resources,\n InProps,\n Name,\n Resource,\n CustomProps,\n Composables\n >;\n\n return Object.assign(createLayout, { setDefaults });\n }\n const forResource: CreateLayoutForResource<\n Resources,\n InProps,\n IncludeProps,\n CustomProps,\n Composables\n > = (options) => {\n const { name: defaultName, resource } = options;\n\n if (!resource) {\n throw new Error('\"resource\" is required when calling \"forResource\"');\n }\n\n return createLayoutForResourceBuilder(defaultName, resource);\n };\n const createResourceLayout: CreateResourceLayoutFn<\n Resources,\n InProps,\n IncludeProps,\n CustomProps,\n Composables\n > = Object.assign(definedResourceLayout, {\n forResource,\n });\n\n return {\n createResourceConfig,\n createResourceLayout,\n } as DefinedResourceLayout<\n Resources,\n InProps,\n IncludeProps,\n CustomProps,\n Composables\n >;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/create-config/get-component.ts
|
|
3
|
+
function resolveResourceConfigEntry(entry, subResource) {
|
|
4
|
+
if (typeof subResource === "string") {
|
|
5
|
+
const next = entry.subResources?.[subResource];
|
|
6
|
+
if (!next) throw new Error(`Sub-resource "${subResource}" is not configured`);
|
|
7
|
+
return next;
|
|
8
|
+
}
|
|
9
|
+
const next = entry.subResources?.[subResource.resource];
|
|
10
|
+
if (!next) throw new Error(`Sub-resource "${subResource.resource}" is not configured`);
|
|
11
|
+
return resolveResourceConfigEntry(next, subResource.subResource);
|
|
12
|
+
}
|
|
13
|
+
function readResourceConfigComponent(entry, componentKey) {
|
|
14
|
+
if (componentKey === "new" || componentKey === "detail") {
|
|
15
|
+
const branch = entry[componentKey];
|
|
16
|
+
if (!branch?.component) throw new Error(`Missing "${componentKey}.component" configuration`);
|
|
17
|
+
return branch.component;
|
|
18
|
+
}
|
|
19
|
+
const value = entry[componentKey];
|
|
20
|
+
if (!value) throw new Error(`Missing "${componentKey}" configuration`);
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
function getComponentFromOptions(config, options) {
|
|
24
|
+
const { resource, component: componentKey = "component" } = options;
|
|
25
|
+
const resourceEntry = config[resource];
|
|
26
|
+
if (!resourceEntry) throw new Error(`Resource "${resource}" is not configured`);
|
|
27
|
+
let entry = resourceEntry;
|
|
28
|
+
if ("subResource" in options && options.subResource !== void 0) entry = resolveResourceConfigEntry(entry, options.subResource);
|
|
29
|
+
return readResourceConfigComponent(entry, componentKey);
|
|
30
|
+
}
|
|
31
|
+
function createGetComponent(config) {
|
|
32
|
+
function getComponent(options) {
|
|
33
|
+
return getComponentFromOptions(config, options);
|
|
34
|
+
}
|
|
35
|
+
const forResource = (bound) => {
|
|
36
|
+
return (options) => getComponentFromOptions(config, {
|
|
37
|
+
...bound,
|
|
38
|
+
...options
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
return Object.assign(getComponent, { forResource });
|
|
42
|
+
}
|
|
43
|
+
function createResourceConfig(config) {
|
|
44
|
+
return {
|
|
45
|
+
config,
|
|
46
|
+
getComponent: createGetComponent(config)
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
exports.createResourceConfig = createResourceConfig;
|
|
52
|
+
//# sourceMappingURL=get-component.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-component.cjs","names":[],"sources":["../../src/create-config/get-component.ts"],"sourcesContent":["import type { JSX } from 'react';\nimport type {\n LayoutResourceKey,\n ResourceDefinition,\n SubResourceDefinitionsFor,\n SubResourceParamForResource,\n} from '../resource';\nimport type {\n ResourceConfigComponentKey,\n ResourceConfigComponents,\n ResourceConfigEntry,\n ResourceConfigMap,\n ResourceConfigInput,\n} from './types';\n\ntype ResourceHasLayoutSubResources<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n> = [SubResourceDefinitionsFor<Resources, Resource>] extends [readonly []]\n ? false\n : true;\n\ntype SubResourceOptionForGenerics<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined,\n> = [SubResource] extends [undefined]\n ? ResourceHasLayoutSubResources<Resources, Resource> extends true\n ? {\n subResource?: SubResourceParamForResource<Resources, Resource>;\n }\n : {}\n : ResourceHasLayoutSubResources<Resources, Resource> extends true\n ? { subResource?: SubResource }\n : {};\n\n/** Options for one layout resource passed to {@link GetComponent}. */\nexport type GetComponentOptionsForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined = undefined,\n> = SubResourceOptionForGenerics<Resources, Resource, SubResource> & {\n resource: Resource;\n /**\n * The component to get.\n *\n * @default 'component'\n */\n component?: ResourceConfigComponentKey;\n};\n\n/** Union of valid `getComponent` option shapes for each declared layout resource. */\nexport type GetComponentOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> =\n LayoutResourceKey<Resources> extends infer Resource\n ? Resource extends LayoutResourceKey<Resources>\n ? GetComponentOptionsForResource<Resources, Resource>\n : never\n : never;\n\n/** `subResource` bound by {@link GetComponentForResource}. */\nexport type SubResourceFromGetComponentBound<Bound> = Bound extends {\n subResource: infer SubResource;\n}\n ? SubResource\n : undefined;\n\n/** Options for {@link GetComponentForResource} — binds `resource` and optional `subResource`. */\nexport type GetComponentForResourceOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined = undefined,\n> = {\n resource: Resource;\n} & SubResourceOptionForGenerics<Resources, Resource, SubResource>;\n\n/** Valid bind shapes for {@link GetComponentForResource}. */\nexport type GetComponentForResourceBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> =\n LayoutResourceKey<Resources> extends infer Resource\n ? Resource extends LayoutResourceKey<Resources>\n ? GetComponentForResourceOptions<Resources, Resource>\n : never\n : never;\n\ntype GetComponentForResourceOptionsForBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Bound extends { resource: LayoutResourceKey<Resources> },\n> = GetComponentForResourceOptions<\n Resources,\n Bound['resource'],\n SubResourceFromGetComponentBound<Bound>\n>;\n\n/**\n * Rejects bind objects with keys (e.g. `subResource`) that are invalid for the\n * given `resource`. Union assignability alone is too permissive for excess keys.\n */\nexport type ValidateForResourceBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Bound extends { resource: LayoutResourceKey<Resources> },\n> = Bound extends GetComponentForResourceOptionsForBound<Resources, Bound>\n ? keyof Bound extends keyof GetComponentForResourceOptionsForBound<\n Resources,\n Bound\n >\n ? Bound\n : never\n : never;\n\n/** `resource` inferred from a {@link GetComponentForResource} bind argument. */\nexport type ResourceFromGetComponentBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Bound,\n> = Bound extends {\n resource: infer Resource extends LayoutResourceKey<Resources>;\n}\n ? Resource\n : never;\n\n/** Reusable getter returned by {@link GetComponentForResource} (only `component` remains). */\nexport type GetComponentAtBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined = undefined,\n> = (\n options?: Pick<\n GetComponentOptionsForResource<Resources, Resource, SubResource>,\n 'component'\n >,\n) => JSX.Element;\n\nexport type GetComponentForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = <\n const Bound extends {\n resource: LayoutResourceKey<Resources>;\n },\n>(\n bound: ValidateForResourceBound<Resources, Bound>,\n) => GetComponentAtBound<\n Resources,\n ResourceFromGetComponentBound<Resources, Bound>,\n SubResourceFromGetComponentBound<Bound>\n>;\n\nexport interface GetComponent<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> {\n <const Options extends GetComponentOptions<Resources>>(\n options: Options,\n ): JSX.Element;\n forResource: GetComponentForResource<Resources>;\n}\n\nexport interface CreatedResourceConfig<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> {\n config: ResourceConfigMap<Resources>;\n getComponent: GetComponent<Resources>;\n}\n\nexport type CreateResourceConfigFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = <const Config extends ResourceConfigMap<Resources>>(\n config: ResourceConfigInput<Resources, Config>,\n) => CreatedResourceConfig<Resources>;\n\ntype SubResourceParam =\n | string\n | {\n resource: string;\n subResource: SubResourceParam;\n };\n\nfunction resolveResourceConfigEntry(\n entry: ResourceConfigEntry,\n subResource: SubResourceParam,\n): ResourceConfigEntry {\n if (typeof subResource === 'string') {\n const next = entry.subResources?.[subResource];\n if (!next) {\n throw new Error(`Sub-resource \"${subResource}\" is not configured`);\n }\n return next;\n }\n\n const next = entry.subResources?.[subResource.resource];\n if (!next) {\n throw new Error(`Sub-resource \"${subResource.resource}\" is not configured`);\n }\n\n return resolveResourceConfigEntry(next, subResource.subResource);\n}\n\nfunction readResourceConfigComponent(\n entry: ResourceConfigComponents,\n componentKey: ResourceConfigComponentKey,\n): JSX.Element {\n if (componentKey === 'new' || componentKey === 'detail') {\n const branch = entry[componentKey];\n\n if (!branch?.component) {\n throw new Error(`Missing \"${componentKey}.component\" configuration`);\n }\n\n return branch.component;\n }\n\n const value = entry[componentKey];\n\n if (!value) {\n throw new Error(`Missing \"${componentKey}\" configuration`);\n }\n\n return value;\n}\n\nfunction getComponentFromOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(\n config: ResourceConfigMap<Resources>,\n options: GetComponentOptions<Resources>,\n): JSX.Element {\n const { resource, component: componentKey = 'component' } = options;\n const resourceEntry = config[resource];\n\n if (!resourceEntry) {\n throw new Error(`Resource \"${resource}\" is not configured`);\n }\n\n let entry: ResourceConfigEntry = resourceEntry;\n\n if ('subResource' in options && options.subResource !== undefined) {\n entry = resolveResourceConfigEntry(entry, options.subResource);\n }\n\n return readResourceConfigComponent(entry, componentKey);\n}\n\nexport function createGetComponent<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(config: ResourceConfigMap<Resources>): GetComponent<Resources> {\n function getComponent<const Options extends GetComponentOptions<Resources>>(\n options: Options,\n ) {\n return getComponentFromOptions(config, options);\n }\n\n const forResource: GetComponentForResource<Resources> = (bound) => {\n return (options) =>\n getComponentFromOptions(config, {\n ...bound,\n ...options,\n } as unknown as GetComponentOptions<Resources>);\n };\n\n return Object.assign(getComponent, { forResource });\n}\n\nexport function createResourceConfig<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(config: ResourceConfigMap<Resources>): CreatedResourceConfig<Resources> {\n return {\n config,\n getComponent: createGetComponent(config),\n };\n}\n"],"mappings":";;AAyLA,SAAS,2BACP,OACA,aACqB;CACrB,IAAI,OAAO,gBAAgB,UAAU;EACnC,MAAM,OAAO,MAAM,eAAe;EAClC,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,iBAAiB,YAAY,oBAAoB;EAEnE,OAAO;CACT;CAEA,MAAM,OAAO,MAAM,eAAe,YAAY;CAC9C,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,iBAAiB,YAAY,SAAS,oBAAoB;CAG5E,OAAO,2BAA2B,MAAM,YAAY,WAAW;AACjE;AAEA,SAAS,4BACP,OACA,cACa;CACb,IAAI,iBAAiB,SAAS,iBAAiB,UAAU;EACvD,MAAM,SAAS,MAAM;EAErB,IAAI,CAAC,QAAQ,WACX,MAAM,IAAI,MAAM,YAAY,aAAa,0BAA0B;EAGrE,OAAO,OAAO;CAChB;CAEA,MAAM,QAAQ,MAAM;CAEpB,IAAI,CAAC,OACH,MAAM,IAAI,MAAM,YAAY,aAAa,gBAAgB;CAG3D,OAAO;AACT;AAEA,SAAS,wBAGP,QACA,SACa;CACb,MAAM,EAAE,UAAU,WAAW,eAAe,gBAAgB;CAC5D,MAAM,gBAAgB,OAAO;CAE7B,IAAI,CAAC,eACH,MAAM,IAAI,MAAM,aAAa,SAAS,oBAAoB;CAG5D,IAAI,QAA6B;CAEjC,IAAI,iBAAiB,WAAW,QAAQ,gBAAgB,QACtD,QAAQ,2BAA2B,OAAO,QAAQ,WAAW;CAG/D,OAAO,4BAA4B,OAAO,YAAY;AACxD;AAEA,SAAgB,mBAEd,QAA+D;CAC/D,SAAS,aACP,SACA;EACA,OAAO,wBAAwB,QAAQ,OAAO;CAChD;CAEA,MAAM,eAAmD,UAAU;EACjE,QAAQ,YACN,wBAAwB,QAAQ;GAC9B,GAAG;GACH,GAAG;EACL,CAA8C;CAClD;CAEA,OAAO,OAAO,OAAO,cAAc,EAAE,YAAY,CAAC;AACpD;AAEA,SAAgB,qBAEd,QAAwE;CACxE,OAAO;EACL;EACA,cAAc,mBAAmB,MAAM;CACzC;AACF"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { LayoutResourceKey, ResourceDefinition, SubResourceDefinitionsFor, SubResourceParamForResource } from "../resource.cjs";
|
|
2
|
+
import { ResourceConfigComponentKey, ResourceConfigInput, ResourceConfigMap } from "./types.cjs";
|
|
3
|
+
import { JSX } from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/create-config/get-component.d.ts
|
|
6
|
+
type ResourceHasLayoutSubResources<Resources extends ReadonlyArray<ResourceDefinition>, Resource extends LayoutResourceKey<Resources>> = [SubResourceDefinitionsFor<Resources, Resource>] extends [readonly []] ? false : true;
|
|
7
|
+
type SubResourceOptionForGenerics<Resources extends ReadonlyArray<ResourceDefinition>, Resource extends LayoutResourceKey<Resources>, SubResource extends SubResourceParamForResource<Resources, Resource> | undefined> = [SubResource] extends [undefined] ? ResourceHasLayoutSubResources<Resources, Resource> extends true ? {
|
|
8
|
+
subResource?: SubResourceParamForResource<Resources, Resource>;
|
|
9
|
+
} : {} : ResourceHasLayoutSubResources<Resources, Resource> extends true ? {
|
|
10
|
+
subResource?: SubResource;
|
|
11
|
+
} : {};
|
|
12
|
+
/** Options for one layout resource passed to {@link GetComponent}. */
|
|
13
|
+
type GetComponentOptionsForResource<Resources extends ReadonlyArray<ResourceDefinition>, Resource extends LayoutResourceKey<Resources>, SubResource extends SubResourceParamForResource<Resources, Resource> | undefined = undefined> = SubResourceOptionForGenerics<Resources, Resource, SubResource> & {
|
|
14
|
+
resource: Resource;
|
|
15
|
+
/**
|
|
16
|
+
* The component to get.
|
|
17
|
+
*
|
|
18
|
+
* @default 'component'
|
|
19
|
+
*/
|
|
20
|
+
component?: ResourceConfigComponentKey;
|
|
21
|
+
};
|
|
22
|
+
/** Union of valid `getComponent` option shapes for each declared layout resource. */
|
|
23
|
+
type GetComponentOptions<Resources extends ReadonlyArray<ResourceDefinition>> = LayoutResourceKey<Resources> extends infer Resource ? Resource extends LayoutResourceKey<Resources> ? GetComponentOptionsForResource<Resources, Resource> : never : never;
|
|
24
|
+
/** `subResource` bound by {@link GetComponentForResource}. */
|
|
25
|
+
type SubResourceFromGetComponentBound<Bound> = Bound extends {
|
|
26
|
+
subResource: infer SubResource;
|
|
27
|
+
} ? SubResource : undefined;
|
|
28
|
+
/** Options for {@link GetComponentForResource} — binds `resource` and optional `subResource`. */
|
|
29
|
+
type GetComponentForResourceOptions<Resources extends ReadonlyArray<ResourceDefinition>, Resource extends LayoutResourceKey<Resources>, SubResource extends SubResourceParamForResource<Resources, Resource> | undefined = undefined> = {
|
|
30
|
+
resource: Resource;
|
|
31
|
+
} & SubResourceOptionForGenerics<Resources, Resource, SubResource>;
|
|
32
|
+
type GetComponentForResourceOptionsForBound<Resources extends ReadonlyArray<ResourceDefinition>, Bound extends {
|
|
33
|
+
resource: LayoutResourceKey<Resources>;
|
|
34
|
+
}> = GetComponentForResourceOptions<Resources, Bound['resource'], SubResourceFromGetComponentBound<Bound>>;
|
|
35
|
+
/**
|
|
36
|
+
* Rejects bind objects with keys (e.g. `subResource`) that are invalid for the
|
|
37
|
+
* given `resource`. Union assignability alone is too permissive for excess keys.
|
|
38
|
+
*/
|
|
39
|
+
type ValidateForResourceBound<Resources extends ReadonlyArray<ResourceDefinition>, Bound extends {
|
|
40
|
+
resource: LayoutResourceKey<Resources>;
|
|
41
|
+
}> = Bound extends GetComponentForResourceOptionsForBound<Resources, Bound> ? keyof Bound extends keyof GetComponentForResourceOptionsForBound<Resources, Bound> ? Bound : never : never;
|
|
42
|
+
/** `resource` inferred from a {@link GetComponentForResource} bind argument. */
|
|
43
|
+
type ResourceFromGetComponentBound<Resources extends ReadonlyArray<ResourceDefinition>, Bound> = Bound extends {
|
|
44
|
+
resource: infer Resource extends LayoutResourceKey<Resources>;
|
|
45
|
+
} ? Resource : never;
|
|
46
|
+
/** Reusable getter returned by {@link GetComponentForResource} (only `component` remains). */
|
|
47
|
+
type GetComponentAtBound<Resources extends ReadonlyArray<ResourceDefinition>, Resource extends LayoutResourceKey<Resources>, SubResource extends SubResourceParamForResource<Resources, Resource> | undefined = undefined> = (options?: Pick<GetComponentOptionsForResource<Resources, Resource, SubResource>, 'component'>) => JSX.Element;
|
|
48
|
+
type GetComponentForResource<Resources extends ReadonlyArray<ResourceDefinition>> = <const Bound extends {
|
|
49
|
+
resource: LayoutResourceKey<Resources>;
|
|
50
|
+
}>(bound: ValidateForResourceBound<Resources, Bound>) => GetComponentAtBound<Resources, ResourceFromGetComponentBound<Resources, Bound>, SubResourceFromGetComponentBound<Bound>>;
|
|
51
|
+
interface GetComponent<Resources extends ReadonlyArray<ResourceDefinition>> {
|
|
52
|
+
<const Options extends GetComponentOptions<Resources>>(options: Options): JSX.Element;
|
|
53
|
+
forResource: GetComponentForResource<Resources>;
|
|
54
|
+
}
|
|
55
|
+
interface CreatedResourceConfig<Resources extends ReadonlyArray<ResourceDefinition>> {
|
|
56
|
+
config: ResourceConfigMap<Resources>;
|
|
57
|
+
getComponent: GetComponent<Resources>;
|
|
58
|
+
}
|
|
59
|
+
type CreateResourceConfigFn<Resources extends ReadonlyArray<ResourceDefinition>> = <const Config extends ResourceConfigMap<Resources>>(config: ResourceConfigInput<Resources, Config>) => CreatedResourceConfig<Resources>;
|
|
60
|
+
//#endregion
|
|
61
|
+
export { CreateResourceConfigFn, CreatedResourceConfig, GetComponent, GetComponentAtBound, GetComponentForResource, GetComponentForResourceOptions, GetComponentOptions, GetComponentOptionsForResource, ResourceFromGetComponentBound, SubResourceFromGetComponentBound, ValidateForResourceBound };
|
|
62
|
+
//# sourceMappingURL=get-component.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-component.d.cts","names":[],"sources":["../../src/create-config/get-component.ts"],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { LayoutResourceKey, ResourceDefinition, SubResourceDefinitionsFor, SubResourceParamForResource } from "../resource.mjs";
|
|
2
|
+
import { ResourceConfigComponentKey, ResourceConfigInput, ResourceConfigMap } from "./types.mjs";
|
|
3
|
+
import { JSX } from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/create-config/get-component.d.ts
|
|
6
|
+
type ResourceHasLayoutSubResources<Resources extends ReadonlyArray<ResourceDefinition>, Resource extends LayoutResourceKey<Resources>> = [SubResourceDefinitionsFor<Resources, Resource>] extends [readonly []] ? false : true;
|
|
7
|
+
type SubResourceOptionForGenerics<Resources extends ReadonlyArray<ResourceDefinition>, Resource extends LayoutResourceKey<Resources>, SubResource extends SubResourceParamForResource<Resources, Resource> | undefined> = [SubResource] extends [undefined] ? ResourceHasLayoutSubResources<Resources, Resource> extends true ? {
|
|
8
|
+
subResource?: SubResourceParamForResource<Resources, Resource>;
|
|
9
|
+
} : {} : ResourceHasLayoutSubResources<Resources, Resource> extends true ? {
|
|
10
|
+
subResource?: SubResource;
|
|
11
|
+
} : {};
|
|
12
|
+
/** Options for one layout resource passed to {@link GetComponent}. */
|
|
13
|
+
type GetComponentOptionsForResource<Resources extends ReadonlyArray<ResourceDefinition>, Resource extends LayoutResourceKey<Resources>, SubResource extends SubResourceParamForResource<Resources, Resource> | undefined = undefined> = SubResourceOptionForGenerics<Resources, Resource, SubResource> & {
|
|
14
|
+
resource: Resource;
|
|
15
|
+
/**
|
|
16
|
+
* The component to get.
|
|
17
|
+
*
|
|
18
|
+
* @default 'component'
|
|
19
|
+
*/
|
|
20
|
+
component?: ResourceConfigComponentKey;
|
|
21
|
+
};
|
|
22
|
+
/** Union of valid `getComponent` option shapes for each declared layout resource. */
|
|
23
|
+
type GetComponentOptions<Resources extends ReadonlyArray<ResourceDefinition>> = LayoutResourceKey<Resources> extends infer Resource ? Resource extends LayoutResourceKey<Resources> ? GetComponentOptionsForResource<Resources, Resource> : never : never;
|
|
24
|
+
/** `subResource` bound by {@link GetComponentForResource}. */
|
|
25
|
+
type SubResourceFromGetComponentBound<Bound> = Bound extends {
|
|
26
|
+
subResource: infer SubResource;
|
|
27
|
+
} ? SubResource : undefined;
|
|
28
|
+
/** Options for {@link GetComponentForResource} — binds `resource` and optional `subResource`. */
|
|
29
|
+
type GetComponentForResourceOptions<Resources extends ReadonlyArray<ResourceDefinition>, Resource extends LayoutResourceKey<Resources>, SubResource extends SubResourceParamForResource<Resources, Resource> | undefined = undefined> = {
|
|
30
|
+
resource: Resource;
|
|
31
|
+
} & SubResourceOptionForGenerics<Resources, Resource, SubResource>;
|
|
32
|
+
type GetComponentForResourceOptionsForBound<Resources extends ReadonlyArray<ResourceDefinition>, Bound extends {
|
|
33
|
+
resource: LayoutResourceKey<Resources>;
|
|
34
|
+
}> = GetComponentForResourceOptions<Resources, Bound['resource'], SubResourceFromGetComponentBound<Bound>>;
|
|
35
|
+
/**
|
|
36
|
+
* Rejects bind objects with keys (e.g. `subResource`) that are invalid for the
|
|
37
|
+
* given `resource`. Union assignability alone is too permissive for excess keys.
|
|
38
|
+
*/
|
|
39
|
+
type ValidateForResourceBound<Resources extends ReadonlyArray<ResourceDefinition>, Bound extends {
|
|
40
|
+
resource: LayoutResourceKey<Resources>;
|
|
41
|
+
}> = Bound extends GetComponentForResourceOptionsForBound<Resources, Bound> ? keyof Bound extends keyof GetComponentForResourceOptionsForBound<Resources, Bound> ? Bound : never : never;
|
|
42
|
+
/** `resource` inferred from a {@link GetComponentForResource} bind argument. */
|
|
43
|
+
type ResourceFromGetComponentBound<Resources extends ReadonlyArray<ResourceDefinition>, Bound> = Bound extends {
|
|
44
|
+
resource: infer Resource extends LayoutResourceKey<Resources>;
|
|
45
|
+
} ? Resource : never;
|
|
46
|
+
/** Reusable getter returned by {@link GetComponentForResource} (only `component` remains). */
|
|
47
|
+
type GetComponentAtBound<Resources extends ReadonlyArray<ResourceDefinition>, Resource extends LayoutResourceKey<Resources>, SubResource extends SubResourceParamForResource<Resources, Resource> | undefined = undefined> = (options?: Pick<GetComponentOptionsForResource<Resources, Resource, SubResource>, 'component'>) => JSX.Element;
|
|
48
|
+
type GetComponentForResource<Resources extends ReadonlyArray<ResourceDefinition>> = <const Bound extends {
|
|
49
|
+
resource: LayoutResourceKey<Resources>;
|
|
50
|
+
}>(bound: ValidateForResourceBound<Resources, Bound>) => GetComponentAtBound<Resources, ResourceFromGetComponentBound<Resources, Bound>, SubResourceFromGetComponentBound<Bound>>;
|
|
51
|
+
interface GetComponent<Resources extends ReadonlyArray<ResourceDefinition>> {
|
|
52
|
+
<const Options extends GetComponentOptions<Resources>>(options: Options): JSX.Element;
|
|
53
|
+
forResource: GetComponentForResource<Resources>;
|
|
54
|
+
}
|
|
55
|
+
interface CreatedResourceConfig<Resources extends ReadonlyArray<ResourceDefinition>> {
|
|
56
|
+
config: ResourceConfigMap<Resources>;
|
|
57
|
+
getComponent: GetComponent<Resources>;
|
|
58
|
+
}
|
|
59
|
+
type CreateResourceConfigFn<Resources extends ReadonlyArray<ResourceDefinition>> = <const Config extends ResourceConfigMap<Resources>>(config: ResourceConfigInput<Resources, Config>) => CreatedResourceConfig<Resources>;
|
|
60
|
+
//#endregion
|
|
61
|
+
export { CreateResourceConfigFn, CreatedResourceConfig, GetComponent, GetComponentAtBound, GetComponentForResource, GetComponentForResourceOptions, GetComponentOptions, GetComponentOptionsForResource, ResourceFromGetComponentBound, SubResourceFromGetComponentBound, ValidateForResourceBound };
|
|
62
|
+
//# sourceMappingURL=get-component.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-component.d.mts","names":[],"sources":["../../src/create-config/get-component.ts"],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
//#region src/create-config/get-component.ts
|
|
2
|
+
function resolveResourceConfigEntry(entry, subResource) {
|
|
3
|
+
if (typeof subResource === "string") {
|
|
4
|
+
const next = entry.subResources?.[subResource];
|
|
5
|
+
if (!next) throw new Error(`Sub-resource "${subResource}" is not configured`);
|
|
6
|
+
return next;
|
|
7
|
+
}
|
|
8
|
+
const next = entry.subResources?.[subResource.resource];
|
|
9
|
+
if (!next) throw new Error(`Sub-resource "${subResource.resource}" is not configured`);
|
|
10
|
+
return resolveResourceConfigEntry(next, subResource.subResource);
|
|
11
|
+
}
|
|
12
|
+
function readResourceConfigComponent(entry, componentKey) {
|
|
13
|
+
if (componentKey === "new" || componentKey === "detail") {
|
|
14
|
+
const branch = entry[componentKey];
|
|
15
|
+
if (!branch?.component) throw new Error(`Missing "${componentKey}.component" configuration`);
|
|
16
|
+
return branch.component;
|
|
17
|
+
}
|
|
18
|
+
const value = entry[componentKey];
|
|
19
|
+
if (!value) throw new Error(`Missing "${componentKey}" configuration`);
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
function getComponentFromOptions(config, options) {
|
|
23
|
+
const { resource, component: componentKey = "component" } = options;
|
|
24
|
+
const resourceEntry = config[resource];
|
|
25
|
+
if (!resourceEntry) throw new Error(`Resource "${resource}" is not configured`);
|
|
26
|
+
let entry = resourceEntry;
|
|
27
|
+
if ("subResource" in options && options.subResource !== void 0) entry = resolveResourceConfigEntry(entry, options.subResource);
|
|
28
|
+
return readResourceConfigComponent(entry, componentKey);
|
|
29
|
+
}
|
|
30
|
+
function createGetComponent(config) {
|
|
31
|
+
function getComponent(options) {
|
|
32
|
+
return getComponentFromOptions(config, options);
|
|
33
|
+
}
|
|
34
|
+
const forResource = (bound) => {
|
|
35
|
+
return (options) => getComponentFromOptions(config, {
|
|
36
|
+
...bound,
|
|
37
|
+
...options
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
return Object.assign(getComponent, { forResource });
|
|
41
|
+
}
|
|
42
|
+
function createResourceConfig(config) {
|
|
43
|
+
return {
|
|
44
|
+
config,
|
|
45
|
+
getComponent: createGetComponent(config)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
export { createResourceConfig };
|
|
51
|
+
//# sourceMappingURL=get-component.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-component.mjs","names":[],"sources":["../../src/create-config/get-component.ts"],"sourcesContent":["import type { JSX } from 'react';\nimport type {\n LayoutResourceKey,\n ResourceDefinition,\n SubResourceDefinitionsFor,\n SubResourceParamForResource,\n} from '../resource';\nimport type {\n ResourceConfigComponentKey,\n ResourceConfigComponents,\n ResourceConfigEntry,\n ResourceConfigMap,\n ResourceConfigInput,\n} from './types';\n\ntype ResourceHasLayoutSubResources<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n> = [SubResourceDefinitionsFor<Resources, Resource>] extends [readonly []]\n ? false\n : true;\n\ntype SubResourceOptionForGenerics<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined,\n> = [SubResource] extends [undefined]\n ? ResourceHasLayoutSubResources<Resources, Resource> extends true\n ? {\n subResource?: SubResourceParamForResource<Resources, Resource>;\n }\n : {}\n : ResourceHasLayoutSubResources<Resources, Resource> extends true\n ? { subResource?: SubResource }\n : {};\n\n/** Options for one layout resource passed to {@link GetComponent}. */\nexport type GetComponentOptionsForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined = undefined,\n> = SubResourceOptionForGenerics<Resources, Resource, SubResource> & {\n resource: Resource;\n /**\n * The component to get.\n *\n * @default 'component'\n */\n component?: ResourceConfigComponentKey;\n};\n\n/** Union of valid `getComponent` option shapes for each declared layout resource. */\nexport type GetComponentOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> =\n LayoutResourceKey<Resources> extends infer Resource\n ? Resource extends LayoutResourceKey<Resources>\n ? GetComponentOptionsForResource<Resources, Resource>\n : never\n : never;\n\n/** `subResource` bound by {@link GetComponentForResource}. */\nexport type SubResourceFromGetComponentBound<Bound> = Bound extends {\n subResource: infer SubResource;\n}\n ? SubResource\n : undefined;\n\n/** Options for {@link GetComponentForResource} — binds `resource` and optional `subResource`. */\nexport type GetComponentForResourceOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined = undefined,\n> = {\n resource: Resource;\n} & SubResourceOptionForGenerics<Resources, Resource, SubResource>;\n\n/** Valid bind shapes for {@link GetComponentForResource}. */\nexport type GetComponentForResourceBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> =\n LayoutResourceKey<Resources> extends infer Resource\n ? Resource extends LayoutResourceKey<Resources>\n ? GetComponentForResourceOptions<Resources, Resource>\n : never\n : never;\n\ntype GetComponentForResourceOptionsForBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Bound extends { resource: LayoutResourceKey<Resources> },\n> = GetComponentForResourceOptions<\n Resources,\n Bound['resource'],\n SubResourceFromGetComponentBound<Bound>\n>;\n\n/**\n * Rejects bind objects with keys (e.g. `subResource`) that are invalid for the\n * given `resource`. Union assignability alone is too permissive for excess keys.\n */\nexport type ValidateForResourceBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Bound extends { resource: LayoutResourceKey<Resources> },\n> = Bound extends GetComponentForResourceOptionsForBound<Resources, Bound>\n ? keyof Bound extends keyof GetComponentForResourceOptionsForBound<\n Resources,\n Bound\n >\n ? Bound\n : never\n : never;\n\n/** `resource` inferred from a {@link GetComponentForResource} bind argument. */\nexport type ResourceFromGetComponentBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Bound,\n> = Bound extends {\n resource: infer Resource extends LayoutResourceKey<Resources>;\n}\n ? Resource\n : never;\n\n/** Reusable getter returned by {@link GetComponentForResource} (only `component` remains). */\nexport type GetComponentAtBound<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n SubResource extends\n | SubResourceParamForResource<Resources, Resource>\n | undefined = undefined,\n> = (\n options?: Pick<\n GetComponentOptionsForResource<Resources, Resource, SubResource>,\n 'component'\n >,\n) => JSX.Element;\n\nexport type GetComponentForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = <\n const Bound extends {\n resource: LayoutResourceKey<Resources>;\n },\n>(\n bound: ValidateForResourceBound<Resources, Bound>,\n) => GetComponentAtBound<\n Resources,\n ResourceFromGetComponentBound<Resources, Bound>,\n SubResourceFromGetComponentBound<Bound>\n>;\n\nexport interface GetComponent<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> {\n <const Options extends GetComponentOptions<Resources>>(\n options: Options,\n ): JSX.Element;\n forResource: GetComponentForResource<Resources>;\n}\n\nexport interface CreatedResourceConfig<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> {\n config: ResourceConfigMap<Resources>;\n getComponent: GetComponent<Resources>;\n}\n\nexport type CreateResourceConfigFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = <const Config extends ResourceConfigMap<Resources>>(\n config: ResourceConfigInput<Resources, Config>,\n) => CreatedResourceConfig<Resources>;\n\ntype SubResourceParam =\n | string\n | {\n resource: string;\n subResource: SubResourceParam;\n };\n\nfunction resolveResourceConfigEntry(\n entry: ResourceConfigEntry,\n subResource: SubResourceParam,\n): ResourceConfigEntry {\n if (typeof subResource === 'string') {\n const next = entry.subResources?.[subResource];\n if (!next) {\n throw new Error(`Sub-resource \"${subResource}\" is not configured`);\n }\n return next;\n }\n\n const next = entry.subResources?.[subResource.resource];\n if (!next) {\n throw new Error(`Sub-resource \"${subResource.resource}\" is not configured`);\n }\n\n return resolveResourceConfigEntry(next, subResource.subResource);\n}\n\nfunction readResourceConfigComponent(\n entry: ResourceConfigComponents,\n componentKey: ResourceConfigComponentKey,\n): JSX.Element {\n if (componentKey === 'new' || componentKey === 'detail') {\n const branch = entry[componentKey];\n\n if (!branch?.component) {\n throw new Error(`Missing \"${componentKey}.component\" configuration`);\n }\n\n return branch.component;\n }\n\n const value = entry[componentKey];\n\n if (!value) {\n throw new Error(`Missing \"${componentKey}\" configuration`);\n }\n\n return value;\n}\n\nfunction getComponentFromOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(\n config: ResourceConfigMap<Resources>,\n options: GetComponentOptions<Resources>,\n): JSX.Element {\n const { resource, component: componentKey = 'component' } = options;\n const resourceEntry = config[resource];\n\n if (!resourceEntry) {\n throw new Error(`Resource \"${resource}\" is not configured`);\n }\n\n let entry: ResourceConfigEntry = resourceEntry;\n\n if ('subResource' in options && options.subResource !== undefined) {\n entry = resolveResourceConfigEntry(entry, options.subResource);\n }\n\n return readResourceConfigComponent(entry, componentKey);\n}\n\nexport function createGetComponent<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(config: ResourceConfigMap<Resources>): GetComponent<Resources> {\n function getComponent<const Options extends GetComponentOptions<Resources>>(\n options: Options,\n ) {\n return getComponentFromOptions(config, options);\n }\n\n const forResource: GetComponentForResource<Resources> = (bound) => {\n return (options) =>\n getComponentFromOptions(config, {\n ...bound,\n ...options,\n } as unknown as GetComponentOptions<Resources>);\n };\n\n return Object.assign(getComponent, { forResource });\n}\n\nexport function createResourceConfig<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(config: ResourceConfigMap<Resources>): CreatedResourceConfig<Resources> {\n return {\n config,\n getComponent: createGetComponent(config),\n };\n}\n"],"mappings":";AAyLA,SAAS,2BACP,OACA,aACqB;CACrB,IAAI,OAAO,gBAAgB,UAAU;EACnC,MAAM,OAAO,MAAM,eAAe;EAClC,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,iBAAiB,YAAY,oBAAoB;EAEnE,OAAO;CACT;CAEA,MAAM,OAAO,MAAM,eAAe,YAAY;CAC9C,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,iBAAiB,YAAY,SAAS,oBAAoB;CAG5E,OAAO,2BAA2B,MAAM,YAAY,WAAW;AACjE;AAEA,SAAS,4BACP,OACA,cACa;CACb,IAAI,iBAAiB,SAAS,iBAAiB,UAAU;EACvD,MAAM,SAAS,MAAM;EAErB,IAAI,CAAC,QAAQ,WACX,MAAM,IAAI,MAAM,YAAY,aAAa,0BAA0B;EAGrE,OAAO,OAAO;CAChB;CAEA,MAAM,QAAQ,MAAM;CAEpB,IAAI,CAAC,OACH,MAAM,IAAI,MAAM,YAAY,aAAa,gBAAgB;CAG3D,OAAO;AACT;AAEA,SAAS,wBAGP,QACA,SACa;CACb,MAAM,EAAE,UAAU,WAAW,eAAe,gBAAgB;CAC5D,MAAM,gBAAgB,OAAO;CAE7B,IAAI,CAAC,eACH,MAAM,IAAI,MAAM,aAAa,SAAS,oBAAoB;CAG5D,IAAI,QAA6B;CAEjC,IAAI,iBAAiB,WAAW,QAAQ,gBAAgB,QACtD,QAAQ,2BAA2B,OAAO,QAAQ,WAAW;CAG/D,OAAO,4BAA4B,OAAO,YAAY;AACxD;AAEA,SAAgB,mBAEd,QAA+D;CAC/D,SAAS,aACP,SACA;EACA,OAAO,wBAAwB,QAAQ,OAAO;CAChD;CAEA,MAAM,eAAmD,UAAU;EACjE,QAAQ,YACN,wBAAwB,QAAQ;GAC9B,GAAG;GACH,GAAG;EACL,CAA8C;CAClD;CAEA,OAAO,OAAO,OAAO,cAAc,EAAE,YAAY,CAAC;AACpD;AAEA,SAAgB,qBAEd,QAAwE;CACxE,OAAO;EACL;EACA,cAAc,mBAAmB,MAAM;CACzC;AACF"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { BaseResourceConfigComponents, ResourceConfig, ResourceConfigComponentKey, ResourceConfigComponents, ResourceConfigInput, ResourceConfigMap, SharedResourceConfigOptions, SubResourceConfig, SubResourceConfigComponentsFor } from "./types.cjs";
|
|
2
|
+
import { CreateResourceConfigFn, CreatedResourceConfig, GetComponent, GetComponentAtBound, GetComponentForResource, GetComponentForResourceOptions, GetComponentOptions, GetComponentOptionsForResource, ResourceFromGetComponentBound, SubResourceFromGetComponentBound, ValidateForResourceBound } from "./get-component.cjs";
|
|
3
|
+
import { CreateResourceLayoutFn, defineResourceLayout } from "./define-layout.cjs";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { BaseResourceConfigComponents, ResourceConfig, ResourceConfigComponentKey, ResourceConfigComponents, ResourceConfigInput, ResourceConfigMap, SharedResourceConfigOptions, SubResourceConfig, SubResourceConfigComponentsFor } from "./types.mjs";
|
|
2
|
+
import { CreateResourceConfigFn, CreatedResourceConfig, GetComponent, GetComponentAtBound, GetComponentForResource, GetComponentForResourceOptions, GetComponentOptions, GetComponentOptionsForResource, ResourceFromGetComponentBound, SubResourceFromGetComponentBound, ValidateForResourceBound } from "./get-component.mjs";
|
|
3
|
+
import { CreateResourceLayoutFn, defineResourceLayout } from "./define-layout.mjs";
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { LayoutResourceKey, ResourceDefinition, ResourceDefinitionForKey, SubResourceDefinitionsFor } from "../resource.cjs";
|
|
2
|
+
import { JSX } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/create-config/types.d.ts
|
|
5
|
+
type BaseResourceConfigComponents = {
|
|
6
|
+
component: JSX.Element;
|
|
7
|
+
errorComponent?: JSX.Element;
|
|
8
|
+
pendingComponent?: JSX.Element;
|
|
9
|
+
notFoundComponent?: JSX.Element;
|
|
10
|
+
};
|
|
11
|
+
type SharedResourceConfigOptions = {
|
|
12
|
+
/**
|
|
13
|
+
* Configuration for the new resource.
|
|
14
|
+
*/
|
|
15
|
+
new?: BaseResourceConfigComponents;
|
|
16
|
+
/**
|
|
17
|
+
* Configuration for the detail resource.
|
|
18
|
+
*/
|
|
19
|
+
detail?: BaseResourceConfigComponents;
|
|
20
|
+
};
|
|
21
|
+
type ResourceConfigComponents = BaseResourceConfigComponents & SharedResourceConfigOptions;
|
|
22
|
+
type ResourceConfigComponentKey = keyof ResourceConfigComponents;
|
|
23
|
+
/** Config entry for one sub-resource node (recurses when the layout tree has children). */
|
|
24
|
+
type SubResourceConfigComponentsFor<Resources extends ReadonlyArray<ResourceDefinition>, SubDef extends ResourceDefinition> = ResourceConfigComponents & (SubDef extends {
|
|
25
|
+
subResources: infer Nested extends ReadonlyArray<ResourceDefinition>;
|
|
26
|
+
} ? {
|
|
27
|
+
subResources?: { [K in LayoutResourceKey<Nested>]?: SubResourceConfigComponentsFor<Resources, ResourceDefinitionForKey<Nested, K>> };
|
|
28
|
+
} : {});
|
|
29
|
+
type SubResourceConfig<Resources extends ReadonlyArray<ResourceDefinition>, Resource extends LayoutResourceKey<Resources>> = [SubResourceDefinitionsFor<Resources, Resource>] extends [readonly []] ? {} : {
|
|
30
|
+
subResources?: { [K in LayoutResourceKey<SubResourceDefinitionsFor<Resources, Resource>>]?: SubResourceConfigComponentsFor<Resources, ResourceDefinitionForKey<SubResourceDefinitionsFor<Resources, Resource>, K>> };
|
|
31
|
+
};
|
|
32
|
+
type ResourceConfig<Resources extends ReadonlyArray<ResourceDefinition>> = { [resource in LayoutResourceKey<Resources>]: ResourceConfigComponents & SubResourceConfig<Resources, resource> };
|
|
33
|
+
/**
|
|
34
|
+
* Parameter type for {@link CreateResourceConfigFn}. Intersects the inferred `Config`
|
|
35
|
+
* with the full optional resource map so editors can suggest keys while `Config`
|
|
36
|
+
* stays narrowed to the keys and values you actually pass.
|
|
37
|
+
*/
|
|
38
|
+
type ResourceConfigInput<Resources extends ReadonlyArray<ResourceDefinition>, Config extends Partial<ResourceConfig<Resources>>> = Partial<ResourceConfig<Resources>> & Config;
|
|
39
|
+
type ResourceConfigMap<Resources extends ReadonlyArray<ResourceDefinition>> = Partial<ResourceConfig<Resources>>;
|
|
40
|
+
//#endregion
|
|
41
|
+
export { BaseResourceConfigComponents, ResourceConfig, ResourceConfigComponentKey, ResourceConfigComponents, ResourceConfigInput, ResourceConfigMap, SharedResourceConfigOptions, SubResourceConfig, SubResourceConfigComponentsFor };
|
|
42
|
+
//# sourceMappingURL=types.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.cts","names":[],"sources":["../../src/create-config/types.ts"],"mappings":";;;;KAQY,4BAAA;EACV,SAAA,EAAW,GAAA,CAAI,OAAA;EACf,cAAA,GAAiB,GAAA,CAAI,OAAA;EACrB,gBAAA,GAAmB,GAAA,CAAI,OAAA;EACvB,iBAAA,GAAoB,GAAA,CAAI,OAAA;AAAA;AAAA,KASd,2BAAA;EATqB;;;EAa/B,GAAA,GAAM,4BAAA;EAhBS;;;EAoBf,MAAA,GAAS,4BAA4B;AAAA;AAAA,KAG3B,wBAAA,GAA2B,4BAAA,GACrC,2BAA2B;AAAA,KAEjB,0BAAA,SAAmC,wBAAwB;;KAG3D,8BAAA,mBACQ,aAAA,CAAc,kBAAA,kBACjB,kBAAA,IACb,wBAAA,IACD,MAAA;EACC,YAAA,uBAAmC,aAAA,CAAc,kBAAA;AAAA;EAG7C,YAAA,WACQ,iBAAA,CAAkB,MAAA,KAAW,8BAAA,CACjC,SAAA,EACA,wBAAA,CAAyB,MAAA,EAAQ,CAAA;AAAA;AAAA,KAMjC,iBAAA,mBACQ,aAAA,CAAc,kBAAA,oBACf,iBAAA,CAAkB,SAAA,MAChC,yBAAA,CAA0B,SAAA,EAAW,QAAA;EAGpC,YAAA,WACQ,iBAAA,CACJ,yBAAA,CAA0B,SAAA,EAAW,QAAA,MAClC,8BAAA,CACH,SAAA,EACA,wBAAA,CACE,yBAAA,CAA0B,SAAA,EAAW,QAAA,GACrC,CAAA;AAAA;AAAA,KAMA,cAAA,mBACQ,aAAA,CAAc,kBAAA,oBAEnB,iBAAA,CAAkB,SAAA,IAAa,wBAAA,GAC1C,iBAAA,CAAkB,SAAA,EAAW,QAAA;;;;AA7CJ;AAE7B;KAmDY,mBAAA,mBACQ,aAAA,CAAc,kBAAA,kBACjB,OAAA,CAAQ,cAAA,CAAe,SAAA,MACpC,OAAA,CAAQ,cAAA,CAAe,SAAA,KAAc,MAAA;AAAA,KAE7B,iBAAA,mBACQ,aAAA,CAAc,kBAAA,KAC9B,OAAA,CAAQ,cAAA,CAAe,SAAA"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { LayoutResourceKey, ResourceDefinition, ResourceDefinitionForKey, SubResourceDefinitionsFor } from "../resource.mjs";
|
|
2
|
+
import { JSX } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/create-config/types.d.ts
|
|
5
|
+
type BaseResourceConfigComponents = {
|
|
6
|
+
component: JSX.Element;
|
|
7
|
+
errorComponent?: JSX.Element;
|
|
8
|
+
pendingComponent?: JSX.Element;
|
|
9
|
+
notFoundComponent?: JSX.Element;
|
|
10
|
+
};
|
|
11
|
+
type SharedResourceConfigOptions = {
|
|
12
|
+
/**
|
|
13
|
+
* Configuration for the new resource.
|
|
14
|
+
*/
|
|
15
|
+
new?: BaseResourceConfigComponents;
|
|
16
|
+
/**
|
|
17
|
+
* Configuration for the detail resource.
|
|
18
|
+
*/
|
|
19
|
+
detail?: BaseResourceConfigComponents;
|
|
20
|
+
};
|
|
21
|
+
type ResourceConfigComponents = BaseResourceConfigComponents & SharedResourceConfigOptions;
|
|
22
|
+
type ResourceConfigComponentKey = keyof ResourceConfigComponents;
|
|
23
|
+
/** Config entry for one sub-resource node (recurses when the layout tree has children). */
|
|
24
|
+
type SubResourceConfigComponentsFor<Resources extends ReadonlyArray<ResourceDefinition>, SubDef extends ResourceDefinition> = ResourceConfigComponents & (SubDef extends {
|
|
25
|
+
subResources: infer Nested extends ReadonlyArray<ResourceDefinition>;
|
|
26
|
+
} ? {
|
|
27
|
+
subResources?: { [K in LayoutResourceKey<Nested>]?: SubResourceConfigComponentsFor<Resources, ResourceDefinitionForKey<Nested, K>> };
|
|
28
|
+
} : {});
|
|
29
|
+
type SubResourceConfig<Resources extends ReadonlyArray<ResourceDefinition>, Resource extends LayoutResourceKey<Resources>> = [SubResourceDefinitionsFor<Resources, Resource>] extends [readonly []] ? {} : {
|
|
30
|
+
subResources?: { [K in LayoutResourceKey<SubResourceDefinitionsFor<Resources, Resource>>]?: SubResourceConfigComponentsFor<Resources, ResourceDefinitionForKey<SubResourceDefinitionsFor<Resources, Resource>, K>> };
|
|
31
|
+
};
|
|
32
|
+
type ResourceConfig<Resources extends ReadonlyArray<ResourceDefinition>> = { [resource in LayoutResourceKey<Resources>]: ResourceConfigComponents & SubResourceConfig<Resources, resource> };
|
|
33
|
+
/**
|
|
34
|
+
* Parameter type for {@link CreateResourceConfigFn}. Intersects the inferred `Config`
|
|
35
|
+
* with the full optional resource map so editors can suggest keys while `Config`
|
|
36
|
+
* stays narrowed to the keys and values you actually pass.
|
|
37
|
+
*/
|
|
38
|
+
type ResourceConfigInput<Resources extends ReadonlyArray<ResourceDefinition>, Config extends Partial<ResourceConfig<Resources>>> = Partial<ResourceConfig<Resources>> & Config;
|
|
39
|
+
type ResourceConfigMap<Resources extends ReadonlyArray<ResourceDefinition>> = Partial<ResourceConfig<Resources>>;
|
|
40
|
+
//#endregion
|
|
41
|
+
export { BaseResourceConfigComponents, ResourceConfig, ResourceConfigComponentKey, ResourceConfigComponents, ResourceConfigInput, ResourceConfigMap, SharedResourceConfigOptions, SubResourceConfig, SubResourceConfigComponentsFor };
|
|
42
|
+
//# sourceMappingURL=types.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../../src/create-config/types.ts"],"mappings":";;;;KAQY,4BAAA;EACV,SAAA,EAAW,GAAA,CAAI,OAAA;EACf,cAAA,GAAiB,GAAA,CAAI,OAAA;EACrB,gBAAA,GAAmB,GAAA,CAAI,OAAA;EACvB,iBAAA,GAAoB,GAAA,CAAI,OAAA;AAAA;AAAA,KASd,2BAAA;EATqB;;;EAa/B,GAAA,GAAM,4BAAA;EAhBS;;;EAoBf,MAAA,GAAS,4BAA4B;AAAA;AAAA,KAG3B,wBAAA,GAA2B,4BAAA,GACrC,2BAA2B;AAAA,KAEjB,0BAAA,SAAmC,wBAAwB;;KAG3D,8BAAA,mBACQ,aAAA,CAAc,kBAAA,kBACjB,kBAAA,IACb,wBAAA,IACD,MAAA;EACC,YAAA,uBAAmC,aAAA,CAAc,kBAAA;AAAA;EAG7C,YAAA,WACQ,iBAAA,CAAkB,MAAA,KAAW,8BAAA,CACjC,SAAA,EACA,wBAAA,CAAyB,MAAA,EAAQ,CAAA;AAAA;AAAA,KAMjC,iBAAA,mBACQ,aAAA,CAAc,kBAAA,oBACf,iBAAA,CAAkB,SAAA,MAChC,yBAAA,CAA0B,SAAA,EAAW,QAAA;EAGpC,YAAA,WACQ,iBAAA,CACJ,yBAAA,CAA0B,SAAA,EAAW,QAAA,MAClC,8BAAA,CACH,SAAA,EACA,wBAAA,CACE,yBAAA,CAA0B,SAAA,EAAW,QAAA,GACrC,CAAA;AAAA;AAAA,KAMA,cAAA,mBACQ,aAAA,CAAc,kBAAA,oBAEnB,iBAAA,CAAkB,SAAA,IAAa,wBAAA,GAC1C,iBAAA,CAAkB,SAAA,EAAW,QAAA;;;;AA7CJ;AAE7B;KAmDY,mBAAA,mBACQ,aAAA,CAAc,kBAAA,kBACjB,OAAA,CAAQ,cAAA,CAAe,SAAA,MACpC,OAAA,CAAQ,cAAA,CAAe,SAAA,KAAc,MAAA;AAAA,KAE7B,iBAAA,mBACQ,aAAA,CAAc,kBAAA,KAC9B,OAAA,CAAQ,cAAA,CAAe,SAAA"}
|
package/dist/index.cjs
CHANGED
|
@@ -4,12 +4,12 @@ const require_composable = require('./composable.cjs');
|
|
|
4
4
|
const require_builders = require('./validators/builders.cjs');
|
|
5
5
|
const require_validate_props = require('./validators/validate-props.cjs');
|
|
6
6
|
const require_resource = require('./resource.cjs');
|
|
7
|
-
const
|
|
7
|
+
const require_define_layout = require('./create-config/define-layout.cjs');
|
|
8
8
|
|
|
9
9
|
exports.createComposableComponent = require_composable.createComposableComponent;
|
|
10
10
|
exports.createPrimitivePropBuilder = require_builders.createPrimitivePropBuilder;
|
|
11
11
|
exports.createProp = require_builders.createProp;
|
|
12
|
-
exports.defineResourceLayout =
|
|
12
|
+
exports.defineResourceLayout = require_define_layout.defineResourceLayout;
|
|
13
13
|
exports.makeComposable = require_composable.makeComposable;
|
|
14
14
|
exports.normalizeResource = require_resource.normalizeResource;
|
|
15
15
|
exports.normalizeResources = require_resource.normalizeResources;
|
package/dist/index.d.cts
CHANGED
|
@@ -5,5 +5,5 @@ import { BaseComponent, MergeIntersection, Show, UnionToIntersection, pick } fro
|
|
|
5
5
|
import { LayoutResourceKey, NormalizeResource, NormalizeResources, ResourceDefinition, ResourceEnum, ResourceLayoutComponentProps, ResourceTree, normalizeResource, normalizeResources, toResourceEnum } from "./resource.cjs";
|
|
6
6
|
import { InPropsDefinition, InPropsFunction, InPropsObject, InPropsOptions, IncludedProps, InferredInProps, LayoutRenderProps } from "./props.cjs";
|
|
7
7
|
import { ComposableComponent, ComposableComponents, ComposableNameContext, ComposableResourceLayout, CreateLayoutComposable, LayoutComposablesFactory, MakeComposable, MakeComposableOptions, createComposableComponent, makeComposable } from "./composable.cjs";
|
|
8
|
-
import { defineResourceLayout } from "./create-config.cjs";
|
|
8
|
+
import { defineResourceLayout } from "./create-config/define-layout.cjs";
|
|
9
9
|
export { type AnyBuiltPropDefinition, type BaseComponent, type ComposableComponent, type ComposableComponents, type ComposableNameContext, type ComposableResourceLayout, type CreateLayoutComposable, type InPropsDefinition, type InPropsFunction, type InPropsObject, type InPropsOptions, type IncludedProps, type InferredInProps, type LayoutComposablesFactory, type LayoutRenderProps, type LayoutResourceKey, type MakeComposable, type MakeComposableOptions, type MergeIntersection, type NormalizeResource, type NormalizeResources, type ResolveLayoutProps, type ResolveProps, type ResourceDefinition, type ResourceEnum, type ResourceLayoutComponentProps, type ResourceTree, type Show, type UnionToIntersection, createComposableComponent, createPrimitivePropBuilder, createProp, defineResourceLayout, makeComposable, normalizeResource, normalizeResources, pick, toResourceEnum, validateProps };
|
package/dist/index.d.mts
CHANGED
|
@@ -5,5 +5,5 @@ import { BaseComponent, MergeIntersection, Show, UnionToIntersection, pick } fro
|
|
|
5
5
|
import { LayoutResourceKey, NormalizeResource, NormalizeResources, ResourceDefinition, ResourceEnum, ResourceLayoutComponentProps, ResourceTree, normalizeResource, normalizeResources, toResourceEnum } from "./resource.mjs";
|
|
6
6
|
import { InPropsDefinition, InPropsFunction, InPropsObject, InPropsOptions, IncludedProps, InferredInProps, LayoutRenderProps } from "./props.mjs";
|
|
7
7
|
import { ComposableComponent, ComposableComponents, ComposableNameContext, ComposableResourceLayout, CreateLayoutComposable, LayoutComposablesFactory, MakeComposable, MakeComposableOptions, createComposableComponent, makeComposable } from "./composable.mjs";
|
|
8
|
-
import { defineResourceLayout } from "./create-config.mjs";
|
|
8
|
+
import { defineResourceLayout } from "./create-config/define-layout.mjs";
|
|
9
9
|
export { type AnyBuiltPropDefinition, type BaseComponent, type ComposableComponent, type ComposableComponents, type ComposableNameContext, type ComposableResourceLayout, type CreateLayoutComposable, type InPropsDefinition, type InPropsFunction, type InPropsObject, type InPropsOptions, type IncludedProps, type InferredInProps, type LayoutComposablesFactory, type LayoutRenderProps, type LayoutResourceKey, type MakeComposable, type MakeComposableOptions, type MergeIntersection, type NormalizeResource, type NormalizeResources, type ResolveLayoutProps, type ResolveProps, type ResourceDefinition, type ResourceEnum, type ResourceLayoutComponentProps, type ResourceTree, type Show, type UnionToIntersection, createComposableComponent, createPrimitivePropBuilder, createProp, defineResourceLayout, makeComposable, normalizeResource, normalizeResources, pick, toResourceEnum, validateProps };
|
package/dist/index.mjs
CHANGED
|
@@ -3,6 +3,6 @@ import { createComposableComponent, makeComposable } from "./composable.mjs";
|
|
|
3
3
|
import { createPrimitivePropBuilder, createProp } from "./validators/builders.mjs";
|
|
4
4
|
import { validateProps } from "./validators/validate-props.mjs";
|
|
5
5
|
import { normalizeResource, normalizeResources, toResourceEnum } from "./resource.mjs";
|
|
6
|
-
import { defineResourceLayout } from "./create-config.mjs";
|
|
6
|
+
import { defineResourceLayout } from "./create-config/define-layout.mjs";
|
|
7
7
|
|
|
8
8
|
export { createComposableComponent, createPrimitivePropBuilder, createProp, defineResourceLayout, makeComposable, normalizeResource, normalizeResources, pick, toResourceEnum, validateProps };
|
package/dist/props.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AnyBuiltPropDefinition, ResolveProps } from "./validators/types.cjs";
|
|
1
|
+
import { AnyBuiltPropDefinition, ResolveLayoutProps, ResolveProps } from "./validators/types.cjs";
|
|
2
2
|
import { EnumWrappedProp, LiteralWrappedProp } from "./validators/builders.cjs";
|
|
3
3
|
import { Show } from "./utils.cjs";
|
|
4
4
|
import { ResourceDefinition, ResourceEnum } from "./resource.cjs";
|
|
@@ -16,7 +16,7 @@ type InferredInProps<Resources extends ReadonlyArray<ResourceDefinition>, Option
|
|
|
16
16
|
* A map of props to include in the layout.
|
|
17
17
|
*/
|
|
18
18
|
type IncludedProps<T> = { [_ in keyof T]?: true };
|
|
19
|
-
type LayoutRenderProps<Resources extends ReadonlyArray<ResourceDefinition>, Options extends InPropsDefinition<Resources>, IncludeProps extends IncludedProps<InferredInProps<Resources, Options>> = {}, CustomProps extends InPropsObject = {}> = Show<ResolveProps<CustomProps & Pick<InferredInProps<Resources, Options>, keyof IncludeProps & string>>>;
|
|
19
|
+
type LayoutRenderProps<Resources extends ReadonlyArray<ResourceDefinition>, Options extends InPropsDefinition<Resources>, IncludeProps extends IncludedProps<InferredInProps<Resources, Options>> = {}, CustomProps extends InPropsObject = {}> = Show<ResolveProps<CustomProps> & ResolveLayoutProps<Pick<InferredInProps<Resources, Options>, keyof IncludeProps & string>>>;
|
|
20
20
|
//#endregion
|
|
21
21
|
export { InPropsDefinition, InPropsFunction, InPropsObject, InPropsOptions, IncludedProps, InferredInProps, LayoutRenderProps };
|
|
22
22
|
//# sourceMappingURL=props.d.cts.map
|
package/dist/props.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"props.d.cts","names":[],"sources":["../src/props.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"props.d.cts","names":[],"sources":["../src/props.ts"],"mappings":";;;;;;KAUY,aAAA,GAAgB,MAAM,SAAS,sBAAA;AAAA,KAC/B,cAAA,mBACQ,aAAA,CAAc,kBAAA;EAGhC,IAAA,EAAM,kBAAA,CAAmB,IAAA;EACzB,QAAA,EAAU,eAAA,CAAgB,YAAA,CAAa,SAAA;AAAA;AAAA,KAE7B,eAAA,mBACQ,aAAA,CAAc,kBAAA,2BAEhC,KAAA,EAAO,IAAA,CAAK,cAAA,CAAe,SAAA,EAAW,IAAA,OACnC,aAAA;AAAA,KACO,iBAAA,mBACQ,aAAA,CAAc,kBAAA,KAC9B,aAAA,GAAgB,eAAA,CAAgB,SAAA;AAAA,KACxB,eAAA,mBACQ,aAAA,CAAc,kBAAA,mBAChB,iBAAA,CAAkB,SAAA,KAChC,OAAA,SAAgB,eAAA,CAAgB,SAAA,IAAa,UAAA,CAAW,OAAA,IAAW,OAAA;AAnBN;AACjE;;AADiE,KAuBrD,aAAA,oBACE,CAAC;AAAA,KAEH,iBAAA,mBACQ,aAAA,CAAc,kBAAA,mBAChB,iBAAA,CAAkB,SAAA,wBACb,aAAA,CAAc,eAAA,CAAgB,SAAA,EAAW,OAAA,6BAC1C,aAAA,SAClB,IAAA,CACF,YAAA,CAAa,WAAA,IACX,kBAAA,CACE,IAAA,CAAK,eAAA,CAAgB,SAAA,EAAW,OAAA,SAAgB,YAAA"}
|
package/dist/props.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AnyBuiltPropDefinition, ResolveProps } from "./validators/types.mjs";
|
|
1
|
+
import { AnyBuiltPropDefinition, ResolveLayoutProps, ResolveProps } from "./validators/types.mjs";
|
|
2
2
|
import { EnumWrappedProp, LiteralWrappedProp } from "./validators/builders.mjs";
|
|
3
3
|
import { Show } from "./utils.mjs";
|
|
4
4
|
import { ResourceDefinition, ResourceEnum } from "./resource.mjs";
|
|
@@ -16,7 +16,7 @@ type InferredInProps<Resources extends ReadonlyArray<ResourceDefinition>, Option
|
|
|
16
16
|
* A map of props to include in the layout.
|
|
17
17
|
*/
|
|
18
18
|
type IncludedProps<T> = { [_ in keyof T]?: true };
|
|
19
|
-
type LayoutRenderProps<Resources extends ReadonlyArray<ResourceDefinition>, Options extends InPropsDefinition<Resources>, IncludeProps extends IncludedProps<InferredInProps<Resources, Options>> = {}, CustomProps extends InPropsObject = {}> = Show<ResolveProps<CustomProps & Pick<InferredInProps<Resources, Options>, keyof IncludeProps & string>>>;
|
|
19
|
+
type LayoutRenderProps<Resources extends ReadonlyArray<ResourceDefinition>, Options extends InPropsDefinition<Resources>, IncludeProps extends IncludedProps<InferredInProps<Resources, Options>> = {}, CustomProps extends InPropsObject = {}> = Show<ResolveProps<CustomProps> & ResolveLayoutProps<Pick<InferredInProps<Resources, Options>, keyof IncludeProps & string>>>;
|
|
20
20
|
//#endregion
|
|
21
21
|
export { InPropsDefinition, InPropsFunction, InPropsObject, InPropsOptions, IncludedProps, InferredInProps, LayoutRenderProps };
|
|
22
22
|
//# sourceMappingURL=props.d.mts.map
|
package/dist/props.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"props.d.mts","names":[],"sources":["../src/props.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"props.d.mts","names":[],"sources":["../src/props.ts"],"mappings":";;;;;;KAUY,aAAA,GAAgB,MAAM,SAAS,sBAAA;AAAA,KAC/B,cAAA,mBACQ,aAAA,CAAc,kBAAA;EAGhC,IAAA,EAAM,kBAAA,CAAmB,IAAA;EACzB,QAAA,EAAU,eAAA,CAAgB,YAAA,CAAa,SAAA;AAAA;AAAA,KAE7B,eAAA,mBACQ,aAAA,CAAc,kBAAA,2BAEhC,KAAA,EAAO,IAAA,CAAK,cAAA,CAAe,SAAA,EAAW,IAAA,OACnC,aAAA;AAAA,KACO,iBAAA,mBACQ,aAAA,CAAc,kBAAA,KAC9B,aAAA,GAAgB,eAAA,CAAgB,SAAA;AAAA,KACxB,eAAA,mBACQ,aAAA,CAAc,kBAAA,mBAChB,iBAAA,CAAkB,SAAA,KAChC,OAAA,SAAgB,eAAA,CAAgB,SAAA,IAAa,UAAA,CAAW,OAAA,IAAW,OAAA;AAnBN;AACjE;;AADiE,KAuBrD,aAAA,oBACE,CAAC;AAAA,KAEH,iBAAA,mBACQ,aAAA,CAAc,kBAAA,mBAChB,iBAAA,CAAkB,SAAA,wBACb,aAAA,CAAc,eAAA,CAAgB,SAAA,EAAW,OAAA,6BAC1C,aAAA,SAClB,IAAA,CACF,YAAA,CAAa,WAAA,IACX,kBAAA,CACE,IAAA,CAAK,eAAA,CAAgB,SAAA,EAAW,OAAA,SAAgB,YAAA"}
|
package/dist/resource.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource.cjs","names":[],"sources":["../src/resource.ts"],"sourcesContent":["import { ReactNode } from 'react';\nimport { NonEmptyReadonlyArray } from './validators';\nimport { MergeIntersection, UnionToIntersection } from './utils';\n\nexport type ResourceDefinition =\n | string\n | {\n value: string;\n subResources: ReadonlyArray<\n ResourceDefinition & {\n /**\n * Whether to allow any string as a sub resource.\n *\n * @default false\n */\n allowAnyString?: boolean;\n }\n >;\n };\n\nexport type ResourceTree = Record<\n string,\n {\n subResources: ResourceTree;\n }\n>;\n\nexport type NormalizeResource<Resource extends ResourceDefinition> =\n Resource extends string\n ? {\n [Key in Resource]: {\n subResources: {};\n };\n }\n : Resource extends {\n value: infer Value extends string;\n subResources: infer SubResources extends\n ReadonlyArray<ResourceDefinition>;\n }\n ? {\n [Key in Value]: {\n subResources: NormalizeResources<SubResources>;\n };\n }\n : never;\n\nexport type NormalizeResources<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = MergeIntersection<\n UnionToIntersection<NormalizeResource<Resources[number]>>\n>;\nexport type ResourceLayoutComponentProps = {\n children: ReactNode;\n};\n\nfunction normalizeResourceTree(resource: ResourceDefinition): ResourceTree {\n if (typeof resource === 'string') {\n return {\n [resource]: {\n subResources: {},\n },\n };\n }\n\n const { value, subResources } = resource;\n\n return {\n [value]: {\n subResources: normalizeResourcesTree(subResources),\n },\n };\n}\n\nfunction normalizeResourcesTree(\n resources: ReadonlyArray<ResourceDefinition>,\n): ResourceTree {\n const normalizedResources: ResourceTree = {};\n\n for (const resource of resources) {\n Object.assign(normalizedResources, normalizeResourceTree(resource));\n }\n\n return normalizedResources;\n}\n\nexport function normalizeResource(resource: ResourceDefinition): ResourceTree {\n return normalizeResourceTree(resource);\n}\n\nexport function normalizeResources<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(resources: Resources): NormalizeResources<Resources> {\n return normalizeResourcesTree(resources) as NormalizeResources<Resources>;\n}\n\ntype ResourceDefinitionValue<Resource extends ResourceDefinition> =\n Resource extends string\n ? Resource\n : Resource extends { value: infer Value extends string }\n ? Value\n
|
|
1
|
+
{"version":3,"file":"resource.cjs","names":[],"sources":["../src/resource.ts"],"sourcesContent":["import { ReactNode } from 'react';\nimport { NonEmptyReadonlyArray } from './validators';\nimport { MergeIntersection, UnionToIntersection } from './utils';\n\nexport type ResourceDefinition =\n | string\n | {\n value: string;\n subResources: ReadonlyArray<\n ResourceDefinition & {\n /**\n * Whether to allow any string as a sub resource.\n *\n * @default false\n */\n allowAnyString?: boolean;\n }\n >;\n };\n\nexport type ResourceTree = Record<\n string,\n {\n subResources: ResourceTree;\n }\n>;\n\nexport type NormalizeResource<Resource extends ResourceDefinition> =\n Resource extends string\n ? {\n [Key in Resource]: {\n subResources: {};\n };\n }\n : Resource extends {\n value: infer Value extends string;\n subResources: infer SubResources extends\n ReadonlyArray<ResourceDefinition>;\n }\n ? {\n [Key in Value]: {\n subResources: NormalizeResources<SubResources>;\n };\n }\n : never;\n\nexport type NormalizeResources<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = MergeIntersection<\n UnionToIntersection<NormalizeResource<Resources[number]>>\n>;\nexport type ResourceLayoutComponentProps = {\n children: ReactNode;\n};\n\nfunction normalizeResourceTree(resource: ResourceDefinition): ResourceTree {\n if (typeof resource === 'string') {\n return {\n [resource]: {\n subResources: {},\n },\n };\n }\n\n const { value, subResources } = resource;\n\n return {\n [value]: {\n subResources: normalizeResourcesTree(subResources),\n },\n };\n}\n\nfunction normalizeResourcesTree(\n resources: ReadonlyArray<ResourceDefinition>,\n): ResourceTree {\n const normalizedResources: ResourceTree = {};\n\n for (const resource of resources) {\n Object.assign(normalizedResources, normalizeResourceTree(resource));\n }\n\n return normalizedResources;\n}\n\nexport function normalizeResource(resource: ResourceDefinition): ResourceTree {\n return normalizeResourceTree(resource);\n}\n\nexport function normalizeResources<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(resources: Resources): NormalizeResources<Resources> {\n return normalizeResourcesTree(resources) as NormalizeResources<Resources>;\n}\n\ntype ResourceDefinitionValue<Resource extends ResourceDefinition> =\n Resource extends string\n ? Resource\n : Resource extends { value: infer Value extends string }\n ? Value\n : never;\n\n /**\n * Top-level resource names declared in a `resources` array. Preserves string\n * literal unions for const resource definitions (unlike `keyof` on the\n * normalized resource tree, which tends to widen to `string` in hovers).\n */\nexport type LayoutResourceKey<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = ResourceDefinitionValue<Resources[number]>;\n\nexport type ResourceDefinitionForKey<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Key extends string,\n> = Extract<Resources[number], Key | { value: Key }>;\n\n/** `subResources` array declared on a layout resource. */\nexport type SubResourceDefinitionsFor<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n> = ResourceDefinitionForKey<Resources, Resource> extends {\n subResources: infer SubResources extends ReadonlyArray<ResourceDefinition>;\n}\n ? SubResources\n : readonly [];\n\ntype CanNestSubResourceParam<\n MaxDepth extends number,\n DepthAcc extends readonly unknown[],\n> = [...DepthAcc, unknown]['length'] extends MaxDepth ? false : true;\n\n/**\n * `subResource` route param: a slug at the current depth, or `{ resource, subResource }`\n * when that slug has nested `subResources` in the layout tree and `MaxDepth` allows it.\n */\nexport type RecursiveSubResourceParam<\n Resources extends ReadonlyArray<ResourceDefinition>,\n SubDefs extends ReadonlyArray<ResourceDefinition>,\n MaxDepth extends number = 6,\n DepthAcc extends readonly unknown[] = readonly [],\n> = LayoutResourceKey<SubDefs> extends infer Key\n ? Key extends LayoutResourceKey<SubDefs>\n ? CanNestSubResourceParam<MaxDepth, DepthAcc> extends true\n ? ResourceDefinitionForKey<SubDefs, Key> extends {\n subResources: infer Nested extends ReadonlyArray<ResourceDefinition>;\n }\n ? [LayoutResourceKey<Nested>] extends [never]\n ? Key\n :\n | Key\n | {\n resource: Key;\n subResource: RecursiveSubResourceParam<\n Resources,\n Nested,\n MaxDepth,\n readonly [...DepthAcc, unknown]\n >;\n }\n : Key\n : Key\n : never\n : never;\n\n/** Recursive `subResource` values for a layout resource (full tree depth). */\nexport type SubResourceParamForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n> = [SubResourceDefinitionsFor<Resources, Resource>] extends [readonly []]\n ? never\n : RecursiveSubResourceParam<\n Resources,\n SubResourceDefinitionsFor<Resources, Resource>\n >;\n\nexport type GetSubResourceKeys<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n> = ResourceDefinitionForKey<Resources, Resource> extends {\n subResources: infer SubResources extends ReadonlyArray<ResourceDefinition>;\n}\n ? LayoutResourceKey<SubResources>\n : never;\nexport type ResourceEnum<Resources extends ReadonlyArray<ResourceDefinition>> =\n NonEmptyReadonlyArray<LayoutResourceKey<Resources>>;\nexport function toResourceEnum<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(resources: NormalizeResources<Resources>) {\n const keys = Object.keys(resources);\n\n if (keys.length === 0) {\n throw new Error('No resources provided');\n }\n\n return keys as unknown as ResourceEnum<Resources>;\n}\n"],"mappings":";;AAuDA,SAAS,sBAAsB,UAA4C;CACzE,IAAI,OAAO,aAAa,UACtB,OAAO,GACJ,WAAW,EACV,cAAc,CAAC,EACjB,EACF;CAGF,MAAM,EAAE,OAAO,iBAAiB;CAEhC,OAAO,GACJ,QAAQ,EACP,cAAc,uBAAuB,YAAY,EACnD,EACF;AACF;AAEA,SAAS,uBACP,WACc;CACd,MAAM,sBAAoC,CAAC;CAE3C,KAAK,MAAM,YAAY,WACrB,OAAO,OAAO,qBAAqB,sBAAsB,QAAQ,CAAC;CAGpE,OAAO;AACT;AAEA,SAAgB,kBAAkB,UAA4C;CAC5E,OAAO,sBAAsB,QAAQ;AACvC;AAEA,SAAgB,mBAEd,WAAqD;CACrD,OAAO,uBAAuB,SAAS;AACzC;AA4FA,SAAgB,eAEd,WAA0C;CAC1C,MAAM,OAAO,OAAO,KAAK,SAAS;CAElC,IAAI,KAAK,WAAW,GAClB,MAAM,IAAI,MAAM,uBAAuB;CAGzC,OAAO;AACT"}
|