@jfdevelops/react-layout 0.8.2 → 0.10.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.
Files changed (37) hide show
  1. package/dist/create-config/create-resource-links.cjs +6 -9
  2. package/dist/create-config/create-resource-links.cjs.map +1 -1
  3. package/dist/create-config/create-resource-links.d.cts +8 -7
  4. package/dist/create-config/create-resource-links.d.cts.map +1 -1
  5. package/dist/create-config/create-resource-links.d.mts +8 -7
  6. package/dist/create-config/create-resource-links.d.mts.map +1 -1
  7. package/dist/create-config/create-resource-links.mjs +6 -10
  8. package/dist/create-config/create-resource-links.mjs.map +1 -1
  9. package/dist/create-config/define-layout.cjs +14 -19
  10. package/dist/create-config/define-layout.cjs.map +1 -1
  11. package/dist/create-config/define-layout.d.cts +8 -35
  12. package/dist/create-config/define-layout.d.cts.map +1 -1
  13. package/dist/create-config/define-layout.d.mts +8 -35
  14. package/dist/create-config/define-layout.d.mts.map +1 -1
  15. package/dist/create-config/define-layout.mjs +14 -19
  16. package/dist/create-config/define-layout.mjs.map +1 -1
  17. package/dist/create-config/for-resource.cjs +49 -0
  18. package/dist/create-config/for-resource.cjs.map +1 -0
  19. package/dist/create-config/for-resource.d.cts +127 -0
  20. package/dist/create-config/for-resource.d.cts.map +1 -0
  21. package/dist/create-config/for-resource.d.mts +127 -0
  22. package/dist/create-config/for-resource.d.mts.map +1 -0
  23. package/dist/create-config/for-resource.mjs +49 -0
  24. package/dist/create-config/for-resource.mjs.map +1 -0
  25. package/dist/create-config/for-resources.cjs +47 -0
  26. package/dist/create-config/for-resources.cjs.map +1 -0
  27. package/dist/create-config/for-resources.d.cts +162 -0
  28. package/dist/create-config/for-resources.d.cts.map +1 -0
  29. package/dist/create-config/for-resources.d.mts +162 -0
  30. package/dist/create-config/for-resources.d.mts.map +1 -0
  31. package/dist/create-config/for-resources.mjs +47 -0
  32. package/dist/create-config/for-resources.mjs.map +1 -0
  33. package/dist/resource.cjs +0 -6
  34. package/dist/resource.cjs.map +1 -1
  35. package/dist/resource.mjs +1 -6
  36. package/dist/resource.mjs.map +1 -1
  37. package/package.json +1 -1
@@ -1,4 +1,3 @@
1
- const require_resource = require('../resource.cjs');
2
1
 
3
2
  //#region src/create-config/create-resource-links.ts
4
3
  function resolveResourceLinkHref(value, resource, fallback) {
@@ -11,9 +10,8 @@ function createFullResourceLinkHref(href, hash) {
11
10
  if (href.includes("#")) return href;
12
11
  return `${href}#${normalizeResourceLinkHash(hash)}`;
13
12
  }
14
- function createResourceLinksFromConfig(isValidResource, config) {
13
+ function createResourceLinksFromConfig(config) {
15
14
  return Object.entries(config).map(([resource, config]) => {
16
- if (!isValidResource(resource)) throw new Error(`[createResourceLinks]: Invalid resource: ${resource}`);
17
15
  if (!config) throw new Error(`[createResourceLinks]: "config" is required for the ${resource} resource.`);
18
16
  if (typeof config !== "object") throw new Error(`[createResourceLinks]: "config" must be an object for the ${resource} resource. Received ${typeof config}`);
19
17
  if (!("label" in config)) throw new Error(`[createResourceLinks]: "label" is required for the ${resource} resource.`);
@@ -39,7 +37,7 @@ function createResourceLinkGroupId() {
39
37
  if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") return crypto.randomUUID();
40
38
  return `group-${Math.random().toString(36).slice(2, 11)}`;
41
39
  }
42
- function createResourceLinksWithGroups(isValidResource, groups) {
40
+ function createResourceLinksWithGroups(groups) {
43
41
  if (!Array.isArray(groups)) throw new Error("[createResourceLinks.withGroups]: \"groups\" must be an array.");
44
42
  return groups.map((group, index) => {
45
43
  if (!group) throw new Error(`[createResourceLinks.withGroups]: group at index ${index} is required.`);
@@ -51,17 +49,16 @@ function createResourceLinksWithGroups(isValidResource, groups) {
51
49
  id: createResourceLinkGroupId(),
52
50
  label: "label" in group ? group.label ?? null : null,
53
51
  icon: "icon" in group ? group.icon : null,
54
- links: createResourceLinksFromConfig(isValidResource, group.links)
52
+ links: createResourceLinksFromConfig(group.links)
55
53
  };
56
54
  });
57
55
  }
58
- function createResourceLinksFn(resources) {
59
- const isValidResource = require_resource.createIsValidResourceFn(resources);
56
+ function createResourceLinksFn(_resources) {
60
57
  function createResourceLinks(config) {
61
- return createResourceLinksFromConfig(isValidResource, config);
58
+ return createResourceLinksFromConfig(config);
62
59
  }
63
60
  function withGroups(groups) {
64
- return createResourceLinksWithGroups(isValidResource, groups);
61
+ return createResourceLinksWithGroups(groups);
65
62
  }
66
63
  return Object.assign(createResourceLinks, { withGroups });
67
64
  }
@@ -1 +1 @@
1
- {"version":3,"file":"create-resource-links.cjs","names":["createIsValidResourceFn"],"sources":["../../src/create-config/create-resource-links.ts"],"sourcesContent":["import { ReactNode } from 'react';\nimport {\n createIsValidResourceFn,\n type LayoutResourceKey,\n type ResourceDefinition,\n} from '../resource';\n\nexport type ResourceAnchorLinkFn<Resource extends string> = (\n resource: Resource,\n) => string;\n\nexport type ResourceLinkHref<Resource extends string> =\n | string\n | ResourceAnchorLinkFn<Resource>;\n\nexport interface CreateResourceLinkOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n> {\n /**\n * The label of the link. This is the text that will be displayed in the link.\n */\n label: string;\n /**\n * An optional icon to register with the link. This is a headless approach, meaning you have full control\n * over the icon's rendering.\n */\n icon?: ReactNode;\n /**\n * The href of the link. By default, the href will be `\"/\"`. While you **don't** need to include a hash,\n * if you do, it will override the `hash` property (if provided).\n */\n href?: ResourceLinkHref<Resource>;\n /**\n * The hash of the link. By default, the hash will be the resource name. If you need to customize it, you can provide\n * a string or a function that returns a string.\n *\n * @remarks A `\"#\"` is not required. The generated href will include it automatically.\n */\n hash?: ResourceLinkHref<Resource>;\n}\n\nexport type CreateResourceLinkConfig<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = {\n [resource in LayoutResourceKey<Resources>]?: CreateResourceLinkOptions<\n Resources,\n resource\n >;\n};\n\nexport type InferHashFromResourceLinkHref<\n Resource extends string,\n Hash extends ResourceLinkHref<Resource>,\n> = Hash extends string\n ? Hash\n : Hash extends ResourceAnchorLinkFn<Resource>\n ? ReturnType<Hash>\n : never;\n\nexport type CreatedResourceHref = {\n /**\n * The full generated href with the `hash` if provided.\n */\n full: string;\n /**\n * The given href. This is the same value as the `href` property of the config.\n */\n given: string;\n};\n\nexport type CreatedResourceLinkBase<Resource extends string> = {\n href: CreatedResourceHref;\n label: string;\n resource: Resource;\n icon: ReactNode;\n};\nexport type CreateResourceLinkWithHash<\n Resource extends string,\n Hash extends ResourceLinkHref<Resource>,\n> = Omit<CreatedResourceLinkBase<Resource>, 'href'> & {\n href: CreatedResourceHref & {\n hash: InferHashFromResourceLinkHref<Resource, Hash>;\n };\n};\n\nexport type CreatedResourceLink<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Config extends CreateResourceLinkConfig<Resources>,\n> = {\n [Resource in keyof Config]: Resource extends LayoutResourceKey<Resources>\n ? Config[Resource] extends {\n hash: infer hash extends ResourceLinkHref<Resource>;\n }\n ? CreateResourceLinkWithHash<Resource, hash>\n : CreatedResourceLinkBase<Resource>\n : never;\n}[keyof Config];\n\nexport interface CreateResourceLinksFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> {\n <const Config extends CreateResourceLinkConfig<Resources>>(\n config: Config,\n ): Array<CreatedResourceLink<Resources, Config>>;\n withGroups: CreateResourceLinksWithGroupsFn<Resources>;\n}\n\nexport interface CreateResourceLinkGroupOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Links extends CreateResourceLinkConfig<Resources> =\n CreateResourceLinkConfig<Resources>,\n> {\n /**\n * The label of the group. This is the text that will be displayed for the group.\n */\n label?: string;\n /**\n * An optional icon to register with the group. This is a headless approach, meaning you have full control\n * over the icon's rendering.\n */\n icon?: ReactNode;\n /**\n * The resource links in this group.\n */\n links: Links;\n}\n\nexport type CreateResourceLinkGroupInput<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = CreateResourceLinkGroupOptions<\n Resources,\n CreateResourceLinkConfig<Resources>\n>;\n\nexport type AnyCreatedResourceLink<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = {\n [Resource in LayoutResourceKey<Resources>]:\n | CreatedResourceLinkBase<Resource>\n | CreateResourceLinkWithHash<Resource, string>;\n}[LayoutResourceKey<Resources>];\n\nexport type CreateResourceLinksWithGroups<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = {\n id: string;\n label: string | null;\n icon: ReactNode;\n links: Array<AnyCreatedResourceLink<Resources>>;\n};\n\nexport type CreateResourceLinksWithGroupsFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = (\n groups: ReadonlyArray<CreateResourceLinkGroupInput<Resources>>,\n) => Array<CreateResourceLinksWithGroups<Resources>>;\n\nfunction resolveResourceLinkHref<Resource extends string>(\n value: ResourceLinkHref<Resource> | undefined,\n resource: Resource,\n fallback: string,\n) {\n return typeof value === 'function' ? value(resource) : (value ?? fallback);\n}\n\nfunction normalizeResourceLinkHash(hash: string) {\n return hash.replace(/^#+/, '');\n}\n\nfunction createFullResourceLinkHref(href: string, hash: string) {\n if (href.includes('#')) {\n return href;\n }\n\n return `${href}#${normalizeResourceLinkHash(hash)}`;\n}\n\nfunction createResourceLinksFromConfig<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(\n isValidResource: ReturnType<typeof createIsValidResourceFn<Resources>>,\n config: CreateResourceLinkConfig<Resources>,\n) {\n return Object.entries(config).map(([resource, config]) => {\n if (!isValidResource(resource)) {\n throw new Error(`[createResourceLinks]: Invalid resource: ${resource}`);\n }\n\n if (!config) {\n throw new Error(\n `[createResourceLinks]: \"config\" is required for the ${resource} resource.`,\n );\n }\n\n if (typeof config !== 'object') {\n throw new Error(\n `[createResourceLinks]: \"config\" must be an object for the ${resource} resource. Received ${typeof config}`,\n );\n }\n\n if (!('label' in config)) {\n throw new Error(\n `[createResourceLinks]: \"label\" is required for the ${resource} resource.`,\n );\n }\n\n if (typeof config.label !== 'string') {\n throw new Error(\n `[createResourceLinks]: \"label\" must be a string for the ${resource} resource. Received ${typeof config.label}`,\n );\n }\n\n const linkConfig = config as CreateResourceLinkOptions<\n Resources,\n typeof resource\n >;\n\n if (\n 'href' in linkConfig &&\n linkConfig.href !== undefined &&\n typeof linkConfig.href !== 'string' &&\n typeof linkConfig.href !== 'function'\n ) {\n throw new Error(\n `[createResourceLinks]: \"href\" must be a string or function for the ${resource} resource. Received ${typeof linkConfig.href}`,\n );\n }\n\n if (\n 'hash' in linkConfig &&\n linkConfig.hash !== undefined &&\n typeof linkConfig.hash !== 'string' &&\n typeof linkConfig.hash !== 'function'\n ) {\n throw new Error(\n `[createResourceLinks]: \"hash\" must be a string or function for the ${resource} resource. Received ${typeof linkConfig.hash}`,\n );\n }\n\n const givenHref = resolveResourceLinkHref(linkConfig.href, resource, '/');\n const givenHash = resolveResourceLinkHref(\n linkConfig.hash,\n resource,\n resource,\n );\n const href = {\n given: givenHref,\n full: createFullResourceLinkHref(givenHref, givenHash),\n ...(linkConfig.hash !== undefined && !givenHref.includes('#')\n ? { hash: normalizeResourceLinkHash(givenHash) }\n : {}),\n };\n\n return {\n href,\n label: config.label,\n resource,\n icon: 'icon' in config ? config.icon : null,\n };\n });\n}\n\nfunction createResourceLinkGroupId() {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n\n return `group-${Math.random().toString(36).slice(2, 11)}`;\n}\n\nfunction createResourceLinksWithGroups<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(\n isValidResource: ReturnType<typeof createIsValidResourceFn<Resources>>,\n groups: ReadonlyArray<CreateResourceLinkGroupInput<Resources>>,\n): Array<CreateResourceLinksWithGroups<Resources>> {\n if (!Array.isArray(groups)) {\n throw new Error(\n '[createResourceLinks.withGroups]: \"groups\" must be an array.',\n );\n }\n\n return groups.map((group, index) => {\n if (!group) {\n throw new Error(\n `[createResourceLinks.withGroups]: group at index ${index} is required.`,\n );\n }\n\n if (typeof group !== 'object') {\n throw new Error(\n `[createResourceLinks.withGroups]: group at index ${index} must be an object. Received ${typeof group}`,\n );\n }\n\n if (\n 'label' in group &&\n group.label !== undefined &&\n typeof group.label !== 'string'\n ) {\n throw new Error(\n `[createResourceLinks.withGroups]: \"label\" must be a string for group at index ${index}. Received ${typeof group.label}`,\n );\n }\n\n if (!('links' in group)) {\n throw new Error(\n `[createResourceLinks.withGroups]: \"links\" is required for group at index ${index}.`,\n );\n }\n\n if (\n typeof group.links !== 'object' ||\n group.links === null ||\n Array.isArray(group.links)\n ) {\n throw new Error(\n `[createResourceLinks.withGroups]: \"links\" must be an object for group at index ${index}. Received ${Array.isArray(group.links) ? 'array' : typeof group.links}`,\n );\n }\n\n return {\n id: createResourceLinkGroupId(),\n label: 'label' in group ? (group.label ?? null) : null,\n icon: 'icon' in group ? group.icon : null,\n links: createResourceLinksFromConfig(isValidResource, group.links),\n };\n }) as Array<CreateResourceLinksWithGroups<Resources>>;\n}\n\nexport function createResourceLinksFn<\n const Resources extends ReadonlyArray<ResourceDefinition>,\n>(resources: Resources): CreateResourceLinksFn<Resources> {\n const isValidResource = createIsValidResourceFn(resources);\n\n function createResourceLinks<\n const Config extends CreateResourceLinkConfig<Resources>,\n >(config: Config) {\n return createResourceLinksFromConfig(isValidResource, config);\n }\n\n function withGroups(\n groups: ReadonlyArray<CreateResourceLinkGroupInput<Resources>>,\n ) {\n return createResourceLinksWithGroups(isValidResource, groups);\n }\n\n return Object.assign(createResourceLinks, {\n withGroups,\n }) as CreateResourceLinksFn<Resources>;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"create-resource-links.cjs","names":[],"sources":["../../src/create-config/create-resource-links.ts"],"sourcesContent":["import { ReactNode } from 'react';\nimport {\n type LayoutResourceKey,\n type ResourceDefinition,\n} from '../resource';\n\nexport type ResourceAnchorLinkFn<Resource extends string> = (\n resource: Resource,\n) => string;\n\nexport type ResourceLinkHref<Resource extends string> =\n | string\n | ResourceAnchorLinkFn<Resource>;\n\nexport type ResourceLinkConfigResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = LayoutResourceKey<Resources> | (string & {});\nexport interface CreateResourceLinkOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends ResourceLinkConfigResource<Resources>,\n> {\n /**\n * The label of the link. This is the text that will be displayed in the link.\n */\n label: string;\n /**\n * An optional icon to register with the link. This is a headless approach, meaning you have full control\n * over the icon's rendering.\n */\n icon?: ReactNode;\n /**\n * The href of the link. By default, the href will be `\"/\"`. While you **don't** need to include a hash,\n * if you do, it will override the `hash` property (if provided).\n */\n href?: ResourceLinkHref<Resource>;\n /**\n * The hash of the link. By default, the hash will be the resource name. If you need to customize it, you can provide\n * a string or a function that returns a string.\n *\n * @remarks A `\"#\"` is not required. The generated href will include it automatically.\n */\n hash?: ResourceLinkHref<Resource>;\n}\n\nexport type CreateResourceLinkConfig<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends ResourceLinkConfigResource<Resources> = ResourceLinkConfigResource<Resources>,\n> = {\n [Key in Resource]?: CreateResourceLinkOptions<\n Resources,\n Key\n >;\n};\n\nexport type InferHashFromResourceLinkHref<\n Resource extends string,\n Hash extends ResourceLinkHref<Resource>,\n> = Hash extends string\n ? Hash\n : Hash extends ResourceAnchorLinkFn<Resource>\n ? ReturnType<Hash>\n : never;\n\nexport type CreatedResourceHref = {\n /**\n * The full generated href with the `hash` if provided.\n */\n full: string;\n /**\n * The given href. This is the same value as the `href` property of the config.\n */\n given: string;\n};\n\nexport type CreatedResourceLinkBase<Resource extends string> = {\n href: CreatedResourceHref;\n label: string;\n resource: Resource;\n icon: ReactNode;\n};\nexport type CreateResourceLinkWithHash<\n Resource extends string,\n Hash extends ResourceLinkHref<Resource>,\n> = Omit<CreatedResourceLinkBase<Resource>, 'href'> & {\n href: CreatedResourceHref & {\n hash: InferHashFromResourceLinkHref<Resource, Hash>;\n };\n};\n\nexport type CreatedResourceLink<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Config,\n> = {\n [Resource in keyof Config]-?: Resource extends ResourceLinkConfigResource<Resources>\n ? Config[Resource] extends {\n hash: infer hash extends ResourceLinkHref<Resource>;\n }\n ? CreateResourceLinkWithHash<Resource, hash>\n : CreatedResourceLinkBase<Resource>\n : never;\n}[keyof Config];\n\nexport interface CreateResourceLinksFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> {\n <const Resource extends ResourceLinkConfigResource<Resources>>(\n config: CreateResourceLinkConfig<Resources, Resource>,\n ): Array<\n CreatedResourceLink<\n Resources,\n CreateResourceLinkConfig<Resources, Resource>\n >\n >;\n withGroups: CreateResourceLinksWithGroupsFn<Resources>;\n}\n\nexport interface CreateResourceLinkGroupOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Links extends object =\n CreateResourceLinkConfig<Resources>,\n> {\n /**\n * The label of the group. This is the text that will be displayed for the group.\n */\n label?: string;\n /**\n * An optional icon to register with the group. This is a headless approach, meaning you have full control\n * over the icon's rendering.\n */\n icon?: ReactNode;\n /**\n * The resource links in this group.\n */\n links: Links;\n}\n\nexport type CreateResourceLinkGroupInput<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends ResourceLinkConfigResource<Resources> = ResourceLinkConfigResource<Resources>,\n> = CreateResourceLinkGroupOptions<\n Resources,\n CreateResourceLinkConfig<Resources, Resource>\n>;\n\nexport type AnyCreatedResourceLink<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = {\n [Resource in LayoutResourceKey<Resources>]:\n | CreatedResourceLinkBase<Resource>\n | CreateResourceLinkWithHash<Resource, string>;\n}[LayoutResourceKey<Resources>];\n\nexport type CreateResourceLinksWithGroups<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = {\n id: string;\n label: string | null;\n icon: ReactNode;\n links: Array<AnyCreatedResourceLink<Resources>>;\n};\n\nexport type CreateResourceLinksWithGroupsFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = <const Resource extends ResourceLinkConfigResource<Resources>>(\n groups: ReadonlyArray<CreateResourceLinkGroupInput<Resources, Resource>>,\n) => Array<CreateResourceLinksWithGroups<Resources>>;\n\nfunction resolveResourceLinkHref<Resource extends string>(\n value: ResourceLinkHref<Resource> | undefined,\n resource: Resource,\n fallback: string,\n) {\n return typeof value === 'function' ? value(resource) : (value ?? fallback);\n}\n\nfunction normalizeResourceLinkHash(hash: string) {\n return hash.replace(/^#+/, '');\n}\n\nfunction createFullResourceLinkHref(href: string, hash: string) {\n if (href.includes('#')) {\n return href;\n }\n\n return `${href}#${normalizeResourceLinkHash(hash)}`;\n}\n\nfunction createResourceLinksFromConfig<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends ResourceLinkConfigResource<Resources>,\n>(config: CreateResourceLinkConfig<Resources, Resource>) {\n return Object.entries(config).map(([resource, config]) => {\n if (!config) {\n throw new Error(\n `[createResourceLinks]: \"config\" is required for the ${resource} resource.`,\n );\n }\n\n if (typeof config !== 'object') {\n throw new Error(\n `[createResourceLinks]: \"config\" must be an object for the ${resource} resource. Received ${typeof config}`,\n );\n }\n\n if (!('label' in config)) {\n throw new Error(\n `[createResourceLinks]: \"label\" is required for the ${resource} resource.`,\n );\n }\n\n if (typeof config.label !== 'string') {\n throw new Error(\n `[createResourceLinks]: \"label\" must be a string for the ${resource} resource. Received ${typeof config.label}`,\n );\n }\n\n const linkConfig = config as CreateResourceLinkOptions<\n Resources,\n typeof resource\n >;\n\n if (\n 'href' in linkConfig &&\n linkConfig.href !== undefined &&\n typeof linkConfig.href !== 'string' &&\n typeof linkConfig.href !== 'function'\n ) {\n throw new Error(\n `[createResourceLinks]: \"href\" must be a string or function for the ${resource} resource. Received ${typeof linkConfig.href}`,\n );\n }\n\n if (\n 'hash' in linkConfig &&\n linkConfig.hash !== undefined &&\n typeof linkConfig.hash !== 'string' &&\n typeof linkConfig.hash !== 'function'\n ) {\n throw new Error(\n `[createResourceLinks]: \"hash\" must be a string or function for the ${resource} resource. Received ${typeof linkConfig.hash}`,\n );\n }\n\n const givenHref = resolveResourceLinkHref(linkConfig.href, resource, '/');\n const givenHash = resolveResourceLinkHref(\n linkConfig.hash,\n resource,\n resource,\n );\n const href = {\n given: givenHref,\n full: createFullResourceLinkHref(givenHref, givenHash),\n ...(linkConfig.hash !== undefined && !givenHref.includes('#')\n ? { hash: normalizeResourceLinkHash(givenHash) }\n : {}),\n };\n\n return {\n href,\n label: config.label,\n resource,\n icon: 'icon' in config ? config.icon : null,\n };\n });\n}\n\nfunction createResourceLinkGroupId() {\n if (\n typeof crypto !== 'undefined' &&\n typeof crypto.randomUUID === 'function'\n ) {\n return crypto.randomUUID();\n }\n\n return `group-${Math.random().toString(36).slice(2, 11)}`;\n}\n\nfunction createResourceLinksWithGroups<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends ResourceLinkConfigResource<Resources>,\n>(\n groups: ReadonlyArray<CreateResourceLinkGroupInput<Resources, Resource>>,\n): Array<CreateResourceLinksWithGroups<Resources>> {\n if (!Array.isArray(groups)) {\n throw new Error(\n '[createResourceLinks.withGroups]: \"groups\" must be an array.',\n );\n }\n\n return groups.map((group, index) => {\n if (!group) {\n throw new Error(\n `[createResourceLinks.withGroups]: group at index ${index} is required.`,\n );\n }\n\n if (typeof group !== 'object') {\n throw new Error(\n `[createResourceLinks.withGroups]: group at index ${index} must be an object. Received ${typeof group}`,\n );\n }\n\n if (\n 'label' in group &&\n group.label !== undefined &&\n typeof group.label !== 'string'\n ) {\n throw new Error(\n `[createResourceLinks.withGroups]: \"label\" must be a string for group at index ${index}. Received ${typeof group.label}`,\n );\n }\n\n if (!('links' in group)) {\n throw new Error(\n `[createResourceLinks.withGroups]: \"links\" is required for group at index ${index}.`,\n );\n }\n\n if (\n typeof group.links !== 'object' ||\n group.links === null ||\n Array.isArray(group.links)\n ) {\n throw new Error(\n `[createResourceLinks.withGroups]: \"links\" must be an object for group at index ${index}. Received ${Array.isArray(group.links) ? 'array' : typeof group.links}`,\n );\n }\n\n return {\n id: createResourceLinkGroupId(),\n label: 'label' in group ? (group.label ?? null) : null,\n icon: 'icon' in group ? group.icon : null,\n links: createResourceLinksFromConfig(group.links),\n };\n }) as Array<CreateResourceLinksWithGroups<Resources>>;\n}\n\nexport function createResourceLinksFn<\n const Resources extends ReadonlyArray<ResourceDefinition>,\n>(_resources: Resources): CreateResourceLinksFn<Resources> {\n function createResourceLinks<\n const Resource extends ResourceLinkConfigResource<Resources>,\n >(config: CreateResourceLinkConfig<Resources, Resource>) {\n return createResourceLinksFromConfig(config);\n }\n\n function withGroups<\n const Resource extends ResourceLinkConfigResource<Resources>,\n >(\n groups: ReadonlyArray<CreateResourceLinkGroupInput<Resources, Resource>>,\n ) {\n return createResourceLinksWithGroups(groups);\n }\n\n return Object.assign(createResourceLinks, {\n withGroups,\n }) as CreateResourceLinksFn<Resources>;\n}\n"],"mappings":"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"}
@@ -4,7 +4,8 @@ import { ReactNode } from "react";
4
4
  //#region src/create-config/create-resource-links.d.ts
5
5
  type ResourceAnchorLinkFn<Resource extends string> = (resource: Resource) => string;
6
6
  type ResourceLinkHref<Resource extends string> = string | ResourceAnchorLinkFn<Resource>;
7
- interface CreateResourceLinkOptions<Resources extends ReadonlyArray<ResourceDefinition>, Resource extends LayoutResourceKey<Resources>> {
7
+ type ResourceLinkConfigResource<Resources extends ReadonlyArray<ResourceDefinition>> = LayoutResourceKey<Resources> | (string & {});
8
+ interface CreateResourceLinkOptions<Resources extends ReadonlyArray<ResourceDefinition>, Resource extends ResourceLinkConfigResource<Resources>> {
8
9
  /**
9
10
  * The label of the link. This is the text that will be displayed in the link.
10
11
  */
@@ -27,7 +28,7 @@ interface CreateResourceLinkOptions<Resources extends ReadonlyArray<ResourceDefi
27
28
  */
28
29
  hash?: ResourceLinkHref<Resource>;
29
30
  }
30
- type CreateResourceLinkConfig<Resources extends ReadonlyArray<ResourceDefinition>> = { [resource in LayoutResourceKey<Resources>]?: CreateResourceLinkOptions<Resources, resource> };
31
+ type CreateResourceLinkConfig<Resources extends ReadonlyArray<ResourceDefinition>, Resource extends ResourceLinkConfigResource<Resources> = ResourceLinkConfigResource<Resources>> = { [Key in Resource]?: CreateResourceLinkOptions<Resources, Key> };
31
32
  type InferHashFromResourceLinkHref<Resource extends string, Hash extends ResourceLinkHref<Resource>> = Hash extends string ? Hash : Hash extends ResourceAnchorLinkFn<Resource> ? ReturnType<Hash> : never;
32
33
  type CreatedResourceHref = {
33
34
  /**
@@ -50,14 +51,14 @@ type CreateResourceLinkWithHash<Resource extends string, Hash extends ResourceLi
50
51
  hash: InferHashFromResourceLinkHref<Resource, Hash>;
51
52
  };
52
53
  };
53
- type CreatedResourceLink<Resources extends ReadonlyArray<ResourceDefinition>, Config extends CreateResourceLinkConfig<Resources>> = { [Resource in keyof Config]: Resource extends LayoutResourceKey<Resources> ? Config[Resource] extends {
54
+ type CreatedResourceLink<Resources extends ReadonlyArray<ResourceDefinition>, Config> = { [Resource in keyof Config]-?: Resource extends ResourceLinkConfigResource<Resources> ? Config[Resource] extends {
54
55
  hash: infer hash extends ResourceLinkHref<Resource>;
55
56
  } ? CreateResourceLinkWithHash<Resource, hash> : CreatedResourceLinkBase<Resource> : never }[keyof Config];
56
57
  interface CreateResourceLinksFn<Resources extends ReadonlyArray<ResourceDefinition>> {
57
- <const Config extends CreateResourceLinkConfig<Resources>>(config: Config): Array<CreatedResourceLink<Resources, Config>>;
58
+ <const Resource extends ResourceLinkConfigResource<Resources>>(config: CreateResourceLinkConfig<Resources, Resource>): Array<CreatedResourceLink<Resources, CreateResourceLinkConfig<Resources, Resource>>>;
58
59
  withGroups: CreateResourceLinksWithGroupsFn<Resources>;
59
60
  }
60
- interface CreateResourceLinkGroupOptions<Resources extends ReadonlyArray<ResourceDefinition>, Links extends CreateResourceLinkConfig<Resources> = CreateResourceLinkConfig<Resources>> {
61
+ interface CreateResourceLinkGroupOptions<Resources extends ReadonlyArray<ResourceDefinition>, Links extends object = CreateResourceLinkConfig<Resources>> {
61
62
  /**
62
63
  * The label of the group. This is the text that will be displayed for the group.
63
64
  */
@@ -72,7 +73,7 @@ interface CreateResourceLinkGroupOptions<Resources extends ReadonlyArray<Resourc
72
73
  */
73
74
  links: Links;
74
75
  }
75
- type CreateResourceLinkGroupInput<Resources extends ReadonlyArray<ResourceDefinition>> = CreateResourceLinkGroupOptions<Resources, CreateResourceLinkConfig<Resources>>;
76
+ type CreateResourceLinkGroupInput<Resources extends ReadonlyArray<ResourceDefinition>, Resource extends ResourceLinkConfigResource<Resources> = ResourceLinkConfigResource<Resources>> = CreateResourceLinkGroupOptions<Resources, CreateResourceLinkConfig<Resources, Resource>>;
76
77
  type AnyCreatedResourceLink<Resources extends ReadonlyArray<ResourceDefinition>> = { [Resource in LayoutResourceKey<Resources>]: CreatedResourceLinkBase<Resource> | CreateResourceLinkWithHash<Resource, string> }[LayoutResourceKey<Resources>];
77
78
  type CreateResourceLinksWithGroups<Resources extends ReadonlyArray<ResourceDefinition>> = {
78
79
  id: string;
@@ -80,7 +81,7 @@ type CreateResourceLinksWithGroups<Resources extends ReadonlyArray<ResourceDefin
80
81
  icon: ReactNode;
81
82
  links: Array<AnyCreatedResourceLink<Resources>>;
82
83
  };
83
- type CreateResourceLinksWithGroupsFn<Resources extends ReadonlyArray<ResourceDefinition>> = (groups: ReadonlyArray<CreateResourceLinkGroupInput<Resources>>) => Array<CreateResourceLinksWithGroups<Resources>>;
84
+ type CreateResourceLinksWithGroupsFn<Resources extends ReadonlyArray<ResourceDefinition>> = <const Resource extends ResourceLinkConfigResource<Resources>>(groups: ReadonlyArray<CreateResourceLinkGroupInput<Resources, Resource>>) => Array<CreateResourceLinksWithGroups<Resources>>;
84
85
  //#endregion
85
86
  export { CreateResourceLinkConfig, CreateResourceLinkGroupInput, CreateResourceLinkGroupOptions, CreateResourceLinkOptions, CreateResourceLinksFn, CreateResourceLinksWithGroups, CreateResourceLinksWithGroupsFn, CreatedResourceHref, CreatedResourceLink, CreatedResourceLinkBase, InferHashFromResourceLinkHref, ResourceAnchorLinkFn, ResourceLinkHref };
86
87
  //# sourceMappingURL=create-resource-links.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-resource-links.d.cts","names":[],"sources":["../../src/create-config/create-resource-links.ts"],"mappings":";;;;KAOY,oBAAA,6BACV,QAAA,EAAU,QAAQ;AAAA,KAGR,gBAAA,qCAER,oBAAoB,CAAC,QAAA;AAAA,UAER,yBAAA,mBACG,aAAA,CAAc,kBAAA,oBACf,iBAAA,CAAkB,SAAA;EAVL;;;EAe9B,KAAA;EAdU;;;AAAQ;EAmBlB,IAAA,GAAO,SAAA;EAhBmB;;;;EAqB1B,IAAA,GAAO,gBAAA,CAAiB,QAAA;EAnBD;;AAAQ;AAEjC;;;EAwBE,IAAA,GAAO,gBAAA,CAAiB,QAAA;AAAA;AAAA,KAGd,wBAAA,mBACQ,aAAA,CAAc,kBAAA,oBAEnB,iBAAA,CAAkB,SAAA,KAAc,yBAAA,CAC3C,SAAA,EACA,QAAA;AAAA,KAIQ,6BAAA,uCAEG,gBAAA,CAAiB,QAAA,KAC5B,IAAA,kBACA,IAAA,GACA,IAAA,SAAa,oBAAA,CAAqB,QAAA,IAChC,UAAA,CAAW,IAAA;AAAA,KAGL,mBAAA;EArBc;;;EAyBxB,IAAA;EAhDA;;;EAoDA,KAAK;AAAA;AAAA,KAGK,uBAAA;EACV,IAAA,EAAM,mBAAA;EACN,KAAA;EACA,QAAA,EAAU,QAAA;EACV,IAAA,EAAM,SAAA;AAAA;AAAA,KAEI,0BAAA,uCAEG,gBAAA,CAAiB,QAAA,KAC5B,IAAA,CAAK,uBAAA,CAAwB,QAAA;EAC/B,IAAA,EAAM,mBAAA;IACJ,IAAA,EAAM,6BAAA,CAA8B,QAAA,EAAU,IAAA;EAAA;AAAA;AAAA,KAItC,mBAAA,mBACQ,aAAA,CAAc,kBAAA,kBACjB,wBAAA,CAAyB,SAAA,0BAErB,MAAA,GAAS,QAAA,SAAiB,iBAAA,CAAkB,SAAA,IAC3D,MAAA,CAAO,QAAA;EACL,IAAA,qBAAyB,gBAAA,CAAiB,QAAA;AAAA,IAE1C,0BAAA,CAA2B,QAAA,EAAU,IAAA,IACrC,uBAAA,CAAwB,QAAA,kBAExB,MAAA;AAAA,UAES,qBAAA,mBACG,aAAA,CAAc,kBAAA;EAAA,sBAEV,wBAAA,CAAyB,SAAA,GAC7C,MAAA,EAAQ,MAAA,GACP,KAAA,CAAM,mBAAA,CAAoB,SAAA,EAAW,MAAA;EACxC,UAAA,EAAY,+BAAA,CAAgC,SAAA;AAAA;AAAA,UAG7B,8BAAA,mBACG,aAAA,CAAc,kBAAA,iBAClB,wBAAA,CAAyB,SAAA,IACrC,wBAAA,CAAyB,SAAA;EAlEkB;;;EAuE7C,KAAA;EAzEkB;;;;EA8ElB,IAAA,GAAO,SAAA;EA5EsC;;;EAgF7C,KAAA,EAAO,KAAA;AAAA;AAAA,KAGG,4BAAA,mBACQ,aAAA,CAAc,kBAAA,KAC9B,8BAAA,CACF,SAAA,EACA,wBAAA,CAAyB,SAAA;AAAA,KAGf,sBAAA,mBACQ,aAAA,CAAc,kBAAA,oBAEnB,iBAAA,CAAkB,SAAA,IAC3B,uBAAA,CAAwB,QAAA,IACxB,0BAAA,CAA2B,QAAA,YAC/B,iBAAA,CAAkB,SAAA;AAAA,KAER,6BAAA,mBACQ,aAAA,CAAc,kBAAA;EAEhC,EAAA;EACA,KAAA;EACA,IAAA,EAAM,SAAA;EACN,KAAA,EAAO,KAAA,CAAM,sBAAA,CAAuB,SAAA;AAAA;AAAA,KAG1B,+BAAA,mBACQ,aAAA,CAAc,kBAAA,MAEhC,MAAA,EAAQ,aAAA,CAAc,4BAAA,CAA6B,SAAA,OAChD,KAAA,CAAM,6BAAA,CAA8B,SAAA"}
1
+ {"version":3,"file":"create-resource-links.d.cts","names":[],"sources":["../../src/create-config/create-resource-links.ts"],"mappings":"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"}
@@ -4,7 +4,8 @@ import { ReactNode } from "react";
4
4
  //#region src/create-config/create-resource-links.d.ts
5
5
  type ResourceAnchorLinkFn<Resource extends string> = (resource: Resource) => string;
6
6
  type ResourceLinkHref<Resource extends string> = string | ResourceAnchorLinkFn<Resource>;
7
- interface CreateResourceLinkOptions<Resources extends ReadonlyArray<ResourceDefinition>, Resource extends LayoutResourceKey<Resources>> {
7
+ type ResourceLinkConfigResource<Resources extends ReadonlyArray<ResourceDefinition>> = LayoutResourceKey<Resources> | (string & {});
8
+ interface CreateResourceLinkOptions<Resources extends ReadonlyArray<ResourceDefinition>, Resource extends ResourceLinkConfigResource<Resources>> {
8
9
  /**
9
10
  * The label of the link. This is the text that will be displayed in the link.
10
11
  */
@@ -27,7 +28,7 @@ interface CreateResourceLinkOptions<Resources extends ReadonlyArray<ResourceDefi
27
28
  */
28
29
  hash?: ResourceLinkHref<Resource>;
29
30
  }
30
- type CreateResourceLinkConfig<Resources extends ReadonlyArray<ResourceDefinition>> = { [resource in LayoutResourceKey<Resources>]?: CreateResourceLinkOptions<Resources, resource> };
31
+ type CreateResourceLinkConfig<Resources extends ReadonlyArray<ResourceDefinition>, Resource extends ResourceLinkConfigResource<Resources> = ResourceLinkConfigResource<Resources>> = { [Key in Resource]?: CreateResourceLinkOptions<Resources, Key> };
31
32
  type InferHashFromResourceLinkHref<Resource extends string, Hash extends ResourceLinkHref<Resource>> = Hash extends string ? Hash : Hash extends ResourceAnchorLinkFn<Resource> ? ReturnType<Hash> : never;
32
33
  type CreatedResourceHref = {
33
34
  /**
@@ -50,14 +51,14 @@ type CreateResourceLinkWithHash<Resource extends string, Hash extends ResourceLi
50
51
  hash: InferHashFromResourceLinkHref<Resource, Hash>;
51
52
  };
52
53
  };
53
- type CreatedResourceLink<Resources extends ReadonlyArray<ResourceDefinition>, Config extends CreateResourceLinkConfig<Resources>> = { [Resource in keyof Config]: Resource extends LayoutResourceKey<Resources> ? Config[Resource] extends {
54
+ type CreatedResourceLink<Resources extends ReadonlyArray<ResourceDefinition>, Config> = { [Resource in keyof Config]-?: Resource extends ResourceLinkConfigResource<Resources> ? Config[Resource] extends {
54
55
  hash: infer hash extends ResourceLinkHref<Resource>;
55
56
  } ? CreateResourceLinkWithHash<Resource, hash> : CreatedResourceLinkBase<Resource> : never }[keyof Config];
56
57
  interface CreateResourceLinksFn<Resources extends ReadonlyArray<ResourceDefinition>> {
57
- <const Config extends CreateResourceLinkConfig<Resources>>(config: Config): Array<CreatedResourceLink<Resources, Config>>;
58
+ <const Resource extends ResourceLinkConfigResource<Resources>>(config: CreateResourceLinkConfig<Resources, Resource>): Array<CreatedResourceLink<Resources, CreateResourceLinkConfig<Resources, Resource>>>;
58
59
  withGroups: CreateResourceLinksWithGroupsFn<Resources>;
59
60
  }
60
- interface CreateResourceLinkGroupOptions<Resources extends ReadonlyArray<ResourceDefinition>, Links extends CreateResourceLinkConfig<Resources> = CreateResourceLinkConfig<Resources>> {
61
+ interface CreateResourceLinkGroupOptions<Resources extends ReadonlyArray<ResourceDefinition>, Links extends object = CreateResourceLinkConfig<Resources>> {
61
62
  /**
62
63
  * The label of the group. This is the text that will be displayed for the group.
63
64
  */
@@ -72,7 +73,7 @@ interface CreateResourceLinkGroupOptions<Resources extends ReadonlyArray<Resourc
72
73
  */
73
74
  links: Links;
74
75
  }
75
- type CreateResourceLinkGroupInput<Resources extends ReadonlyArray<ResourceDefinition>> = CreateResourceLinkGroupOptions<Resources, CreateResourceLinkConfig<Resources>>;
76
+ type CreateResourceLinkGroupInput<Resources extends ReadonlyArray<ResourceDefinition>, Resource extends ResourceLinkConfigResource<Resources> = ResourceLinkConfigResource<Resources>> = CreateResourceLinkGroupOptions<Resources, CreateResourceLinkConfig<Resources, Resource>>;
76
77
  type AnyCreatedResourceLink<Resources extends ReadonlyArray<ResourceDefinition>> = { [Resource in LayoutResourceKey<Resources>]: CreatedResourceLinkBase<Resource> | CreateResourceLinkWithHash<Resource, string> }[LayoutResourceKey<Resources>];
77
78
  type CreateResourceLinksWithGroups<Resources extends ReadonlyArray<ResourceDefinition>> = {
78
79
  id: string;
@@ -80,7 +81,7 @@ type CreateResourceLinksWithGroups<Resources extends ReadonlyArray<ResourceDefin
80
81
  icon: ReactNode;
81
82
  links: Array<AnyCreatedResourceLink<Resources>>;
82
83
  };
83
- type CreateResourceLinksWithGroupsFn<Resources extends ReadonlyArray<ResourceDefinition>> = (groups: ReadonlyArray<CreateResourceLinkGroupInput<Resources>>) => Array<CreateResourceLinksWithGroups<Resources>>;
84
+ type CreateResourceLinksWithGroupsFn<Resources extends ReadonlyArray<ResourceDefinition>> = <const Resource extends ResourceLinkConfigResource<Resources>>(groups: ReadonlyArray<CreateResourceLinkGroupInput<Resources, Resource>>) => Array<CreateResourceLinksWithGroups<Resources>>;
84
85
  //#endregion
85
86
  export { CreateResourceLinkConfig, CreateResourceLinkGroupInput, CreateResourceLinkGroupOptions, CreateResourceLinkOptions, CreateResourceLinksFn, CreateResourceLinksWithGroups, CreateResourceLinksWithGroupsFn, CreatedResourceHref, CreatedResourceLink, CreatedResourceLinkBase, InferHashFromResourceLinkHref, ResourceAnchorLinkFn, ResourceLinkHref };
86
87
  //# sourceMappingURL=create-resource-links.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-resource-links.d.mts","names":[],"sources":["../../src/create-config/create-resource-links.ts"],"mappings":";;;;KAOY,oBAAA,6BACV,QAAA,EAAU,QAAQ;AAAA,KAGR,gBAAA,qCAER,oBAAoB,CAAC,QAAA;AAAA,UAER,yBAAA,mBACG,aAAA,CAAc,kBAAA,oBACf,iBAAA,CAAkB,SAAA;EAVL;;;EAe9B,KAAA;EAdU;;;AAAQ;EAmBlB,IAAA,GAAO,SAAA;EAhBmB;;;;EAqB1B,IAAA,GAAO,gBAAA,CAAiB,QAAA;EAnBD;;AAAQ;AAEjC;;;EAwBE,IAAA,GAAO,gBAAA,CAAiB,QAAA;AAAA;AAAA,KAGd,wBAAA,mBACQ,aAAA,CAAc,kBAAA,oBAEnB,iBAAA,CAAkB,SAAA,KAAc,yBAAA,CAC3C,SAAA,EACA,QAAA;AAAA,KAIQ,6BAAA,uCAEG,gBAAA,CAAiB,QAAA,KAC5B,IAAA,kBACA,IAAA,GACA,IAAA,SAAa,oBAAA,CAAqB,QAAA,IAChC,UAAA,CAAW,IAAA;AAAA,KAGL,mBAAA;EArBc;;;EAyBxB,IAAA;EAhDA;;;EAoDA,KAAK;AAAA;AAAA,KAGK,uBAAA;EACV,IAAA,EAAM,mBAAA;EACN,KAAA;EACA,QAAA,EAAU,QAAA;EACV,IAAA,EAAM,SAAA;AAAA;AAAA,KAEI,0BAAA,uCAEG,gBAAA,CAAiB,QAAA,KAC5B,IAAA,CAAK,uBAAA,CAAwB,QAAA;EAC/B,IAAA,EAAM,mBAAA;IACJ,IAAA,EAAM,6BAAA,CAA8B,QAAA,EAAU,IAAA;EAAA;AAAA;AAAA,KAItC,mBAAA,mBACQ,aAAA,CAAc,kBAAA,kBACjB,wBAAA,CAAyB,SAAA,0BAErB,MAAA,GAAS,QAAA,SAAiB,iBAAA,CAAkB,SAAA,IAC3D,MAAA,CAAO,QAAA;EACL,IAAA,qBAAyB,gBAAA,CAAiB,QAAA;AAAA,IAE1C,0BAAA,CAA2B,QAAA,EAAU,IAAA,IACrC,uBAAA,CAAwB,QAAA,kBAExB,MAAA;AAAA,UAES,qBAAA,mBACG,aAAA,CAAc,kBAAA;EAAA,sBAEV,wBAAA,CAAyB,SAAA,GAC7C,MAAA,EAAQ,MAAA,GACP,KAAA,CAAM,mBAAA,CAAoB,SAAA,EAAW,MAAA;EACxC,UAAA,EAAY,+BAAA,CAAgC,SAAA;AAAA;AAAA,UAG7B,8BAAA,mBACG,aAAA,CAAc,kBAAA,iBAClB,wBAAA,CAAyB,SAAA,IACrC,wBAAA,CAAyB,SAAA;EAlEkB;;;EAuE7C,KAAA;EAzEkB;;;;EA8ElB,IAAA,GAAO,SAAA;EA5EsC;;;EAgF7C,KAAA,EAAO,KAAA;AAAA;AAAA,KAGG,4BAAA,mBACQ,aAAA,CAAc,kBAAA,KAC9B,8BAAA,CACF,SAAA,EACA,wBAAA,CAAyB,SAAA;AAAA,KAGf,sBAAA,mBACQ,aAAA,CAAc,kBAAA,oBAEnB,iBAAA,CAAkB,SAAA,IAC3B,uBAAA,CAAwB,QAAA,IACxB,0BAAA,CAA2B,QAAA,YAC/B,iBAAA,CAAkB,SAAA;AAAA,KAER,6BAAA,mBACQ,aAAA,CAAc,kBAAA;EAEhC,EAAA;EACA,KAAA;EACA,IAAA,EAAM,SAAA;EACN,KAAA,EAAO,KAAA,CAAM,sBAAA,CAAuB,SAAA;AAAA;AAAA,KAG1B,+BAAA,mBACQ,aAAA,CAAc,kBAAA,MAEhC,MAAA,EAAQ,aAAA,CAAc,4BAAA,CAA6B,SAAA,OAChD,KAAA,CAAM,6BAAA,CAA8B,SAAA"}
1
+ {"version":3,"file":"create-resource-links.d.mts","names":[],"sources":["../../src/create-config/create-resource-links.ts"],"mappings":"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"}
@@ -1,5 +1,3 @@
1
- import { createIsValidResourceFn } from "../resource.mjs";
2
-
3
1
  //#region src/create-config/create-resource-links.ts
4
2
  function resolveResourceLinkHref(value, resource, fallback) {
5
3
  return typeof value === "function" ? value(resource) : value ?? fallback;
@@ -11,9 +9,8 @@ function createFullResourceLinkHref(href, hash) {
11
9
  if (href.includes("#")) return href;
12
10
  return `${href}#${normalizeResourceLinkHash(hash)}`;
13
11
  }
14
- function createResourceLinksFromConfig(isValidResource, config) {
12
+ function createResourceLinksFromConfig(config) {
15
13
  return Object.entries(config).map(([resource, config]) => {
16
- if (!isValidResource(resource)) throw new Error(`[createResourceLinks]: Invalid resource: ${resource}`);
17
14
  if (!config) throw new Error(`[createResourceLinks]: "config" is required for the ${resource} resource.`);
18
15
  if (typeof config !== "object") throw new Error(`[createResourceLinks]: "config" must be an object for the ${resource} resource. Received ${typeof config}`);
19
16
  if (!("label" in config)) throw new Error(`[createResourceLinks]: "label" is required for the ${resource} resource.`);
@@ -39,7 +36,7 @@ function createResourceLinkGroupId() {
39
36
  if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") return crypto.randomUUID();
40
37
  return `group-${Math.random().toString(36).slice(2, 11)}`;
41
38
  }
42
- function createResourceLinksWithGroups(isValidResource, groups) {
39
+ function createResourceLinksWithGroups(groups) {
43
40
  if (!Array.isArray(groups)) throw new Error("[createResourceLinks.withGroups]: \"groups\" must be an array.");
44
41
  return groups.map((group, index) => {
45
42
  if (!group) throw new Error(`[createResourceLinks.withGroups]: group at index ${index} is required.`);
@@ -51,17 +48,16 @@ function createResourceLinksWithGroups(isValidResource, groups) {
51
48
  id: createResourceLinkGroupId(),
52
49
  label: "label" in group ? group.label ?? null : null,
53
50
  icon: "icon" in group ? group.icon : null,
54
- links: createResourceLinksFromConfig(isValidResource, group.links)
51
+ links: createResourceLinksFromConfig(group.links)
55
52
  };
56
53
  });
57
54
  }
58
- function createResourceLinksFn(resources) {
59
- const isValidResource = createIsValidResourceFn(resources);
55
+ function createResourceLinksFn(_resources) {
60
56
  function createResourceLinks(config) {
61
- return createResourceLinksFromConfig(isValidResource, config);
57
+ return createResourceLinksFromConfig(config);
62
58
  }
63
59
  function withGroups(groups) {
64
- return createResourceLinksWithGroups(isValidResource, groups);
60
+ return createResourceLinksWithGroups(groups);
65
61
  }
66
62
  return Object.assign(createResourceLinks, { withGroups });
67
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"create-resource-links.mjs","names":[],"sources":["../../src/create-config/create-resource-links.ts"],"sourcesContent":["import { ReactNode } from 'react';\nimport {\n createIsValidResourceFn,\n type LayoutResourceKey,\n type ResourceDefinition,\n} from '../resource';\n\nexport type ResourceAnchorLinkFn<Resource extends string> = (\n resource: Resource,\n) => string;\n\nexport type ResourceLinkHref<Resource extends string> =\n | string\n | ResourceAnchorLinkFn<Resource>;\n\nexport interface CreateResourceLinkOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends LayoutResourceKey<Resources>,\n> {\n /**\n * The label of the link. This is the text that will be displayed in the link.\n */\n label: string;\n /**\n * An optional icon to register with the link. This is a headless approach, meaning you have full control\n * over the icon's rendering.\n */\n icon?: ReactNode;\n /**\n * The href of the link. By default, the href will be `\"/\"`. While you **don't** need to include a hash,\n * if you do, it will override the `hash` property (if provided).\n */\n href?: ResourceLinkHref<Resource>;\n /**\n * The hash of the link. By default, the hash will be the resource name. If you need to customize it, you can provide\n * a string or a function that returns a string.\n *\n * @remarks A `\"#\"` is not required. The generated href will include it automatically.\n */\n hash?: ResourceLinkHref<Resource>;\n}\n\nexport type CreateResourceLinkConfig<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = {\n [resource in LayoutResourceKey<Resources>]?: CreateResourceLinkOptions<\n Resources,\n resource\n >;\n};\n\nexport type InferHashFromResourceLinkHref<\n Resource extends string,\n Hash extends ResourceLinkHref<Resource>,\n> = Hash extends string\n ? Hash\n : Hash extends ResourceAnchorLinkFn<Resource>\n ? ReturnType<Hash>\n : never;\n\nexport type CreatedResourceHref = {\n /**\n * The full generated href with the `hash` if provided.\n */\n full: string;\n /**\n * The given href. This is the same value as the `href` property of the config.\n */\n given: string;\n};\n\nexport type CreatedResourceLinkBase<Resource extends string> = {\n href: CreatedResourceHref;\n label: string;\n resource: Resource;\n icon: ReactNode;\n};\nexport type CreateResourceLinkWithHash<\n Resource extends string,\n Hash extends ResourceLinkHref<Resource>,\n> = Omit<CreatedResourceLinkBase<Resource>, 'href'> & {\n href: CreatedResourceHref & {\n hash: InferHashFromResourceLinkHref<Resource, Hash>;\n };\n};\n\nexport type CreatedResourceLink<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Config extends CreateResourceLinkConfig<Resources>,\n> = {\n [Resource in keyof Config]: Resource extends LayoutResourceKey<Resources>\n ? Config[Resource] extends {\n hash: infer hash extends ResourceLinkHref<Resource>;\n }\n ? CreateResourceLinkWithHash<Resource, hash>\n : CreatedResourceLinkBase<Resource>\n : never;\n}[keyof Config];\n\nexport interface CreateResourceLinksFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> {\n <const Config extends CreateResourceLinkConfig<Resources>>(\n config: Config,\n ): Array<CreatedResourceLink<Resources, Config>>;\n withGroups: CreateResourceLinksWithGroupsFn<Resources>;\n}\n\nexport interface CreateResourceLinkGroupOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Links extends CreateResourceLinkConfig<Resources> =\n CreateResourceLinkConfig<Resources>,\n> {\n /**\n * The label of the group. This is the text that will be displayed for the group.\n */\n label?: string;\n /**\n * An optional icon to register with the group. This is a headless approach, meaning you have full control\n * over the icon's rendering.\n */\n icon?: ReactNode;\n /**\n * The resource links in this group.\n */\n links: Links;\n}\n\nexport type CreateResourceLinkGroupInput<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = CreateResourceLinkGroupOptions<\n Resources,\n CreateResourceLinkConfig<Resources>\n>;\n\nexport type AnyCreatedResourceLink<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = {\n [Resource in LayoutResourceKey<Resources>]:\n | CreatedResourceLinkBase<Resource>\n | CreateResourceLinkWithHash<Resource, string>;\n}[LayoutResourceKey<Resources>];\n\nexport type CreateResourceLinksWithGroups<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = {\n id: string;\n label: string | null;\n icon: ReactNode;\n links: Array<AnyCreatedResourceLink<Resources>>;\n};\n\nexport type CreateResourceLinksWithGroupsFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = (\n groups: ReadonlyArray<CreateResourceLinkGroupInput<Resources>>,\n) => Array<CreateResourceLinksWithGroups<Resources>>;\n\nfunction resolveResourceLinkHref<Resource extends string>(\n value: ResourceLinkHref<Resource> | undefined,\n resource: Resource,\n fallback: string,\n) {\n return typeof value === 'function' ? value(resource) : (value ?? fallback);\n}\n\nfunction normalizeResourceLinkHash(hash: string) {\n return hash.replace(/^#+/, '');\n}\n\nfunction createFullResourceLinkHref(href: string, hash: string) {\n if (href.includes('#')) {\n return href;\n }\n\n return `${href}#${normalizeResourceLinkHash(hash)}`;\n}\n\nfunction createResourceLinksFromConfig<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(\n isValidResource: ReturnType<typeof createIsValidResourceFn<Resources>>,\n config: CreateResourceLinkConfig<Resources>,\n) {\n return Object.entries(config).map(([resource, config]) => {\n if (!isValidResource(resource)) {\n throw new Error(`[createResourceLinks]: Invalid resource: ${resource}`);\n }\n\n if (!config) {\n throw new Error(\n `[createResourceLinks]: \"config\" is required for the ${resource} resource.`,\n );\n }\n\n if (typeof config !== 'object') {\n throw new Error(\n `[createResourceLinks]: \"config\" must be an object for the ${resource} resource. Received ${typeof config}`,\n );\n }\n\n if (!('label' in config)) {\n throw new Error(\n `[createResourceLinks]: \"label\" is required for the ${resource} resource.`,\n );\n }\n\n if (typeof config.label !== 'string') {\n throw new Error(\n `[createResourceLinks]: \"label\" must be a string for the ${resource} resource. Received ${typeof config.label}`,\n );\n }\n\n const linkConfig = config as CreateResourceLinkOptions<\n Resources,\n typeof resource\n >;\n\n if (\n 'href' in linkConfig &&\n linkConfig.href !== undefined &&\n typeof linkConfig.href !== 'string' &&\n typeof linkConfig.href !== 'function'\n ) {\n throw new Error(\n `[createResourceLinks]: \"href\" must be a string or function for the ${resource} resource. Received ${typeof linkConfig.href}`,\n );\n }\n\n if (\n 'hash' in linkConfig &&\n linkConfig.hash !== undefined &&\n typeof linkConfig.hash !== 'string' &&\n typeof linkConfig.hash !== 'function'\n ) {\n throw new Error(\n `[createResourceLinks]: \"hash\" must be a string or function for the ${resource} resource. Received ${typeof linkConfig.hash}`,\n );\n }\n\n const givenHref = resolveResourceLinkHref(linkConfig.href, resource, '/');\n const givenHash = resolveResourceLinkHref(\n linkConfig.hash,\n resource,\n resource,\n );\n const href = {\n given: givenHref,\n full: createFullResourceLinkHref(givenHref, givenHash),\n ...(linkConfig.hash !== undefined && !givenHref.includes('#')\n ? { hash: normalizeResourceLinkHash(givenHash) }\n : {}),\n };\n\n return {\n href,\n label: config.label,\n resource,\n icon: 'icon' in config ? config.icon : null,\n };\n });\n}\n\nfunction createResourceLinkGroupId() {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n\n return `group-${Math.random().toString(36).slice(2, 11)}`;\n}\n\nfunction createResourceLinksWithGroups<\n Resources extends ReadonlyArray<ResourceDefinition>,\n>(\n isValidResource: ReturnType<typeof createIsValidResourceFn<Resources>>,\n groups: ReadonlyArray<CreateResourceLinkGroupInput<Resources>>,\n): Array<CreateResourceLinksWithGroups<Resources>> {\n if (!Array.isArray(groups)) {\n throw new Error(\n '[createResourceLinks.withGroups]: \"groups\" must be an array.',\n );\n }\n\n return groups.map((group, index) => {\n if (!group) {\n throw new Error(\n `[createResourceLinks.withGroups]: group at index ${index} is required.`,\n );\n }\n\n if (typeof group !== 'object') {\n throw new Error(\n `[createResourceLinks.withGroups]: group at index ${index} must be an object. Received ${typeof group}`,\n );\n }\n\n if (\n 'label' in group &&\n group.label !== undefined &&\n typeof group.label !== 'string'\n ) {\n throw new Error(\n `[createResourceLinks.withGroups]: \"label\" must be a string for group at index ${index}. Received ${typeof group.label}`,\n );\n }\n\n if (!('links' in group)) {\n throw new Error(\n `[createResourceLinks.withGroups]: \"links\" is required for group at index ${index}.`,\n );\n }\n\n if (\n typeof group.links !== 'object' ||\n group.links === null ||\n Array.isArray(group.links)\n ) {\n throw new Error(\n `[createResourceLinks.withGroups]: \"links\" must be an object for group at index ${index}. Received ${Array.isArray(group.links) ? 'array' : typeof group.links}`,\n );\n }\n\n return {\n id: createResourceLinkGroupId(),\n label: 'label' in group ? (group.label ?? null) : null,\n icon: 'icon' in group ? group.icon : null,\n links: createResourceLinksFromConfig(isValidResource, group.links),\n };\n }) as Array<CreateResourceLinksWithGroups<Resources>>;\n}\n\nexport function createResourceLinksFn<\n const Resources extends ReadonlyArray<ResourceDefinition>,\n>(resources: Resources): CreateResourceLinksFn<Resources> {\n const isValidResource = createIsValidResourceFn(resources);\n\n function createResourceLinks<\n const Config extends CreateResourceLinkConfig<Resources>,\n >(config: Config) {\n return createResourceLinksFromConfig(isValidResource, config);\n }\n\n function withGroups(\n groups: ReadonlyArray<CreateResourceLinkGroupInput<Resources>>,\n ) {\n return createResourceLinksWithGroups(isValidResource, groups);\n }\n\n return Object.assign(createResourceLinks, {\n withGroups,\n }) as CreateResourceLinksFn<Resources>;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"create-resource-links.mjs","names":[],"sources":["../../src/create-config/create-resource-links.ts"],"sourcesContent":["import { ReactNode } from 'react';\nimport {\n type LayoutResourceKey,\n type ResourceDefinition,\n} from '../resource';\n\nexport type ResourceAnchorLinkFn<Resource extends string> = (\n resource: Resource,\n) => string;\n\nexport type ResourceLinkHref<Resource extends string> =\n | string\n | ResourceAnchorLinkFn<Resource>;\n\nexport type ResourceLinkConfigResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = LayoutResourceKey<Resources> | (string & {});\nexport interface CreateResourceLinkOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends ResourceLinkConfigResource<Resources>,\n> {\n /**\n * The label of the link. This is the text that will be displayed in the link.\n */\n label: string;\n /**\n * An optional icon to register with the link. This is a headless approach, meaning you have full control\n * over the icon's rendering.\n */\n icon?: ReactNode;\n /**\n * The href of the link. By default, the href will be `\"/\"`. While you **don't** need to include a hash,\n * if you do, it will override the `hash` property (if provided).\n */\n href?: ResourceLinkHref<Resource>;\n /**\n * The hash of the link. By default, the hash will be the resource name. If you need to customize it, you can provide\n * a string or a function that returns a string.\n *\n * @remarks A `\"#\"` is not required. The generated href will include it automatically.\n */\n hash?: ResourceLinkHref<Resource>;\n}\n\nexport type CreateResourceLinkConfig<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends ResourceLinkConfigResource<Resources> = ResourceLinkConfigResource<Resources>,\n> = {\n [Key in Resource]?: CreateResourceLinkOptions<\n Resources,\n Key\n >;\n};\n\nexport type InferHashFromResourceLinkHref<\n Resource extends string,\n Hash extends ResourceLinkHref<Resource>,\n> = Hash extends string\n ? Hash\n : Hash extends ResourceAnchorLinkFn<Resource>\n ? ReturnType<Hash>\n : never;\n\nexport type CreatedResourceHref = {\n /**\n * The full generated href with the `hash` if provided.\n */\n full: string;\n /**\n * The given href. This is the same value as the `href` property of the config.\n */\n given: string;\n};\n\nexport type CreatedResourceLinkBase<Resource extends string> = {\n href: CreatedResourceHref;\n label: string;\n resource: Resource;\n icon: ReactNode;\n};\nexport type CreateResourceLinkWithHash<\n Resource extends string,\n Hash extends ResourceLinkHref<Resource>,\n> = Omit<CreatedResourceLinkBase<Resource>, 'href'> & {\n href: CreatedResourceHref & {\n hash: InferHashFromResourceLinkHref<Resource, Hash>;\n };\n};\n\nexport type CreatedResourceLink<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Config,\n> = {\n [Resource in keyof Config]-?: Resource extends ResourceLinkConfigResource<Resources>\n ? Config[Resource] extends {\n hash: infer hash extends ResourceLinkHref<Resource>;\n }\n ? CreateResourceLinkWithHash<Resource, hash>\n : CreatedResourceLinkBase<Resource>\n : never;\n}[keyof Config];\n\nexport interface CreateResourceLinksFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> {\n <const Resource extends ResourceLinkConfigResource<Resources>>(\n config: CreateResourceLinkConfig<Resources, Resource>,\n ): Array<\n CreatedResourceLink<\n Resources,\n CreateResourceLinkConfig<Resources, Resource>\n >\n >;\n withGroups: CreateResourceLinksWithGroupsFn<Resources>;\n}\n\nexport interface CreateResourceLinkGroupOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Links extends object =\n CreateResourceLinkConfig<Resources>,\n> {\n /**\n * The label of the group. This is the text that will be displayed for the group.\n */\n label?: string;\n /**\n * An optional icon to register with the group. This is a headless approach, meaning you have full control\n * over the icon's rendering.\n */\n icon?: ReactNode;\n /**\n * The resource links in this group.\n */\n links: Links;\n}\n\nexport type CreateResourceLinkGroupInput<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends ResourceLinkConfigResource<Resources> = ResourceLinkConfigResource<Resources>,\n> = CreateResourceLinkGroupOptions<\n Resources,\n CreateResourceLinkConfig<Resources, Resource>\n>;\n\nexport type AnyCreatedResourceLink<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = {\n [Resource in LayoutResourceKey<Resources>]:\n | CreatedResourceLinkBase<Resource>\n | CreateResourceLinkWithHash<Resource, string>;\n}[LayoutResourceKey<Resources>];\n\nexport type CreateResourceLinksWithGroups<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = {\n id: string;\n label: string | null;\n icon: ReactNode;\n links: Array<AnyCreatedResourceLink<Resources>>;\n};\n\nexport type CreateResourceLinksWithGroupsFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n> = <const Resource extends ResourceLinkConfigResource<Resources>>(\n groups: ReadonlyArray<CreateResourceLinkGroupInput<Resources, Resource>>,\n) => Array<CreateResourceLinksWithGroups<Resources>>;\n\nfunction resolveResourceLinkHref<Resource extends string>(\n value: ResourceLinkHref<Resource> | undefined,\n resource: Resource,\n fallback: string,\n) {\n return typeof value === 'function' ? value(resource) : (value ?? fallback);\n}\n\nfunction normalizeResourceLinkHash(hash: string) {\n return hash.replace(/^#+/, '');\n}\n\nfunction createFullResourceLinkHref(href: string, hash: string) {\n if (href.includes('#')) {\n return href;\n }\n\n return `${href}#${normalizeResourceLinkHash(hash)}`;\n}\n\nfunction createResourceLinksFromConfig<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends ResourceLinkConfigResource<Resources>,\n>(config: CreateResourceLinkConfig<Resources, Resource>) {\n return Object.entries(config).map(([resource, config]) => {\n if (!config) {\n throw new Error(\n `[createResourceLinks]: \"config\" is required for the ${resource} resource.`,\n );\n }\n\n if (typeof config !== 'object') {\n throw new Error(\n `[createResourceLinks]: \"config\" must be an object for the ${resource} resource. Received ${typeof config}`,\n );\n }\n\n if (!('label' in config)) {\n throw new Error(\n `[createResourceLinks]: \"label\" is required for the ${resource} resource.`,\n );\n }\n\n if (typeof config.label !== 'string') {\n throw new Error(\n `[createResourceLinks]: \"label\" must be a string for the ${resource} resource. Received ${typeof config.label}`,\n );\n }\n\n const linkConfig = config as CreateResourceLinkOptions<\n Resources,\n typeof resource\n >;\n\n if (\n 'href' in linkConfig &&\n linkConfig.href !== undefined &&\n typeof linkConfig.href !== 'string' &&\n typeof linkConfig.href !== 'function'\n ) {\n throw new Error(\n `[createResourceLinks]: \"href\" must be a string or function for the ${resource} resource. Received ${typeof linkConfig.href}`,\n );\n }\n\n if (\n 'hash' in linkConfig &&\n linkConfig.hash !== undefined &&\n typeof linkConfig.hash !== 'string' &&\n typeof linkConfig.hash !== 'function'\n ) {\n throw new Error(\n `[createResourceLinks]: \"hash\" must be a string or function for the ${resource} resource. Received ${typeof linkConfig.hash}`,\n );\n }\n\n const givenHref = resolveResourceLinkHref(linkConfig.href, resource, '/');\n const givenHash = resolveResourceLinkHref(\n linkConfig.hash,\n resource,\n resource,\n );\n const href = {\n given: givenHref,\n full: createFullResourceLinkHref(givenHref, givenHash),\n ...(linkConfig.hash !== undefined && !givenHref.includes('#')\n ? { hash: normalizeResourceLinkHash(givenHash) }\n : {}),\n };\n\n return {\n href,\n label: config.label,\n resource,\n icon: 'icon' in config ? config.icon : null,\n };\n });\n}\n\nfunction createResourceLinkGroupId() {\n if (\n typeof crypto !== 'undefined' &&\n typeof crypto.randomUUID === 'function'\n ) {\n return crypto.randomUUID();\n }\n\n return `group-${Math.random().toString(36).slice(2, 11)}`;\n}\n\nfunction createResourceLinksWithGroups<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Resource extends ResourceLinkConfigResource<Resources>,\n>(\n groups: ReadonlyArray<CreateResourceLinkGroupInput<Resources, Resource>>,\n): Array<CreateResourceLinksWithGroups<Resources>> {\n if (!Array.isArray(groups)) {\n throw new Error(\n '[createResourceLinks.withGroups]: \"groups\" must be an array.',\n );\n }\n\n return groups.map((group, index) => {\n if (!group) {\n throw new Error(\n `[createResourceLinks.withGroups]: group at index ${index} is required.`,\n );\n }\n\n if (typeof group !== 'object') {\n throw new Error(\n `[createResourceLinks.withGroups]: group at index ${index} must be an object. Received ${typeof group}`,\n );\n }\n\n if (\n 'label' in group &&\n group.label !== undefined &&\n typeof group.label !== 'string'\n ) {\n throw new Error(\n `[createResourceLinks.withGroups]: \"label\" must be a string for group at index ${index}. Received ${typeof group.label}`,\n );\n }\n\n if (!('links' in group)) {\n throw new Error(\n `[createResourceLinks.withGroups]: \"links\" is required for group at index ${index}.`,\n );\n }\n\n if (\n typeof group.links !== 'object' ||\n group.links === null ||\n Array.isArray(group.links)\n ) {\n throw new Error(\n `[createResourceLinks.withGroups]: \"links\" must be an object for group at index ${index}. Received ${Array.isArray(group.links) ? 'array' : typeof group.links}`,\n );\n }\n\n return {\n id: createResourceLinkGroupId(),\n label: 'label' in group ? (group.label ?? null) : null,\n icon: 'icon' in group ? group.icon : null,\n links: createResourceLinksFromConfig(group.links),\n };\n }) as Array<CreateResourceLinksWithGroups<Resources>>;\n}\n\nexport function createResourceLinksFn<\n const Resources extends ReadonlyArray<ResourceDefinition>,\n>(_resources: Resources): CreateResourceLinksFn<Resources> {\n function createResourceLinks<\n const Resource extends ResourceLinkConfigResource<Resources>,\n >(config: CreateResourceLinkConfig<Resources, Resource>) {\n return createResourceLinksFromConfig(config);\n }\n\n function withGroups<\n const Resource extends ResourceLinkConfigResource<Resources>,\n >(\n groups: ReadonlyArray<CreateResourceLinkGroupInput<Resources, Resource>>,\n ) {\n return createResourceLinksWithGroups(groups);\n }\n\n return Object.assign(createResourceLinks, {\n withGroups,\n }) as CreateResourceLinksFn<Resources>;\n}\n"],"mappings":"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"}
@@ -3,6 +3,8 @@ const require_utils = require('../utils.cjs');
3
3
  const require_capitalize = require('../utils/capitalize.cjs');
4
4
  const require_get_component = require('./get-component.cjs');
5
5
  const require_create_resource_links = require('./create-resource-links.cjs');
6
+ const require_for_resource = require('./for-resource.cjs');
7
+ const require_for_resources = require('./for-resources.cjs');
6
8
  let _jfdevelops_react_layout_composables = require("@jfdevelops/react-layout-composables");
7
9
  let _jfdevelops_react_layout_validator = require("@jfdevelops/react-layout-validator");
8
10
  let react_jsx_runtime = require("react/jsx-runtime");
@@ -121,24 +123,6 @@ function defineResourceLayout(options) {
121
123
  })
122
124
  });
123
125
  });
124
- function createLayoutForResource(defaultName, resource, defaults) {
125
- return (({ name, ...rest }) => definedResourceLayout({
126
- ...defaults,
127
- name: name ?? defaultName,
128
- resource,
129
- ...resolveLayoutOptionDefaults(defaults, rest)
130
- }));
131
- }
132
- function createLayoutForResourceBuilder(defaultName, resource) {
133
- const createLayout = createLayoutForResource(defaultName, resource, {});
134
- const setDefaults = ((defaults) => createLayoutForResource(defaultName, resource, defaults));
135
- return Object.assign(createLayout, { setDefaults });
136
- }
137
- const forResource = (options) => {
138
- const { name: defaultName, resource } = options;
139
- if (!resource) throw new Error("\"resource\" is required when calling \"forResource\"");
140
- return createLayoutForResourceBuilder(defaultName, resource);
141
- };
142
126
  const createTopLevelMakeComposable = () => {
143
127
  return (options) => {
144
128
  const layout = definedResourceLayout(options);
@@ -146,7 +130,18 @@ function defineResourceLayout(options) {
146
130
  return layout.makeComposable();
147
131
  };
148
132
  };
149
- const createResourceLayoutExtras = { forResource };
133
+ const { createLayoutForResourceBuilder, forResource } = require_for_resource.createForResource({
134
+ createResourceLayout: definedResourceLayout,
135
+ resolveLayoutOptionDefaults
136
+ });
137
+ const createResourceLayoutExtras = {
138
+ forResource,
139
+ forResources: require_for_resources.createForResources({
140
+ createLayoutForResource: createLayoutForResourceBuilder,
141
+ ...layout.composables ? { createMakeComposableLayout: createTopLevelMakeComposable } : {},
142
+ createResourceLayout: definedResourceLayout
143
+ })
144
+ };
150
145
  if (layout.composables) createResourceLayoutExtras.makeComposable = createTopLevelMakeComposable();
151
146
  return {
152
147
  createResourceConfig: require_get_component.createResourceConfig,
@@ -1 +1 @@
1
- {"version":3,"file":"define-layout.cjs","names":["capitalize","functionalUpdate","normalizeResources","toResourceEnum","createProp","pick","LayoutComposablePresetProvider","createResourceLinksFn"],"sources":["../../src/create-config/define-layout.tsx"],"sourcesContent":["import type { JSX } from 'react';\nimport {\n type ComposableComponents,\n type ComposableNameContext,\n type ComposableResourceLayout,\n type CreateLayoutComposable,\n collectComposablePresetEntries,\n LayoutComposablePresetProvider,\n MakeComposable,\n makeComposable,\n MakeComposableOptions,\n RequiredPresetLayoutProps,\n resolveComposablePresetProps,\n resolveLayoutComposables,\n} from '@jfdevelops/react-layout-composables';\nimport {\n type AnyBuiltPropDefinition,\n createPrimitivePropBuilder,\n createProp,\n type ResolveLayoutProps,\n type ResolveProps,\n resolvePropDefinitionValues,\n validateProps,\n} from '@jfdevelops/react-layout-validator';\nimport {\n IncludedProps,\n InferredInProps,\n InPropsDefinition,\n InPropsObject,\n LayoutRenderProps,\n MergedLayoutInProps,\n} from '../props';\nimport {\n normalizeResources,\n toResourceEnum,\n type LayoutResourceKey,\n type ResourceDefinition,\n} from '../resource';\nimport { BaseComponent, functionalUpdate, pick, Show, Updater } from '../utils';\nimport { capitalize } from '../utils/capitalize';\nimport {\n type CreateResourceConfigFn,\n createResourceConfig,\n} from './get-component';\nimport {\n createResourceLinksFn,\n type CreateResourceLinksFn,\n} from './create-resource-links';\n\ntype LayoutIncludeProps<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n> = IncludedProps<MergedLayoutInProps<Resources, Options, Composables>>;\n\ntype LayoutProps<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n IncludeProps extends LayoutIncludeProps<Resources, Options, Composables> = {},\n CustomProps extends InPropsObject = {},\n> = {\n /**\n * Props to include in the layout.\n */\n include?: LayoutIncludeProps<Resources, Options, Composables> & 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(includeKey: string, definition: unknown) {\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 Composables extends ComposableComponents = {},\n IncludeProps extends LayoutIncludeProps<Resources, Options, Composables> = {},\n CustomProps extends InPropsObject = {},\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<\n Resources,\n Options,\n Composables,\n IncludeProps,\n CustomProps\n >;\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<\n Resources,\n Options,\n Composables,\n IncludeProps,\n CustomProps\n >,\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 Composables extends ComposableComponents = {},\n> = ResolveLayoutProps<InferredInProps<Resources, InProps>> &\n RequiredPresetLayoutProps<Composables>;\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\nexport type CreateResourceLayoutOptionsBase<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Props extends InPropsObject = {},\n> = {\n name: Name;\n resource: Resource;\n props?: Props;\n};\ntype CreateResourceLayoutOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Props extends InPropsObject = {},\n> = LayoutPropsForResource<Resources, InProps, Composables> &\n CreateResourceLayoutOptionsBase<Resources, Name, Resource, Props>;\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 Composables extends ComposableComponents,\n Props extends InPropsObject = {},\n Defaults extends LayoutPropDefaults = {},\n> = ResolveLayoutPropsWithDefaults<\n LayoutPropsForResource<Resources, InProps, Composables>,\n Defaults\n> & {\n props?: Props;\n};\ntype CreatedLayoutForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n CustomProps extends InPropsObject = {},\n Defaults extends LayoutPropDefaults = {},\n> = <OverrideName extends string = Name, Props extends InPropsObject = {}>(\n options: CreatedLayoutForResourceOptions<\n Resources,\n InProps,\n Composables,\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 Composables extends ComposableComponents = {},\n> = Partial<LayoutPropsForResource<Resources, InProps, Composables>>;\n\ntype ResolvedSetDefaultProps<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n Defaults extends SetDefaultPropsForResource<Resources, InProps, Composables>,\n> = {\n [K in keyof Defaults &\n keyof LayoutPropsForResource<\n Resources,\n InProps,\n Composables\n >]: LayoutPropsForResource<Resources, InProps, Composables>[K];\n};\n\ntype SetDefaultPropForResourceFn<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n CustomProps extends InPropsObject = {},\n> = <\n const Defaults extends SetDefaultPropsForResource<\n Resources,\n InProps,\n Composables\n >,\n>(\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 Composables,\n Name,\n Resource,\n CustomProps,\n ResolvedSetDefaultProps<Resources, InProps, Composables, Defaults>\n>;\n\ntype CreateLayoutForResource<\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> = <Name extends string, Resource extends LayoutResourceKey<Resources>>(\n options: CreateLayoutForResourceOptions<Resources, Name, Resource>,\n) => CreatedLayoutForResource<\n Resources,\n InProps,\n Composables,\n Name,\n Resource,\n CustomProps\n> & {\n /**\n * Set default values for layout props in a single call.\n */\n setDefaults: SetDefaultPropForResourceFn<\n Resources,\n InProps,\n Composables,\n Name,\n Resource,\n CustomProps\n >;\n};\ntype CreateResourceLayoutFnImpl<\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 Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Props extends InPropsObject = {},\n>(\n options: CreateResourceLayoutOptions<\n Resources,\n InProps,\n Composables,\n Name,\n Resource,\n Props\n >,\n) => ResourceLayoutComponent<Name, CustomProps, Composables>;\n\nexport type CreateResourceLayoutMakeComposableOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Props extends InPropsObject = {},\n> = CreateResourceLayoutOptionsBase<Resources, Name, Resource, Props> &\n Partial<LayoutPropsForResource<Resources, InProps, Composables>>;\n\ntype CreateResourceLayoutMakeComposableFn<\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 Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Props extends InPropsObject = {},\n>(\n options: CreateResourceLayoutMakeComposableOptions<\n Resources,\n InProps,\n Composables,\n Name,\n Resource,\n Props\n >,\n) => ComposableResourceLayout<Composables, Name, any, any, any>;\n\ntype CreateResourceLayoutFnBase<\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> = CreateResourceLayoutFnImpl<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n> & {\n /**\n * A function to create a resource layout for a specific resource.\n */\n forResource: CreateLayoutForResource<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n};\n\ntype CreateResourceLayoutMakeComposableMember<\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> = [keyof Composables] extends [never]\n ? {}\n : {\n makeComposable: CreateResourceLayoutMakeComposableFn<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n };\n\nexport type CreateResourceLayoutFn<\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> = CreateResourceLayoutFnBase<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n> &\n CreateResourceLayoutMakeComposableMember<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n\ntype DefinedResourceLayout<\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 createResourceConfig: CreateResourceConfigFn<Resources>;\n createResourceLayout: CreateResourceLayoutFn<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n createResourceLinks: CreateResourceLinksFn<Resources>;\n};\n\nexport function defineResourceLayout<\n const Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents = {},\n const IncludeProps extends LayoutIncludeProps<\n Resources,\n InProps,\n Composables\n > = {},\n CustomProps extends InPropsObject = {},\n>(\n options: CreateViewMapOptions<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\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 = (<\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Props extends InPropsObject = {},\n >(\n layoutOptions: CreateResourceLayoutOptions<\n Resources,\n InProps,\n Composables,\n Name,\n Resource,\n Props\n >,\n ) => {\n const {\n name,\n props: instancePropDefinitions,\n ...layoutOptionProps\n } = layoutOptions;\n const createComposableLayout =\n makeComposable<\n LayoutRenderProps<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >\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 mergedResolvedInProps = { ...resolvedInProps };\n\n for (const {\n props: presetPropDefinitions,\n } of collectComposablePresetEntries(resolvedComposables)) {\n Object.assign(mergedResolvedInProps, presetPropDefinitions);\n }\n\n const composablePresetProps = resolveComposablePresetProps(\n resolvedComposables,\n layoutOptionProps as Record<string, unknown>,\n );\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 mergedResolvedInProps,\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 = mergedResolvedInProps[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, mergedResolvedInProps[key]),\n validatedIncludedProps[\n key as keyof typeof validatedIncludedProps\n ],\n ],\n ];\n }),\n );\n const layoutRenderProps = {\n ...validatedProps,\n ...layoutRenderIncludedProps,\n } as unknown as LayoutRenderProps<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n\n return (\n <LayoutComposablePresetProvider value={composablePresetProps}>\n {render(layoutRenderProps, mergedRenderContext)}\n </LayoutComposablePresetProvider>\n );\n }\n\n function createComposition<\n LayoutName extends string,\n const Defined extends MakeComposableOptions<Composables, LayoutName>,\n >(compositionOptions: Defined) {\n if (!compositionOptions.components) {\n return {} as ResourceLayoutComposition<LayoutName, Composables>;\n }\n\n return {\n makeComposable: createComposableLayout(\n compositionOptions,\n ) as MakeComposable<Composables, LayoutName>,\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 }) as CreateResourceLayoutFnImpl<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\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 Composables,\n Name,\n Resource,\n CustomProps,\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 Composables,\n Name,\n Resource,\n CustomProps\n > & {\n setDefaults: SetDefaultPropForResourceFn<\n Resources,\n InProps,\n Composables,\n Name,\n Resource,\n CustomProps\n >;\n } {\n const createLayout = createLayoutForResource(defaultName, resource, {});\n\n const setDefaults = ((defaults) =>\n createLayoutForResource(\n defaultName,\n resource,\n defaults,\n )) as SetDefaultPropForResourceFn<\n Resources,\n InProps,\n Composables,\n Name,\n Resource,\n CustomProps\n >;\n\n return Object.assign(createLayout, { setDefaults });\n }\n const forResource: CreateLayoutForResource<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\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\n const createTopLevelMakeComposable = () => {\n return (options: Record<string, unknown>) => {\n const layout = definedResourceLayout(options as never);\n\n if (\n !('makeComposable' in layout) ||\n typeof layout.makeComposable !== 'function'\n ) {\n throw new Error(\n 'makeComposable requires composables to be defined in the layout',\n );\n }\n\n return layout.makeComposable();\n };\n };\n\n const createResourceLayoutExtras: {\n forResource: CreateLayoutForResource<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n makeComposable?: ReturnType<typeof createTopLevelMakeComposable>;\n } = {\n forResource,\n };\n\n if (layout.composables) {\n createResourceLayoutExtras.makeComposable = createTopLevelMakeComposable();\n }\n\n const createResourceLayout = Object.assign(\n definedResourceLayout,\n createResourceLayoutExtras,\n ) as CreateResourceLayoutFn<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n\n const createResourceLinks = createResourceLinksFn(resources);\n\n return {\n createResourceConfig,\n createResourceLayout,\n createResourceLinks,\n } as DefinedResourceLayout<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"define-layout.cjs","names":["capitalize","functionalUpdate","normalizeResources","toResourceEnum","createProp","pick","LayoutComposablePresetProvider","createForResource","createForResources","createResourceLinksFn"],"sources":["../../src/create-config/define-layout.tsx"],"sourcesContent":["import type { JSX } from 'react';\nimport {\n type ComposableComponents,\n type ComposableNameContext,\n type ComposableResourceLayout,\n type CreateLayoutComposable,\n collectComposablePresetEntries,\n LayoutComposablePresetProvider,\n MakeComposable,\n makeComposable,\n MakeComposableOptions,\n RequiredPresetLayoutProps,\n resolveComposablePresetProps,\n resolveLayoutComposables,\n} from '@jfdevelops/react-layout-composables';\nimport {\n type AnyBuiltPropDefinition,\n createPrimitivePropBuilder,\n createProp,\n type ResolveLayoutProps,\n type ResolveProps,\n resolvePropDefinitionValues,\n validateProps,\n} from '@jfdevelops/react-layout-validator';\nimport {\n IncludedProps,\n InferredInProps,\n InPropsDefinition,\n InPropsObject,\n LayoutRenderProps,\n MergedLayoutInProps,\n} from '../props';\nimport {\n normalizeResources,\n toResourceEnum,\n type LayoutResourceKey,\n type ResourceDefinition,\n} from '../resource';\nimport { BaseComponent, functionalUpdate, pick, Show, Updater } from '../utils';\nimport { capitalize } from '../utils/capitalize';\nimport {\n type CreateResourceConfigFn,\n createResourceConfig,\n} from './get-component';\nimport {\n createResourceLinksFn,\n type CreateResourceLinksFn,\n} from './create-resource-links';\nimport {\n createForResource,\n type CreateLayoutForResource,\n type CreateResourceLayoutOptions,\n type CreateResourceLayoutOptionsBase,\n} from './for-resource';\nimport {\n createForResources,\n type CreateResourceLayoutForResourcesFn,\n} from './for-resources';\n\nexport type LayoutIncludeProps<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n> = IncludedProps<MergedLayoutInProps<Resources, Options, Composables>>;\n\ntype LayoutProps<\n Resources extends ReadonlyArray<ResourceDefinition>,\n Options extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n IncludeProps extends LayoutIncludeProps<Resources, Options, Composables> = {},\n CustomProps extends InPropsObject = {},\n> = {\n /**\n * Props to include in the layout.\n */\n include?: LayoutIncludeProps<Resources, Options, Composables> & 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(includeKey: string, definition: unknown) {\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 Composables extends ComposableComponents = {},\n IncludeProps extends LayoutIncludeProps<Resources, Options, Composables> = {},\n CustomProps extends InPropsObject = {},\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<\n Resources,\n Options,\n Composables,\n IncludeProps,\n CustomProps\n >;\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<\n Resources,\n Options,\n Composables,\n IncludeProps,\n CustomProps\n >,\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 };\nexport type 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\nexport type LayoutPropsForResource<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents = {},\n> = ResolveLayoutProps<InferredInProps<Resources, InProps>> &\n RequiredPresetLayoutProps<Composables>;\n\ntype CreateResourceLayoutFnImpl<\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 Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Props extends InPropsObject = {},\n>(\n options: CreateResourceLayoutOptions<\n Resources,\n InProps,\n Composables,\n Name,\n Resource,\n Props\n >,\n) => ResourceLayoutComponent<Name, CustomProps, Composables>;\n\nexport type CreateResourceLayoutMakeComposableOptions<\n Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents,\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Props extends InPropsObject = {},\n> = CreateResourceLayoutOptionsBase<Resources, Name, Resource, Props> &\n Partial<LayoutPropsForResource<Resources, InProps, Composables>>;\n\ntype CreateResourceLayoutMakeComposableFn<\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 Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Props extends InPropsObject = {},\n>(\n options: CreateResourceLayoutMakeComposableOptions<\n Resources,\n InProps,\n Composables,\n Name,\n Resource,\n Props\n >,\n) => ComposableResourceLayout<Composables, Name, any, any, any>;\n\ntype CreateResourceLayoutFnBase<\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> = CreateResourceLayoutFnImpl<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n> & {\n /**\n * A function to create a resource layout for a specific resource.\n */\n forResource: CreateLayoutForResource<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n /**\n * Creates resource layout factories for multiple defined resources.\n */\n forResources: CreateResourceLayoutForResourcesFn<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n};\n\ntype CreateResourceLayoutMakeComposableMember<\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> = [keyof Composables] extends [never]\n ? {}\n : {\n makeComposable: CreateResourceLayoutMakeComposableFn<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n };\n\nexport type CreateResourceLayoutFn<\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> = CreateResourceLayoutFnBase<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n> &\n CreateResourceLayoutMakeComposableMember<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n\ntype DefinedResourceLayout<\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 createResourceConfig: CreateResourceConfigFn<Resources>;\n createResourceLayout: CreateResourceLayoutFn<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n createResourceLinks: CreateResourceLinksFn<Resources>;\n};\n\nexport function defineResourceLayout<\n const Resources extends ReadonlyArray<ResourceDefinition>,\n InProps extends InPropsDefinition<Resources>,\n Composables extends ComposableComponents = {},\n const IncludeProps extends LayoutIncludeProps<\n Resources,\n InProps,\n Composables\n > = {},\n CustomProps extends InPropsObject = {},\n>(\n options: CreateViewMapOptions<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\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 = (<\n Name extends string,\n Resource extends LayoutResourceKey<Resources>,\n Props extends InPropsObject = {},\n >(\n layoutOptions: CreateResourceLayoutOptions<\n Resources,\n InProps,\n Composables,\n Name,\n Resource,\n Props\n >,\n ) => {\n const {\n name,\n props: instancePropDefinitions,\n ...layoutOptionProps\n } = layoutOptions;\n const createComposableLayout =\n makeComposable<\n LayoutRenderProps<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >\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 mergedResolvedInProps = { ...resolvedInProps };\n\n for (const {\n props: presetPropDefinitions,\n } of collectComposablePresetEntries(resolvedComposables)) {\n Object.assign(mergedResolvedInProps, presetPropDefinitions);\n }\n\n const composablePresetProps = resolveComposablePresetProps(\n resolvedComposables,\n layoutOptionProps as Record<string, unknown>,\n );\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 mergedResolvedInProps,\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 = mergedResolvedInProps[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, mergedResolvedInProps[key]),\n validatedIncludedProps[\n key as keyof typeof validatedIncludedProps\n ],\n ],\n ];\n }),\n );\n const layoutRenderProps = {\n ...validatedProps,\n ...layoutRenderIncludedProps,\n } as unknown as LayoutRenderProps<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n\n return (\n <LayoutComposablePresetProvider value={composablePresetProps}>\n {render(layoutRenderProps, mergedRenderContext)}\n </LayoutComposablePresetProvider>\n );\n }\n\n function createComposition<\n LayoutName extends string,\n const Defined extends MakeComposableOptions<Composables, LayoutName>,\n >(compositionOptions: Defined) {\n if (!compositionOptions.components) {\n return {} as ResourceLayoutComposition<LayoutName, Composables>;\n }\n\n return {\n makeComposable: createComposableLayout(\n compositionOptions,\n ) as MakeComposable<Composables, LayoutName>,\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 }) as CreateResourceLayoutFnImpl<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n const createTopLevelMakeComposable = () => {\n return (options: Record<string, unknown>) => {\n const layout = definedResourceLayout(options as never);\n\n if (\n !('makeComposable' in layout) ||\n typeof layout.makeComposable !== 'function'\n ) {\n throw new Error(\n 'makeComposable requires composables to be defined in the layout',\n );\n }\n\n return layout.makeComposable();\n };\n };\n\n const { createLayoutForResourceBuilder, forResource } = createForResource<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >({\n createResourceLayout: definedResourceLayout as never,\n resolveLayoutOptionDefaults,\n });\n const forResources = createForResources<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >({\n createLayoutForResource: createLayoutForResourceBuilder,\n ...(layout.composables\n ? { createMakeComposableLayout: createTopLevelMakeComposable }\n : {}),\n createResourceLayout: definedResourceLayout as never,\n });\n\n const createResourceLayoutExtras: {\n forResource: CreateLayoutForResource<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n forResources: CreateResourceLayoutForResourcesFn<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n makeComposable?: ReturnType<typeof createTopLevelMakeComposable>;\n } = {\n forResource,\n forResources,\n };\n\n if (layout.composables) {\n createResourceLayoutExtras.makeComposable = createTopLevelMakeComposable();\n }\n\n const createResourceLayout = Object.assign(\n definedResourceLayout,\n createResourceLayoutExtras,\n ) as CreateResourceLayoutFn<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n\n const createResourceLinks = createResourceLinksFn(resources);\n\n return {\n createResourceConfig,\n createResourceLayout,\n createResourceLinks,\n } as DefinedResourceLayout<\n Resources,\n InProps,\n Composables,\n IncludeProps,\n CustomProps\n >;\n}\n"],"mappings":"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"}