@elastic/isomer-sdk 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.txt +0 -286
- package/THIRD_PARTY_LICENSES.md +1 -885
- package/dist/author/authored_fields.d.ts +37 -12
- package/dist/author/authored_fields.d.ts.map +1 -1
- package/dist/author/authored_fields.js +45 -69
- package/dist/author/authored_fields.js.map +1 -1
- package/dist/author/authoring_input.d.ts.map +1 -1
- package/dist/author/authoring_input.js +12 -6
- package/dist/author/authoring_input.js.map +1 -1
- package/dist/author/authoring_model.d.ts +8 -2
- package/dist/author/authoring_model.d.ts.map +1 -1
- package/dist/author/authoring_model.js +67 -23
- package/dist/author/authoring_model.js.map +1 -1
- package/dist/author/declarations.d.ts.map +1 -1
- package/dist/author/declarations.js +45 -34
- package/dist/author/declarations.js.map +1 -1
- package/dist/author/index.d.ts +2 -1
- package/dist/author/index.d.ts.map +1 -1
- package/dist/author/index.js +2 -1
- package/dist/author/index.js.map +1 -1
- package/dist/author/jsx_shim.d.ts +49 -30
- package/dist/author/jsx_shim.d.ts.map +1 -1
- package/dist/author/jsx_shim.js +131 -40
- package/dist/author/jsx_shim.js.map +1 -1
- package/dist/author/print_jsx.d.ts +19 -0
- package/dist/author/print_jsx.d.ts.map +1 -0
- package/dist/author/print_jsx.js +372 -0
- package/dist/author/print_jsx.js.map +1 -0
- package/dist/author/prompt.d.ts +2 -2
- package/dist/author/prompt.d.ts.map +1 -1
- package/dist/author/prompt.js +7 -2
- package/dist/author/prompt.js.map +1 -1
- package/dist/author/schema_to_typescript.d.ts.map +1 -1
- package/dist/author/schema_to_typescript.js +6 -3
- package/dist/author/schema_to_typescript.js.map +1 -1
- package/dist/cjs/author/authored_fields.js +47 -70
- package/dist/cjs/author/authored_fields.js.map +1 -1
- package/dist/cjs/author/authoring_input.js +12 -6
- package/dist/cjs/author/authoring_input.js.map +1 -1
- package/dist/cjs/author/authoring_model.js +69 -24
- package/dist/cjs/author/authoring_model.js.map +1 -1
- package/dist/cjs/author/declarations.js +44 -33
- package/dist/cjs/author/declarations.js.map +1 -1
- package/dist/cjs/author/index.js +5 -1
- package/dist/cjs/author/index.js.map +1 -1
- package/dist/cjs/author/jsx_shim.js +130 -39
- package/dist/cjs/author/jsx_shim.js.map +1 -1
- package/dist/cjs/author/print_jsx.js +378 -0
- package/dist/cjs/author/print_jsx.js.map +1 -0
- package/dist/cjs/author/prompt.js +7 -2
- package/dist/cjs/author/prompt.js.map +1 -1
- package/dist/cjs/author/schema_to_typescript.js +6 -3
- package/dist/cjs/author/schema_to_typescript.js.map +1 -1
- package/dist/cjs/composition/error.js +2 -0
- package/dist/cjs/composition/error.js.map +1 -1
- package/dist/cjs/composition/structured_value.js.map +1 -1
- package/dist/cjs/define/index.js.map +1 -1
- package/dist/cjs/define/primitive_module.js +10 -4
- package/dist/cjs/define/primitive_module.js.map +1 -1
- package/dist/cjs/define/slack_blocks.js.map +1 -1
- package/dist/cjs/entries/index.js +5 -2
- package/dist/cjs/entries/index.js.map +1 -1
- package/dist/cjs/entries/markdown.js +3 -1
- package/dist/cjs/entries/markdown.js.map +1 -1
- package/dist/cjs/entries/react.js +2 -1
- package/dist/cjs/entries/react.js.map +1 -1
- package/dist/cjs/entries/slack.js +5 -1
- package/dist/cjs/entries/slack.js.map +1 -1
- package/dist/cjs/pack/enhancements.js.map +1 -1
- package/dist/cjs/pack/index.js +2 -1
- package/dist/cjs/pack/index.js.map +1 -1
- package/dist/cjs/pack/primitive_pack.js +14 -4
- package/dist/cjs/pack/primitive_pack.js.map +1 -1
- package/dist/cjs/render/format_number.js +2 -1
- package/dist/cjs/render/format_number.js.map +1 -1
- package/dist/cjs/render/html/envelope.js +12 -6
- package/dist/cjs/render/html/envelope.js.map +1 -1
- package/dist/cjs/render/markdown/blocks.js +82 -0
- package/dist/cjs/render/markdown/blocks.js.map +1 -0
- package/dist/cjs/render/markdown/builder.js +6 -2
- package/dist/cjs/render/markdown/builder.js.map +1 -1
- package/dist/cjs/render/markdown/format.js +46 -24
- package/dist/cjs/render/markdown/format.js.map +1 -1
- package/dist/cjs/render/markdown/host_tags.js +67 -0
- package/dist/cjs/render/markdown/host_tags.js.map +1 -0
- package/dist/cjs/render/markdown/index.js +5 -1
- package/dist/cjs/render/markdown/index.js.map +1 -1
- package/dist/cjs/render/markdown/split.js +325 -0
- package/dist/cjs/render/markdown/split.js.map +1 -0
- package/dist/cjs/render/primitive_dispatch.js +36 -6
- package/dist/cjs/render/primitive_dispatch.js.map +1 -1
- package/dist/cjs/render/react/content.js +3 -1
- package/dist/cjs/render/react/content.js.map +1 -1
- package/dist/cjs/render/react/index.js +3 -1
- package/dist/cjs/render/react/index.js.map +1 -1
- package/dist/cjs/render/react/markdown_content.js +143 -0
- package/dist/cjs/render/react/markdown_content.js.map +1 -0
- package/dist/cjs/render/slack/blocks.js +7 -0
- package/dist/cjs/render/slack/blocks.js.map +1 -1
- package/dist/cjs/render/slack/container.js +62 -0
- package/dist/cjs/render/slack/container.js.map +1 -0
- package/dist/cjs/render/slack/envelope.js +70 -14
- package/dist/cjs/render/slack/envelope.js.map +1 -1
- package/dist/cjs/render/slack/format.js +56 -6
- package/dist/cjs/render/slack/format.js.map +1 -1
- package/dist/cjs/render/slack/index.js +7 -1
- package/dist/cjs/render/slack/index.js.map +1 -1
- package/dist/cjs/render/slack/markdown_content.js +36 -77
- package/dist/cjs/render/slack/markdown_content.js.map +1 -1
- package/dist/cjs/render/slack/unmodeled.js +38 -0
- package/dist/cjs/render/slack/unmodeled.js.map +1 -0
- package/dist/cjs/testing/conformance.js +15 -1
- package/dist/cjs/testing/conformance.js.map +1 -1
- package/dist/cjs/testing/index.js +2 -1
- package/dist/cjs/testing/index.js.map +1 -1
- package/dist/cjs/validate/json_schema.js +10 -3
- package/dist/cjs/validate/json_schema.js.map +1 -1
- package/dist/cjs/validate/url.js +2 -1
- package/dist/cjs/validate/url.js.map +1 -1
- package/dist/composition/error.d.ts +2 -0
- package/dist/composition/error.d.ts.map +1 -1
- package/dist/composition/error.js +2 -0
- package/dist/composition/error.js.map +1 -1
- package/dist/composition/structured_value.d.ts +3 -3
- package/dist/composition/structured_value.d.ts.map +1 -1
- package/dist/composition/structured_value.js.map +1 -1
- package/dist/define/index.d.ts +1 -1
- package/dist/define/index.d.ts.map +1 -1
- package/dist/define/index.js.map +1 -1
- package/dist/define/primitive_module.d.ts +14 -5
- package/dist/define/primitive_module.d.ts.map +1 -1
- package/dist/define/primitive_module.js +10 -4
- package/dist/define/primitive_module.js.map +1 -1
- package/dist/define/slack_blocks.d.ts +31 -1
- package/dist/define/slack_blocks.d.ts.map +1 -1
- package/dist/define/slack_blocks.js.map +1 -1
- package/dist/entries/index.d.ts +2 -2
- package/dist/entries/index.d.ts.map +1 -1
- package/dist/entries/index.js +2 -2
- package/dist/entries/index.js.map +1 -1
- package/dist/entries/markdown.d.ts +1 -1
- package/dist/entries/markdown.d.ts.map +1 -1
- package/dist/entries/markdown.js +1 -1
- package/dist/entries/markdown.js.map +1 -1
- package/dist/entries/react.d.ts +1 -1
- package/dist/entries/react.d.ts.map +1 -1
- package/dist/entries/react.js +1 -1
- package/dist/entries/react.js.map +1 -1
- package/dist/entries/slack.d.ts +1 -1
- package/dist/entries/slack.d.ts.map +1 -1
- package/dist/entries/slack.js +1 -1
- package/dist/entries/slack.js.map +1 -1
- package/dist/pack/enhancements.d.ts +4 -0
- package/dist/pack/enhancements.d.ts.map +1 -1
- package/dist/pack/enhancements.js.map +1 -1
- package/dist/pack/index.d.ts +1 -1
- package/dist/pack/index.d.ts.map +1 -1
- package/dist/pack/index.js +1 -1
- package/dist/pack/index.js.map +1 -1
- package/dist/pack/primitive_pack.d.ts +3 -1
- package/dist/pack/primitive_pack.d.ts.map +1 -1
- package/dist/pack/primitive_pack.js +13 -3
- package/dist/pack/primitive_pack.js.map +1 -1
- package/dist/render/format_number.d.ts.map +1 -1
- package/dist/render/format_number.js +2 -1
- package/dist/render/format_number.js.map +1 -1
- package/dist/render/html/envelope.js +12 -6
- package/dist/render/html/envelope.js.map +1 -1
- package/dist/render/markdown/blocks.d.ts +6 -0
- package/dist/render/markdown/blocks.d.ts.map +1 -0
- package/dist/render/markdown/blocks.js +77 -0
- package/dist/render/markdown/blocks.js.map +1 -0
- package/dist/render/markdown/builder.d.ts +3 -0
- package/dist/render/markdown/builder.d.ts.map +1 -1
- package/dist/render/markdown/builder.js +3 -1
- package/dist/render/markdown/builder.js.map +1 -1
- package/dist/render/markdown/format.d.ts +2 -0
- package/dist/render/markdown/format.d.ts.map +1 -1
- package/dist/render/markdown/format.js +42 -22
- package/dist/render/markdown/format.js.map +1 -1
- package/dist/render/markdown/host_tags.d.ts +14 -0
- package/dist/render/markdown/host_tags.d.ts.map +1 -0
- package/dist/render/markdown/host_tags.js +63 -0
- package/dist/render/markdown/host_tags.js.map +1 -0
- package/dist/render/markdown/index.d.ts +2 -0
- package/dist/render/markdown/index.d.ts.map +1 -1
- package/dist/render/markdown/index.js +2 -0
- package/dist/render/markdown/index.js.map +1 -1
- package/dist/render/markdown/split.d.ts +32 -0
- package/dist/render/markdown/split.d.ts.map +1 -0
- package/dist/render/markdown/split.js +321 -0
- package/dist/render/markdown/split.js.map +1 -0
- package/dist/render/primitive_dispatch.d.ts +4 -2
- package/dist/render/primitive_dispatch.d.ts.map +1 -1
- package/dist/render/primitive_dispatch.js +36 -6
- package/dist/render/primitive_dispatch.js.map +1 -1
- package/dist/render/react/content.d.ts +1 -1
- package/dist/render/react/content.d.ts.map +1 -1
- package/dist/render/react/content.js +3 -1
- package/dist/render/react/content.js.map +1 -1
- package/dist/render/react/index.d.ts +1 -0
- package/dist/render/react/index.d.ts.map +1 -1
- package/dist/render/react/index.js +1 -0
- package/dist/render/react/index.js.map +1 -1
- package/dist/render/react/markdown_content.d.ts +9 -0
- package/dist/render/react/markdown_content.d.ts.map +1 -0
- package/dist/render/react/markdown_content.js +139 -0
- package/dist/render/react/markdown_content.js.map +1 -0
- package/dist/render/slack/blocks.d.ts +8 -1
- package/dist/render/slack/blocks.d.ts.map +1 -1
- package/dist/render/slack/blocks.js +7 -0
- package/dist/render/slack/blocks.js.map +1 -1
- package/dist/render/slack/container.d.ts +25 -0
- package/dist/render/slack/container.d.ts.map +1 -0
- package/dist/render/slack/container.js +55 -0
- package/dist/render/slack/container.js.map +1 -0
- package/dist/render/slack/envelope.d.ts +6 -4
- package/dist/render/slack/envelope.d.ts.map +1 -1
- package/dist/render/slack/envelope.js +71 -15
- package/dist/render/slack/envelope.js.map +1 -1
- package/dist/render/slack/format.d.ts +15 -3
- package/dist/render/slack/format.d.ts.map +1 -1
- package/dist/render/slack/format.js +54 -5
- package/dist/render/slack/format.js.map +1 -1
- package/dist/render/slack/index.d.ts +4 -2
- package/dist/render/slack/index.d.ts.map +1 -1
- package/dist/render/slack/index.js +2 -0
- package/dist/render/slack/index.js.map +1 -1
- package/dist/render/slack/markdown_content.d.ts +3 -2
- package/dist/render/slack/markdown_content.d.ts.map +1 -1
- package/dist/render/slack/markdown_content.js +27 -68
- package/dist/render/slack/markdown_content.js.map +1 -1
- package/dist/render/slack/unmodeled.d.ts +16 -0
- package/dist/render/slack/unmodeled.d.ts.map +1 -0
- package/dist/render/slack/unmodeled.js +32 -0
- package/dist/render/slack/unmodeled.js.map +1 -0
- package/dist/testing/conformance.d.ts +3 -1
- package/dist/testing/conformance.d.ts.map +1 -1
- package/dist/testing/conformance.js +14 -0
- package/dist/testing/conformance.js.map +1 -1
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +1 -1
- package/dist/testing/index.js.map +1 -1
- package/dist/validate/json_schema.d.ts.map +1 -1
- package/dist/validate/json_schema.js +10 -3
- package/dist/validate/json_schema.js.map +1 -1
- package/dist/validate/url.d.ts.map +1 -1
- package/dist/validate/url.js +2 -1
- package/dist/validate/url.js.map +1 -1
- package/package.json +2 -2
|
@@ -2,7 +2,7 @@ import { type ReactElement, type ReactNode } from 'react';
|
|
|
2
2
|
import type { z, ZodObject } from 'zod';
|
|
3
3
|
import type { Composition } from '../composition/composition.js';
|
|
4
4
|
import type { PrimitiveNode } from '../define/primitive_module.js';
|
|
5
|
-
import { type AuthoredChildBrand, type AuthoredTextBrand, type AuthoredToItemBrand, type ItemSchema } from './authored_fields.js';
|
|
5
|
+
import { type AuthoredChildBrand, type AuthoredNodesBrand, type AuthoredTextBrand, type AuthoredToItemBrand, type ItemSchema } from './authored_fields.js';
|
|
6
6
|
import { type AuthorComponent } from './jsx.js';
|
|
7
7
|
/** A {@link Composition} whose `body` is the pack's own authoring node type. */
|
|
8
8
|
export type AuthorComposition<TNode extends PrimitiveNode = PrimitiveNode> = Omit<Composition<TNode>, 'body'> & {
|
|
@@ -31,7 +31,7 @@ type SchemaOf<P> = P extends {
|
|
|
31
31
|
} ? S extends ZodObject ? S : never : never;
|
|
32
32
|
/** A bare `ZodObject` has a string index; a real shape does not. */
|
|
33
33
|
type LooseSchema<TSchema> = string extends keyof ShapeOf<TSchema> ? true : false;
|
|
34
|
-
type Branded<F> = F extends AuthoredChildBrand<string, unknown> | AuthoredTextBrand ? F : F extends {
|
|
34
|
+
type Branded<F> = F extends AuthoredChildBrand<string, unknown> | AuthoredTextBrand | AuthoredNodesBrand ? F : F extends {
|
|
35
35
|
_zod: {
|
|
36
36
|
def: {
|
|
37
37
|
type: 'optional' | 'nullable' | 'default' | 'readonly';
|
|
@@ -40,48 +40,61 @@ type Branded<F> = F extends AuthoredChildBrand<string, unknown> | AuthoredTextBr
|
|
|
40
40
|
};
|
|
41
41
|
} ? Branded<Inner> : F;
|
|
42
42
|
type AuthoredNames<TSchema> = {
|
|
43
|
-
[K in keyof ShapeOf<TSchema>]: Branded<ShapeOf<TSchema>[K]> extends AuthoredChildBrand<string, unknown> | AuthoredTextBrand ? K : never;
|
|
43
|
+
[K in keyof ShapeOf<TSchema>]: Branded<ShapeOf<TSchema>[K]> extends AuthoredChildBrand<string, unknown> | AuthoredTextBrand | AuthoredNodesBrand ? K : never;
|
|
44
44
|
}[keyof ShapeOf<TSchema>];
|
|
45
|
-
type
|
|
45
|
+
type SlotValue<V> = NonNullable<V> extends readonly (infer Item)[] ? Item : NonNullable<V>;
|
|
46
|
+
/**
|
|
47
|
+
* A field holding body nodes, or an array of them: its `type` is wide or one of
|
|
48
|
+
* the pack's `TTypes`, so a discriminated config object does not count.
|
|
49
|
+
*/
|
|
50
|
+
type NodeSlotKey<T, TTypes extends string> = {
|
|
51
|
+
[K in keyof T]-?: K extends 'type' ? never : SlotValue<T[K]> extends {
|
|
52
|
+
type: infer Type extends string;
|
|
53
|
+
} ? string extends Type ? K : [Type] extends [TTypes] ? K : never : never;
|
|
54
|
+
}[keyof T];
|
|
55
|
+
type IsUnion<T, U = T> = [T] extends [never] ? false : T extends unknown ? [U] extends [T] ? false : true : false;
|
|
56
|
+
/** `T` when it is exactly one key. */
|
|
57
|
+
type Only<T> = [T] extends [never] ? never : IsUnion<T> extends true ? never : T;
|
|
58
|
+
/**
|
|
59
|
+
* The one unbranded node field JSX children fill. With several, each stays a
|
|
60
|
+
* prop, as at runtime.
|
|
61
|
+
*/
|
|
62
|
+
type PassthroughSlot<TSchema extends ZodObject, TTypes extends string> = Only<Exclude<NodeSlotKey<z.infer<TSchema>, TTypes>, AuthoredNames<TSchema>>>;
|
|
63
|
+
type FilledNames<TSchema extends ZodObject, TTypes extends string> = AuthoredNames<TSchema> | PassthroughSlot<TSchema, TTypes>;
|
|
64
|
+
type AuthorPropsForSchema<TSchema extends ZodObject, TTypes extends string> = LooseSchema<TSchema> extends true ? Record<string, unknown> & {
|
|
46
65
|
children?: ReactNode;
|
|
47
|
-
} : Omit<z.infer<TSchema>, 'type' |
|
|
66
|
+
} : Omit<z.infer<TSchema>, 'type' | FilledNames<TSchema, TTypes>> & Partial<Pick<z.infer<TSchema>, Extract<FilledNames<TSchema, TTypes>, keyof z.infer<TSchema>>>> & {
|
|
48
67
|
children?: ReactNode;
|
|
49
68
|
};
|
|
50
|
-
type AuthorPropsFor<P> = [SchemaOf<P>] extends [never] ? Record<string, unknown> & {
|
|
69
|
+
type AuthorPropsFor<P, TTypes extends string> = [SchemaOf<P>] extends [never] ? Record<string, unknown> & {
|
|
51
70
|
children?: ReactNode;
|
|
52
|
-
} : AuthorPropsForSchema<SchemaOf<P
|
|
53
|
-
type ChildEntry<F, TDepth extends unknown[]> = 0 extends 1 & F ? NoKeys : F extends AuthoredChildBrand<infer Name, infer Props> ? [Name] extends [string] ? {
|
|
71
|
+
} : AuthorPropsForSchema<SchemaOf<P>, TTypes>;
|
|
72
|
+
type ChildEntry<F, TOwner extends string, TDepth extends unknown[]> = 0 extends 1 & F ? NoKeys : F extends AuthoredChildBrand<infer Name, infer Props> ? [Name] extends [string] ? {
|
|
54
73
|
[K in Capitalize<Name>]: AuthorComponent<Props & {
|
|
55
74
|
children?: ReactNode;
|
|
56
|
-
},
|
|
57
|
-
} & (F extends AuthoredToItemBrand ? NoKeys : ChildComponentsOf<ItemSchema<F>, [...TDepth, unknown]>) : NoKeys : NoKeys;
|
|
75
|
+
}, `${TOwner}.${K}`>;
|
|
76
|
+
} & (F extends AuthoredToItemBrand ? NoKeys : ChildComponentsOf<ItemSchema<F>, TOwner, [...TDepth, unknown]>) : NoKeys : NoKeys;
|
|
58
77
|
type UnionToIntersection<T> = (T extends unknown ? (value: T) => void : never) extends (value: infer R) => void ? R : never;
|
|
59
78
|
/** Child components branded on `TSchema`, then on each child's item schema, five levels deep. */
|
|
60
|
-
type ChildComponentsOf<TSchema, TDepth extends unknown[] = []> = TDepth['length'] extends 5 ? NoKeys : LooseSchema<TSchema> extends true ? NoKeys : UnionToIntersection<{
|
|
61
|
-
[K in keyof ShapeOf<TSchema>]: ChildEntry<Branded<ShapeOf<TSchema>[K]>, TDepth>;
|
|
79
|
+
type ChildComponentsOf<TSchema, TOwner extends string, TDepth extends unknown[] = []> = TDepth['length'] extends 5 ? NoKeys : LooseSchema<TSchema> extends true ? NoKeys : UnionToIntersection<{
|
|
80
|
+
[K in keyof ShapeOf<TSchema>]: ChildEntry<Branded<ShapeOf<TSchema>[K]>, TOwner, TDepth>;
|
|
62
81
|
}[keyof ShapeOf<TSchema>]>;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
...infer Tail
|
|
66
|
-
] ? ChildComponentsOf<SchemaOf<Head>> & ChildMapOfTuple<Tail extends readonly {
|
|
67
|
-
type: string;
|
|
68
|
-
}[] ? Tail : []> : NoKeys;
|
|
69
|
-
type ChildComponentMap<TPrimitives extends readonly {
|
|
70
|
-
type: string;
|
|
71
|
-
}[]> = ChildMapOfTuple<TPrimitives>;
|
|
82
|
+
/** A primitive's child components, as members of its own component. */
|
|
83
|
+
type MembersOf<P, TType extends string> = [SchemaOf<P>] extends [never] ? NoKeys : ChildComponentsOf<SchemaOf<P>, TType>;
|
|
72
84
|
/**
|
|
73
85
|
* PascalCase authoring components keyed from a pack's primitive `type` list.
|
|
74
|
-
* `slideFrame` becomes `SlideFrame`. Props come from the primitive's schema
|
|
86
|
+
* `slideFrame` becomes `SlideFrame`. Props come from the primitive's schema,
|
|
87
|
+
* and each branded child is a member: `SlideFrame.Footer`.
|
|
75
88
|
*/
|
|
76
89
|
export type PrimitiveComponentMap<TPrimitives extends readonly {
|
|
77
90
|
type: string;
|
|
78
91
|
}[]> = {
|
|
79
|
-
[P in TPrimitives[number] as Capitalize<LiteralType<P['type'] & string>>]: AuthorComponent<AuthorPropsFor<P
|
|
92
|
+
[P in TPrimitives[number] as Capitalize<LiteralType<P['type'] & string>>]: AuthorComponent<AuthorPropsFor<P, LiteralType<TPrimitives[number]['type'] & string>>, P['type'] & string> & MembersOf<P, P['type'] & string>;
|
|
80
93
|
};
|
|
81
94
|
/**
|
|
82
95
|
* A pack's JSX authoring front: the root `Composition` element, one
|
|
83
|
-
* PascalCase component per primitive
|
|
84
|
-
* back to plain data.
|
|
96
|
+
* PascalCase component per primitive with its branded children as members,
|
|
97
|
+
* and the conversion back to plain data.
|
|
85
98
|
*/
|
|
86
99
|
export type JsxShim<TNode extends PrimitiveNode = PrimitiveNode, TPrimitives extends readonly {
|
|
87
100
|
type: string;
|
|
@@ -91,14 +104,19 @@ export type JsxShim<TNode extends PrimitiveNode = PrimitiveNode, TPrimitives ext
|
|
|
91
104
|
Composition: AuthorComponent<CompositionAuthorProps<TNode>, 'view'>;
|
|
92
105
|
/** Throws when the root is not the `Composition` element, or when a child is not a registered primitive. */
|
|
93
106
|
toComposition: (element: ReactElement<CompositionAuthorProps<TNode>>) => AuthorComposition<TNode>;
|
|
94
|
-
} & PrimitiveComponentMap<TPrimitives
|
|
107
|
+
} & PrimitiveComponentMap<TPrimitives>;
|
|
95
108
|
/**
|
|
96
109
|
* Builds a pack's {@link JsxShim} from its primitive list.
|
|
97
110
|
*
|
|
98
111
|
* Branded schema fields ({@link fromChildren}, {@link fromTextChildren}) fill
|
|
99
|
-
* from JSX children, and each child
|
|
100
|
-
*
|
|
101
|
-
*
|
|
112
|
+
* from JSX children, and each child becomes a member of its primitive's
|
|
113
|
+
* component. Several branded fields share one children list, and each takes
|
|
114
|
+
* the elements of its member.
|
|
115
|
+
* Elements of a registered primitive that match none of them fill the one
|
|
116
|
+
* unbranded child slot from {@link PrimitiveDefinition.children}, or the one
|
|
117
|
+
* {@link fromNodeChildren} field. A primitive with no brand still fills that slot, array or
|
|
118
|
+
* single node, from its children. That field is optional on the component's
|
|
119
|
+
* props.
|
|
102
120
|
*/
|
|
103
121
|
export declare const buildJsxShim: <const TPrimitives extends readonly {
|
|
104
122
|
type: string;
|
|
@@ -108,10 +126,11 @@ export declare const buildJsxShim: <const TPrimitives extends readonly {
|
|
|
108
126
|
/** React children as a flat array, with fragments inlined. */
|
|
109
127
|
export declare const flattenChildren: (children: ReactNode) => ReactNode[];
|
|
110
128
|
/**
|
|
111
|
-
* Children joined into one string. Throws on an element child, so a prop typed as text stays text. Collapses whitespace unless `{ collapseWhitespace: false }`.
|
|
129
|
+
* Children joined into one string. Throws on an element child, so a prop typed as text stays text. Collapses whitespace unless `{ collapseWhitespace: false }`; `{ dedent: true }` reads it as source, lines joined by `\n`.
|
|
112
130
|
*/
|
|
113
131
|
export declare const textFromChildren: (children: ReactNode, options?: {
|
|
114
132
|
collapseWhitespace?: boolean;
|
|
133
|
+
dedent?: boolean;
|
|
115
134
|
}) => string;
|
|
116
135
|
export {};
|
|
117
136
|
//# sourceMappingURL=jsx_shim.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsx_shim.d.ts","sourceRoot":"","sources":["../../src/author/jsx_shim.ts"],"names":[],"mappings":"AAOA,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,CAAC,EAAE,SAAS,EAAW,MAAM,KAAK,CAAC;AAEjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE,OAAO,EACL,KAAK,kBAAkB,
|
|
1
|
+
{"version":3,"file":"jsx_shim.d.ts","sourceRoot":"","sources":["../../src/author/jsx_shim.ts"],"names":[],"mappings":"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"}
|
package/dist/author/jsx_shim.js
CHANGED
|
@@ -7,20 +7,24 @@
|
|
|
7
7
|
import { Children, Fragment, isValidElement, } from 'react';
|
|
8
8
|
import { IsomerError } from '../composition/error.js';
|
|
9
9
|
import { readAuthoredSpec, } from './authored_fields.js';
|
|
10
|
-
import { capitalize, createAuthoringModel, } from './authoring_model.js';
|
|
10
|
+
import { capitalize, createAuthoringModel, memberType, } from './authoring_model.js';
|
|
11
11
|
import { authorType, defineAuthorComponent } from './jsx.js';
|
|
12
12
|
/**
|
|
13
13
|
* Builds a pack's {@link JsxShim} from its primitive list.
|
|
14
14
|
*
|
|
15
15
|
* Branded schema fields ({@link fromChildren}, {@link fromTextChildren}) fill
|
|
16
|
-
* from JSX children, and each child
|
|
17
|
-
*
|
|
18
|
-
*
|
|
16
|
+
* from JSX children, and each child becomes a member of its primitive's
|
|
17
|
+
* component. Several branded fields share one children list, and each takes
|
|
18
|
+
* the elements of its member.
|
|
19
|
+
* Elements of a registered primitive that match none of them fill the one
|
|
20
|
+
* unbranded child slot from {@link PrimitiveDefinition.children}, or the one
|
|
21
|
+
* {@link fromNodeChildren} field. A primitive with no brand still fills that slot, array or
|
|
22
|
+
* single node, from its children. That field is optional on the component's
|
|
23
|
+
* props.
|
|
19
24
|
*/
|
|
20
25
|
export const buildJsxShim = (primitives = []) => {
|
|
21
26
|
const primitiveTypes = new Set(primitives.map((primitive) => primitive.type));
|
|
22
|
-
const { authoredByType,
|
|
23
|
-
const childComponents = new Map([...children.keys()].map((type) => [type, defineAuthorComponent(type)]));
|
|
27
|
+
const { authoredByType, membersByType, childSlotsByType } = createAuthoringModel(primitives);
|
|
24
28
|
const view = defineAuthorComponent('view');
|
|
25
29
|
const env = {
|
|
26
30
|
authoredByType,
|
|
@@ -30,13 +34,12 @@ export const buildJsxShim = (primitives = []) => {
|
|
|
30
34
|
return {
|
|
31
35
|
Composition: view,
|
|
32
36
|
toComposition: (element) => toAuthorComposition(element, env),
|
|
33
|
-
...Object.fromEntries(primitives.map((
|
|
34
|
-
capitalize(primitive.type),
|
|
35
|
-
defineAuthorComponent(primitive.type),
|
|
36
|
-
])),
|
|
37
|
-
...Object.fromEntries([...childComponents].map(([type, component]) => [
|
|
37
|
+
...Object.fromEntries(primitives.map(({ type }) => [
|
|
38
38
|
capitalize(type),
|
|
39
|
-
|
|
39
|
+
Object.assign(defineAuthorComponent(type), Object.fromEntries((membersByType.get(type) ?? []).map(({ member, authorType }) => [
|
|
40
|
+
member,
|
|
41
|
+
defineAuthorComponent(authorType),
|
|
42
|
+
]))),
|
|
40
43
|
])),
|
|
41
44
|
};
|
|
42
45
|
};
|
|
@@ -79,12 +82,12 @@ const bodyNodeFromElement = (node, env) => {
|
|
|
79
82
|
for (const [key, value] of Object.entries(withoutChildren(element))) {
|
|
80
83
|
const childField = authored?.children.find((field) => field.field === key);
|
|
81
84
|
converted[key] = childField
|
|
82
|
-
? valueFromChildField(value, childField, env)
|
|
85
|
+
? valueFromChildField(value, childField, env, type)
|
|
83
86
|
: convertPropValue(value, key, slots, parseChild);
|
|
84
87
|
}
|
|
85
88
|
const rawChildren = element.props.children;
|
|
86
89
|
if (authored && (authored.children.length > 0 || authored.text.length > 0)) {
|
|
87
|
-
fillAuthoredFields(converted, authored, rawChildren, env);
|
|
90
|
+
fillAuthoredFields(converted, authored, rawChildren, env, slots, parseChild, type);
|
|
88
91
|
}
|
|
89
92
|
else {
|
|
90
93
|
const unique = slots.length === 1 ? slots[0] : undefined;
|
|
@@ -92,7 +95,7 @@ const bodyNodeFromElement = (node, env) => {
|
|
|
92
95
|
converted[unique.field] === undefined &&
|
|
93
96
|
rawChildren !== undefined) {
|
|
94
97
|
const nested = flattenChildren(rawChildren).map(parseChild);
|
|
95
|
-
converted[unique.field] =
|
|
98
|
+
converted[unique.field] = slotValue(nested, unique);
|
|
96
99
|
}
|
|
97
100
|
else if (slots.length === 0 && flattenChildren(rawChildren).length > 0) {
|
|
98
101
|
throw new IsomerError('UNEXPECTED_CHILDREN', `<${capitalize(type)}> takes no JSX children; set its fields through props.`);
|
|
@@ -100,31 +103,79 @@ const bodyNodeFromElement = (node, env) => {
|
|
|
100
103
|
}
|
|
101
104
|
return omitUndefined({ ...converted, type });
|
|
102
105
|
};
|
|
103
|
-
const fillAuthoredFields = (converted, authored, rawChildren, env) => {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
106
|
+
const fillAuthoredFields = (converted, authored, rawChildren, env, slots, parseChild, parentType) => {
|
|
107
|
+
const unsetChildren = authored.children.filter((field) => converted[field.field] === undefined);
|
|
108
|
+
const unsetText = authored.text.filter((field) => converted[field.field] === undefined);
|
|
109
|
+
const brandedFields = new Set(authored.children.map((field) => field.field));
|
|
110
|
+
const unbranded = slots.filter(({ field }) => !brandedFields.has(field));
|
|
111
|
+
const slot = unbranded.length === 1 ? unbranded[0] : undefined;
|
|
112
|
+
const slotOpen = slot !== undefined && converted[slot.field] === undefined;
|
|
113
|
+
if (rawChildren === undefined ||
|
|
114
|
+
(unsetChildren.length === 0 && unsetText.length === 0 && !slotOpen)) {
|
|
115
|
+
for (const field of unsetText) {
|
|
116
|
+
if (!field.optional) {
|
|
117
|
+
throw new IsomerError('MISSING_AUTHORED_TEXT', `Expected text children for "${field.field}".`);
|
|
118
|
+
}
|
|
107
119
|
}
|
|
108
|
-
|
|
120
|
+
return;
|
|
109
121
|
}
|
|
110
|
-
|
|
111
|
-
|
|
122
|
+
const flat = flattenChildren(rawChildren);
|
|
123
|
+
const elements = flat.filter(isAuthorElement);
|
|
124
|
+
const textNodes = flat.filter((child) => !isAuthorElement(child));
|
|
125
|
+
const claimed = new Set();
|
|
126
|
+
for (const field of unsetChildren) {
|
|
127
|
+
const matching = elements.filter((child) => getAuthorType(child) === memberType(parentType, field));
|
|
128
|
+
if (matching.length === 0) {
|
|
129
|
+
if (flat.length === 0 && field.array && !field.optional) {
|
|
130
|
+
converted[field.field] = [];
|
|
131
|
+
}
|
|
112
132
|
continue;
|
|
113
133
|
}
|
|
114
|
-
|
|
134
|
+
for (const child of matching) {
|
|
135
|
+
claimed.add(child);
|
|
136
|
+
}
|
|
137
|
+
converted[field.field] = valueFromBrand(matching, field, env, parentType);
|
|
138
|
+
}
|
|
139
|
+
const brandedTypes = new Set(authored.children.map((field) => memberType(parentType, field)));
|
|
140
|
+
const stray = elements.filter((child) => brandedTypes.has(getAuthorType(child)) && !claimed.has(child));
|
|
141
|
+
if (stray.length > 0) {
|
|
142
|
+
const childType = getAuthorType(stray[0]);
|
|
143
|
+
throw new IsomerError('UNEXPECTED_CHILDREN', `<${capitalize(parentType)}> already has its <${capitalize(childType)}>.`);
|
|
144
|
+
}
|
|
145
|
+
const leftover = elements.filter((child) => !claimed.has(child));
|
|
146
|
+
if (slotOpen && slot && leftover.length > 0) {
|
|
147
|
+
const nested = leftover.map(parseChild);
|
|
148
|
+
converted[slot.field] = slotValue(nested, slot);
|
|
149
|
+
}
|
|
150
|
+
else if (leftover.length > 0) {
|
|
151
|
+
const childType = getAuthorType(leftover[0]);
|
|
152
|
+
const [empty, ...moreEmpty] = unsetChildren.filter(({ field }) => converted[field] === undefined);
|
|
153
|
+
if (empty && moreEmpty.length === 0 && !slotOpen) {
|
|
154
|
+
throw new IsomerError('AUTHOR_TYPE_MISMATCH', `Expected <${capitalize(memberType(parentType, empty))}> but received <${capitalize(childType)}>.`);
|
|
155
|
+
}
|
|
156
|
+
throw new IsomerError('UNEXPECTED_CHILDREN', `<${capitalize(childType)}> is not a child of <${capitalize(parentType)}>.`);
|
|
157
|
+
}
|
|
158
|
+
if (textNodes.length === 0) {
|
|
159
|
+
for (const field of unsetText) {
|
|
115
160
|
if (!field.optional) {
|
|
116
161
|
throw new IsomerError('MISSING_AUTHORED_TEXT', `Expected text children for "${field.field}".`);
|
|
117
162
|
}
|
|
118
|
-
continue;
|
|
119
163
|
}
|
|
120
|
-
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (unsetText.length === 0) {
|
|
167
|
+
throw new IsomerError('EXPECTED_JSX_ELEMENT', 'Expected an Isomer JSX element.');
|
|
168
|
+
}
|
|
169
|
+
for (const field of unsetText) {
|
|
170
|
+
converted[field.field] = textFromChildren(textNodes, {
|
|
121
171
|
collapseWhitespace: field.collapseWhitespace,
|
|
172
|
+
...(field.dedent ? { dedent: true } : {}),
|
|
122
173
|
});
|
|
123
174
|
}
|
|
124
175
|
};
|
|
125
|
-
const valueFromChildField = (value, field, env) => {
|
|
176
|
+
const valueFromChildField = (value, field, env, owner) => {
|
|
126
177
|
if (isJsxNodes(value)) {
|
|
127
|
-
return valueFromBrand(flattenChildren(value), field, env);
|
|
178
|
+
return valueFromBrand(flattenChildren(value), field, env, owner);
|
|
128
179
|
}
|
|
129
180
|
return value;
|
|
130
181
|
};
|
|
@@ -139,18 +190,18 @@ const isJsxNodes = (value) => {
|
|
|
139
190
|
value.some((item) => isAuthorElement(item) || isValidElement(item)));
|
|
140
191
|
};
|
|
141
192
|
/** The field's array of items, or its one item; throws on a second element for a single-item field. */
|
|
142
|
-
const valueFromBrand = (elements, field, env) => {
|
|
143
|
-
const items = elements.map((child) => itemFromElement(child, field, env));
|
|
193
|
+
const valueFromBrand = (elements, field, env, owner) => {
|
|
194
|
+
const items = elements.map((child) => itemFromElement(child, field, env, owner));
|
|
144
195
|
if (field.array) {
|
|
145
196
|
return items;
|
|
146
197
|
}
|
|
147
198
|
if (items.length > 1) {
|
|
148
|
-
throw new IsomerError('UNEXPECTED_CHILDREN', `"${field.field}" takes one <${capitalize(field
|
|
199
|
+
throw new IsomerError('UNEXPECTED_CHILDREN', `"${field.field}" takes one <${capitalize(memberType(owner, field))}>, not ${items.length}.`);
|
|
149
200
|
}
|
|
150
201
|
return items[0];
|
|
151
202
|
};
|
|
152
|
-
const itemFromElement = (child, field, env) => {
|
|
153
|
-
const element = requireAuthorElement(child, field
|
|
203
|
+
const itemFromElement = (child, field, env, owner) => {
|
|
204
|
+
const element = requireAuthorElement(child, memberType(owner, field));
|
|
154
205
|
if (field.toItem) {
|
|
155
206
|
return field.toItem(element.props, {
|
|
156
207
|
parseChildren: (nested) => flattenChildren(nested).map((node) => bodyNodeFromElement(node, env)),
|
|
@@ -165,28 +216,49 @@ const itemFromElement = (child, field, env) => {
|
|
|
165
216
|
text.length > 0) {
|
|
166
217
|
props[field.textField] = textFromChildren(text);
|
|
167
218
|
}
|
|
168
|
-
fillNestedBrands(field.itemSchema, props, elements, env);
|
|
219
|
+
fillNestedBrands(field.itemSchema, props, elements, env, owner, capitalize(memberType(owner, field)));
|
|
169
220
|
return props;
|
|
170
221
|
};
|
|
171
|
-
const fillNestedBrands = (itemSchema, props, elements, env) => {
|
|
222
|
+
const fillNestedBrands = (itemSchema, props, elements, env, owner, parent) => {
|
|
172
223
|
if (elements.length === 0) {
|
|
173
224
|
return;
|
|
174
225
|
}
|
|
175
|
-
|
|
226
|
+
const fields = readAuthoredSpec(itemSchema).children;
|
|
227
|
+
const claimed = new Set();
|
|
228
|
+
for (const field of fields) {
|
|
176
229
|
if (props[field.field] !== undefined) {
|
|
177
230
|
continue;
|
|
178
231
|
}
|
|
179
|
-
const matching = elements.filter((child) => getAuthorType(child) === field
|
|
232
|
+
const matching = elements.filter((child) => getAuthorType(child) === memberType(owner, field));
|
|
180
233
|
if (matching.length > 0) {
|
|
181
|
-
|
|
234
|
+
matching.forEach((child) => claimed.add(child));
|
|
235
|
+
props[field.field] = valueFromBrand(matching, field, env, owner);
|
|
182
236
|
}
|
|
183
237
|
}
|
|
238
|
+
const [stray] = elements.filter((child) => !claimed.has(child));
|
|
239
|
+
if (stray) {
|
|
240
|
+
const strayType = getAuthorType(stray);
|
|
241
|
+
const held = fields.some((field) => memberType(owner, field) === strayType);
|
|
242
|
+
throw new IsomerError('UNEXPECTED_CHILDREN', held
|
|
243
|
+
? `<${parent}> already has its <${capitalize(strayType)}>.`
|
|
244
|
+
: `<${capitalize(strayType)}> is not a child of <${parent}>.`);
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
/** The slot's nodes, or its one node; throws on a second node for a single-node slot. */
|
|
248
|
+
const slotValue = (nodes, { array, field }) => {
|
|
249
|
+
if (array) {
|
|
250
|
+
return nodes;
|
|
251
|
+
}
|
|
252
|
+
if (nodes.length > 1) {
|
|
253
|
+
throw new IsomerError('UNEXPECTED_CHILDREN', `"${field}" takes one node, not ${nodes.length}.`);
|
|
254
|
+
}
|
|
255
|
+
return nodes[0];
|
|
184
256
|
};
|
|
185
257
|
const convertPropValue = (value, field, slots, parseChild) => {
|
|
186
|
-
const
|
|
258
|
+
const array = slots.some((slot) => slot.field === field && slot.array);
|
|
187
259
|
const fromJsx = nodesFromJsx(value, parseChild);
|
|
188
260
|
if (fromJsx) {
|
|
189
|
-
return
|
|
261
|
+
return slotValue(fromJsx, { array, field });
|
|
190
262
|
}
|
|
191
263
|
if (Array.isArray(value)) {
|
|
192
264
|
return value.flatMap((item) => {
|
|
@@ -220,8 +292,24 @@ export const flattenChildren = (children) => Children.toArray(children).flatMap(
|
|
|
220
292
|
}
|
|
221
293
|
return child;
|
|
222
294
|
});
|
|
295
|
+
const lineBreak = /\r\n|[\n\r\u2028\u2029]/;
|
|
296
|
+
// A template literal's source: the break after the opening backtick, the
|
|
297
|
+
// indentation before the closing one, and the indentation every line shares go.
|
|
298
|
+
const dedentSource = (text) => {
|
|
299
|
+
const all = text.split(lineBreak);
|
|
300
|
+
const start = all.length > 1 && all[0] === '' ? 1 : 0;
|
|
301
|
+
const end = all.length - start > 1 && /^ *$/.test(all[all.length - 1])
|
|
302
|
+
? all.length - 1
|
|
303
|
+
: all.length;
|
|
304
|
+
const lines = all.slice(start, end);
|
|
305
|
+
const indents = lines
|
|
306
|
+
.filter((line) => line.trim() !== '')
|
|
307
|
+
.map((line) => line.length - line.trimStart().length);
|
|
308
|
+
const shared = indents.length > 0 ? Math.min(...indents) : 0;
|
|
309
|
+
return lines.map((line) => line.slice(shared)).join('\n');
|
|
310
|
+
};
|
|
223
311
|
/**
|
|
224
|
-
* Children joined into one string. Throws on an element child, so a prop typed as text stays text. Collapses whitespace unless `{ collapseWhitespace: false }`.
|
|
312
|
+
* Children joined into one string. Throws on an element child, so a prop typed as text stays text. Collapses whitespace unless `{ collapseWhitespace: false }`; `{ dedent: true }` reads it as source, lines joined by `\n`.
|
|
225
313
|
*/
|
|
226
314
|
export const textFromChildren = (children, options) => {
|
|
227
315
|
const text = flattenChildren(children)
|
|
@@ -232,6 +320,9 @@ export const textFromChildren = (children, options) => {
|
|
|
232
320
|
throw new IsomerError('EXPECTED_TEXT_CHILDREN', 'Expected text children.');
|
|
233
321
|
})
|
|
234
322
|
.join('');
|
|
323
|
+
if (options?.dedent) {
|
|
324
|
+
return dedentSource(text);
|
|
325
|
+
}
|
|
235
326
|
if (options?.collapseWhitespace === false) {
|
|
236
327
|
return text.trim();
|
|
237
328
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsx_shim.js","sourceRoot":"","sources":["../../src/author/jsx_shim.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nimport {\n Children,\n Fragment,\n isValidElement,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport type { z, ZodObject, ZodType } from 'zod';\n\nimport type { Composition } from '../composition/composition';\nimport { IsomerError } from '../composition/error';\nimport type { PrimitiveNode } from '../define/primitive_module';\n\nimport {\n type AuthoredChildBrand,\n type AuthoredChildField,\n type AuthoredSpec,\n type AuthoredTextBrand,\n type AuthoredToItemBrand,\n type ItemSchema,\n readAuthoredSpec,\n} from './authored_fields';\nimport {\n capitalize,\n type ChildSlot,\n createAuthoringModel,\n} from './authoring_model';\nimport { type AuthorComponent, authorType, defineAuthorComponent } from './jsx';\n\n/** A {@link Composition} whose `body` is the pack's own authoring node type. */\nexport type AuthorComposition<TNode extends PrimitiveNode = PrimitiveNode> =\n Omit<Composition<TNode>, 'body'> & {\n body: TNode[];\n };\n\n/**\n * Props of the shim's root element: the composition fields minus `type`, with\n * `body` given either as an array or as JSX children.\n */\nexport interface CompositionAuthorProps<\n TNode extends PrimitiveNode = PrimitiveNode,\n> extends Omit<AuthorComposition<TNode>, 'type' | 'body'> {\n /** Wins outright when present: `children` are then ignored, not merged. */\n body?: TNode[];\n /** Parsed into `body` only when `body` is absent. Each child must be an authoring element of a registered primitive type. */\n children?: ReactNode;\n}\n\n/** Literal `type` strings; wide `string` is dropped so a string index cannot collide with `component`. */\ntype LiteralType<T extends string> = string extends T ? never : T;\n\n/** No keys. Intersects away, unlike `Record<string, never>`. */\ntype NoKeys = Record<never, never>;\n\ntype ShapeOf<T> = T extends { shape: infer Shape } ? Shape : NoKeys;\n\n/** A primitive's schema type, or `never` when it declares none. */\ntype SchemaOf<P> = P extends { schema: infer S }\n ? S extends ZodObject\n ? S\n : never\n : never;\n\n/** A bare `ZodObject` has a string index; a real shape does not. */\ntype LooseSchema<TSchema> = string extends keyof ShapeOf<TSchema>\n ? true\n : false;\n\n// The schema a brand is read from: `F`, or one an optional, nullable, default,\n// or readonly wrapper holds.\ntype Branded<F> = F extends\n AuthoredChildBrand<string, unknown> | AuthoredTextBrand\n ? F\n : F extends {\n _zod: {\n def: {\n type: 'optional' | 'nullable' | 'default' | 'readonly';\n innerType: infer Inner;\n };\n };\n }\n ? Branded<Inner>\n : F;\n\ntype AuthoredNames<TSchema> = {\n [K in keyof ShapeOf<TSchema>]: Branded<ShapeOf<TSchema>[K]> extends\n AuthoredChildBrand<string, unknown> | AuthoredTextBrand\n ? K\n : never;\n}[keyof ShapeOf<TSchema>];\n\ntype AuthorPropsForSchema<TSchema extends ZodObject> =\n LooseSchema<TSchema> extends true\n ? Record<string, unknown> & { children?: ReactNode }\n : Omit<z.infer<TSchema>, 'type' | AuthoredNames<TSchema>> &\n Partial<\n Pick<\n z.infer<TSchema>,\n Extract<AuthoredNames<TSchema>, keyof z.infer<TSchema>>\n >\n > & { children?: ReactNode };\n\ntype AuthorPropsFor<P> = [SchemaOf<P>] extends [never]\n ? Record<string, unknown> & { children?: ReactNode }\n : AuthorPropsForSchema<SchemaOf<P>>;\n\ntype ChildEntry<F, TDepth extends unknown[]> = 0 extends 1 & F\n ? NoKeys\n : F extends AuthoredChildBrand<infer Name, infer Props>\n ? [Name] extends [string]\n ? {\n [K in Capitalize<Name>]: AuthorComponent<\n Props & { children?: ReactNode },\n Name\n >;\n } & (F extends AuthoredToItemBrand\n ? NoKeys\n : ChildComponentsOf<ItemSchema<F>, [...TDepth, unknown]>)\n : NoKeys\n : NoKeys;\n\ntype UnionToIntersection<T> = (\n T extends unknown ? (value: T) => void : never\n) extends (value: infer R) => void\n ? R\n : never;\n\n/** Child components branded on `TSchema`, then on each child's item schema, five levels deep. */\ntype ChildComponentsOf<\n TSchema,\n TDepth extends unknown[] = [],\n> = TDepth['length'] extends 5\n ? NoKeys\n : LooseSchema<TSchema> extends true\n ? NoKeys\n : UnionToIntersection<\n {\n [K in keyof ShapeOf<TSchema>]: ChildEntry<\n Branded<ShapeOf<TSchema>[K]>,\n TDepth\n >;\n }[keyof ShapeOf<TSchema>]\n >;\n\ntype ChildMapOfTuple<TPrimitives> = TPrimitives extends readonly [\n infer Head,\n ...infer Tail,\n]\n ? ChildComponentsOf<SchemaOf<Head>> &\n ChildMapOfTuple<Tail extends readonly { type: string }[] ? Tail : []>\n : NoKeys;\n\ntype ChildComponentMap<TPrimitives extends readonly { type: string }[]> =\n ChildMapOfTuple<TPrimitives>;\n\n/**\n * PascalCase authoring components keyed from a pack's primitive `type` list.\n * `slideFrame` becomes `SlideFrame`. Props come from the primitive's schema.\n */\nexport type PrimitiveComponentMap<\n TPrimitives extends readonly { type: string }[],\n> = {\n [\n P in TPrimitives[number] as Capitalize<LiteralType<P['type'] & string>>\n ]: AuthorComponent<AuthorPropsFor<P>, P['type'] & string>;\n};\n\n/**\n * A pack's JSX authoring front: the root `Composition` element, one\n * PascalCase component per primitive and per branded child, and the conversion\n * back to plain data.\n */\nexport type JsxShim<\n TNode extends PrimitiveNode = PrimitiveNode,\n TPrimitives extends readonly { type: string }[] = readonly { type: string }[],\n> = {\n Composition: AuthorComponent<CompositionAuthorProps<TNode>, 'view'>;\n /** Throws when the root is not the `Composition` element, or when a child is not a registered primitive. */\n toComposition: (\n element: ReactElement<CompositionAuthorProps<TNode>>\n ) => AuthorComposition<TNode>;\n} & PrimitiveComponentMap<TPrimitives> &\n ChildComponentMap<TPrimitives>;\n\n/**\n * Builds a pack's {@link JsxShim} from its primitive list.\n *\n * Branded schema fields ({@link fromChildren}, {@link fromTextChildren}) fill\n * from JSX children, and each child type becomes a component. A primitive with\n * no brand still fills its one child slot, array or single node, from\n * {@link PrimitiveDefinition.children}.\n */\nexport const buildJsxShim = <\n const TPrimitives extends readonly { type: string }[] = readonly {\n type: string;\n }[],\n TNode extends PrimitiveNode = PrimitiveNode,\n>(\n primitives: TPrimitives = [] as unknown as TPrimitives\n): JsxShim<TNode, TPrimitives> => {\n const primitiveTypes = new Set(primitives.map((primitive) => primitive.type));\n const { authoredByType, children, childSlotsByType } =\n createAuthoringModel(primitives);\n const childComponents = new Map(\n [...children.keys()].map((type) => [type, defineAuthorComponent(type)])\n );\n const view = defineAuthorComponent<CompositionAuthorProps<TNode>, 'view'>(\n 'view'\n );\n const env: ParseEnv = {\n authoredByType,\n childSlotsByType,\n primitiveTypes,\n };\n\n return {\n Composition: view,\n toComposition: (element) => toAuthorComposition<TNode>(element, env),\n ...Object.fromEntries(\n primitives.map((primitive) => [\n capitalize(primitive.type),\n defineAuthorComponent(primitive.type),\n ])\n ),\n ...Object.fromEntries(\n [...childComponents].map(([type, component]) => [\n capitalize(type),\n component,\n ])\n ),\n } as JsxShim<TNode, TPrimitives>;\n};\n\ninterface ParseEnv {\n authoredByType: ReadonlyMap<string, AuthoredSpec>;\n childSlotsByType: ReadonlyMap<string, readonly ChildSlot[]>;\n primitiveTypes: ReadonlySet<string>;\n}\n\nconst toAuthorComposition = <TNode extends PrimitiveNode>(\n element: ReactElement<CompositionAuthorProps<TNode>>,\n env: ParseEnv\n): AuthorComposition<TNode> => {\n requireAuthorElement<CompositionAuthorProps<TNode>>(element, 'view');\n const props = element.props;\n const resolvedBody =\n props.body ??\n flattenChildren(props.children).map((child) =>\n bodyNodeFromElement<TNode>(child, env)\n );\n const spec: AuthorComposition<TNode> = {\n type: 'view',\n body: resolvedBody,\n };\n\n if (props.version !== undefined) {\n spec.version = props.version;\n }\n if (props.title !== undefined) {\n spec.title = props.title;\n }\n if (props.subtitle !== undefined) {\n spec.subtitle = props.subtitle;\n }\n if (props.theme !== undefined) {\n spec.theme = props.theme;\n }\n if (props.meta !== undefined) {\n spec.meta = props.meta;\n }\n\n return spec;\n};\n\nconst bodyNodeFromElement = <TNode extends PrimitiveNode>(\n node: ReactNode,\n env: ParseEnv\n): TNode => {\n const element = requireAuthorElement<{ children?: ReactNode }>(node);\n const type = getAuthorType(element);\n if (!env.primitiveTypes.has(type)) {\n throw new IsomerError(\n 'INVALID_BODY_NODE',\n `\"${type}\" cannot be used as a composition body node.`\n );\n }\n\n const parseChild = (child: ReactNode): TNode =>\n bodyNodeFromElement<TNode>(child, env);\n const slots = env.childSlotsByType.get(type) ?? [];\n const authored = env.authoredByType.get(type);\n const converted: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(\n withoutChildren<Record<string, unknown>>(element)\n )) {\n const childField = authored?.children.find((field) => field.field === key);\n converted[key] = childField\n ? valueFromChildField(value, childField, env)\n : convertPropValue(value, key, slots, parseChild);\n }\n\n const rawChildren = element.props.children;\n if (authored && (authored.children.length > 0 || authored.text.length > 0)) {\n fillAuthoredFields(converted, authored, rawChildren, env);\n } else {\n const unique = slots.length === 1 ? slots[0] : undefined;\n if (\n unique &&\n converted[unique.field] === undefined &&\n rawChildren !== undefined\n ) {\n const nested = flattenChildren(rawChildren).map(parseChild);\n converted[unique.field] = unique.array ? nested : nested[0];\n } else if (slots.length === 0 && flattenChildren(rawChildren).length > 0) {\n throw new IsomerError(\n 'UNEXPECTED_CHILDREN',\n `<${capitalize(type)}> takes no JSX children; set its fields through props.`\n );\n }\n }\n\n return omitUndefined({ ...converted, type }) as TNode;\n};\n\nconst fillAuthoredFields = (\n converted: Record<string, unknown>,\n authored: AuthoredSpec,\n rawChildren: ReactNode,\n env: ParseEnv\n): void => {\n for (const field of authored.children) {\n if (converted[field.field] !== undefined || rawChildren === undefined) {\n continue;\n }\n converted[field.field] = valueFromBrand(\n flattenChildren(rawChildren),\n field,\n env\n );\n }\n for (const field of authored.text) {\n if (converted[field.field] !== undefined) {\n continue;\n }\n if (rawChildren === undefined) {\n if (!field.optional) {\n throw new IsomerError(\n 'MISSING_AUTHORED_TEXT',\n `Expected text children for \"${field.field}\".`\n );\n }\n continue;\n }\n converted[field.field] = textFromChildren(rawChildren, {\n collapseWhitespace: field.collapseWhitespace,\n });\n }\n};\n\nconst valueFromChildField = (\n value: unknown,\n field: AuthoredChildField,\n env: ParseEnv\n): unknown => {\n if (isJsxNodes(value)) {\n return valueFromBrand(flattenChildren(value), field, env);\n }\n return value;\n};\n\nconst isJsxNodes = (value: unknown): value is ReactNode => {\n if (isAuthorElement(value)) {\n return true;\n }\n if (isValidElement(value) && value.type === Fragment) {\n return true;\n }\n return (\n Array.isArray(value) &&\n value.some((item: unknown) => isAuthorElement(item) || isValidElement(item))\n );\n};\n\n/** The field's array of items, or its one item; throws on a second element for a single-item field. */\nconst valueFromBrand = (\n elements: readonly ReactNode[],\n field: AuthoredChildField,\n env: ParseEnv\n): unknown => {\n const items = elements.map((child) => itemFromElement(child, field, env));\n if (field.array) {\n return items;\n }\n if (items.length > 1) {\n throw new IsomerError(\n 'UNEXPECTED_CHILDREN',\n `\"${field.field}\" takes one <${capitalize(field.childType)}>, not ${items.length}.`\n );\n }\n return items[0];\n};\n\nconst itemFromElement = (\n child: ReactNode,\n field: AuthoredChildField,\n env: ParseEnv\n): unknown => {\n const element = requireAuthorElement<Record<string, unknown>>(\n child,\n field.childType\n );\n if (field.toItem) {\n return field.toItem(element.props, {\n parseChildren: (nested) =>\n flattenChildren(nested).map((node) => bodyNodeFromElement(node, env)),\n });\n }\n const props = withoutChildren<Record<string, unknown>>(element);\n const nested = flattenChildren(element.props.children);\n const elements = nested.filter(isAuthorElement);\n const text = nested.filter((child) => !isAuthorElement(child));\n if (\n field.textField !== undefined &&\n props[field.textField] === undefined &&\n text.length > 0\n ) {\n props[field.textField] = textFromChildren(text);\n }\n fillNestedBrands(field.itemSchema, props, elements, env);\n return props;\n};\n\nconst fillNestedBrands = (\n itemSchema: ZodType,\n props: Record<string, unknown>,\n elements: readonly ReactElement[],\n env: ParseEnv\n): void => {\n if (elements.length === 0) {\n return;\n }\n for (const field of readAuthoredSpec(itemSchema).children) {\n if (props[field.field] !== undefined) {\n continue;\n }\n const matching = elements.filter(\n (child) => getAuthorType(child) === field.childType\n );\n if (matching.length > 0) {\n props[field.field] = valueFromBrand(matching, field, env);\n }\n }\n};\n\nconst convertPropValue = <TNode extends PrimitiveNode>(\n value: unknown,\n field: string,\n slots: readonly ChildSlot[],\n parseChild: (child: ReactNode) => TNode\n): unknown => {\n const asArray = slots.some((slot) => slot.field === field && slot.array);\n const fromJsx = nodesFromJsx(value, parseChild);\n if (fromJsx) {\n return asArray ? fromJsx : fromJsx[0];\n }\n if (Array.isArray(value)) {\n return value.flatMap((item: unknown) => {\n const nodes = nodesFromJsx(item, parseChild);\n return nodes ?? [item];\n });\n }\n return value;\n};\n\nconst nodesFromJsx = <TNode extends PrimitiveNode>(\n value: unknown,\n parseChild: (child: ReactNode) => TNode\n): TNode[] | undefined => {\n if (isAuthorElement(value)) {\n return [parseChild(value)];\n }\n if (isValidElement(value) && value.type === Fragment) {\n return flattenChildren(value).map(parseChild);\n }\n return undefined;\n};\n\nconst isAuthorElement = (value: unknown): value is ReactElement => {\n if (!isValidElement(value)) {\n return false;\n }\n const component = value.type as Partial<AuthorComponent<unknown, string>>;\n return typeof component[authorType] === 'string';\n};\n\n/** React children as a flat array, with fragments inlined. */\nexport const flattenChildren = (children: ReactNode): ReactNode[] =>\n Children.toArray(children).flatMap((child) => {\n if (isValidElement(child) && child.type === Fragment) {\n const props = child.props as { children?: ReactNode };\n return flattenChildren(props.children);\n }\n return child;\n });\n\n/**\n * Children joined into one string. Throws on an element child, so a prop typed as text stays text. Collapses whitespace unless `{ collapseWhitespace: false }`.\n */\nexport const textFromChildren = (\n children: ReactNode,\n options?: { collapseWhitespace?: boolean }\n): string => {\n const text = flattenChildren(children)\n .map((child) => {\n if (typeof child === 'string' || typeof child === 'number') {\n return String(child);\n }\n throw new IsomerError(\n 'EXPECTED_TEXT_CHILDREN',\n 'Expected text children.'\n );\n })\n .join('');\n if (options?.collapseWhitespace === false) {\n return text.trim();\n }\n return text.replace(/\\s+/g, ' ').trim();\n};\n\n/** An element's props without `children` and without `undefined` entries. */\nconst withoutChildren = <TProps>(element: ReactElement<unknown>): TProps => {\n const props = { ...(element.props as TProps & { children?: ReactNode }) };\n delete props.children;\n return omitUndefined(props);\n};\n\n/** Narrows `element` to an authoring element, asserting `type` when given. */\nconst requireAuthorElement = <TProps>(\n element: ReactNode,\n type?: string\n): ReactElement<TProps & { children?: ReactNode }> => {\n assertValidElement(element);\n const actual = getAuthorType(element);\n if (type !== undefined && actual !== type) {\n throw new IsomerError(\n 'AUTHOR_TYPE_MISMATCH',\n `Expected <${type}> but received <${actual}>.`\n );\n }\n return element as ReactElement<TProps & { children?: ReactNode }>;\n};\n\n/** The primitive type {@link authorType} brands onto `element`'s component. */\nconst getAuthorType = (element: ReactElement<unknown>): string => {\n const component = element.type as Partial<AuthorComponent<unknown, string>>;\n const type = component[authorType];\n if (!type) {\n throw new IsomerError(\n 'EXPECTED_AUTHOR_COMPONENT',\n 'Expected an Isomer authoring component.'\n );\n }\n return type;\n};\n\nconst assertValidElement: (\n element: ReactNode\n) => asserts element is ReactElement<unknown> = (element) => {\n if (!isValidElement(element)) {\n throw new IsomerError(\n 'EXPECTED_JSX_ELEMENT',\n 'Expected an Isomer JSX element.'\n );\n }\n};\n\nconst omitUndefined = <T extends object>(value: T): T =>\n Object.fromEntries(\n Object.entries(value).filter((entry) => entry[1] !== undefined)\n ) as T;\n"]}
|
|
1
|
+
{"version":3,"file":"jsx_shim.js","sourceRoot":"","sources":["../../src/author/jsx_shim.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nimport {\n Children,\n Fragment,\n isValidElement,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport type { z, ZodObject, ZodType } from 'zod';\n\nimport type { Composition } from '../composition/composition';\nimport { IsomerError } from '../composition/error';\nimport type { PrimitiveNode } from '../define/primitive_module';\n\nimport {\n type AuthoredChildBrand,\n type AuthoredChildField,\n type AuthoredNodesBrand,\n type AuthoredSpec,\n type AuthoredTextBrand,\n type AuthoredToItemBrand,\n type ItemSchema,\n readAuthoredSpec,\n} from './authored_fields';\nimport {\n capitalize,\n type ChildSlot,\n createAuthoringModel,\n memberType,\n} from './authoring_model';\nimport { type AuthorComponent, authorType, defineAuthorComponent } from './jsx';\n\n/** A {@link Composition} whose `body` is the pack's own authoring node type. */\nexport type AuthorComposition<TNode extends PrimitiveNode = PrimitiveNode> =\n Omit<Composition<TNode>, 'body'> & {\n body: TNode[];\n };\n\n/**\n * Props of the shim's root element: the composition fields minus `type`, with\n * `body` given either as an array or as JSX children.\n */\nexport interface CompositionAuthorProps<\n TNode extends PrimitiveNode = PrimitiveNode,\n> extends Omit<AuthorComposition<TNode>, 'type' | 'body'> {\n /** Wins outright when present: `children` are then ignored, not merged. */\n body?: TNode[];\n /** Parsed into `body` only when `body` is absent. Each child must be an authoring element of a registered primitive type. */\n children?: ReactNode;\n}\n\n/** Literal `type` strings; wide `string` is dropped so a string index cannot collide with `component`. */\ntype LiteralType<T extends string> = string extends T ? never : T;\n\n/** No keys. Intersects away, unlike `Record<string, never>`. */\ntype NoKeys = Record<never, never>;\n\ntype ShapeOf<T> = T extends { shape: infer Shape } ? Shape : NoKeys;\n\n/** A primitive's schema type, or `never` when it declares none. */\ntype SchemaOf<P> = P extends { schema: infer S }\n ? S extends ZodObject\n ? S\n : never\n : never;\n\n/** A bare `ZodObject` has a string index; a real shape does not. */\ntype LooseSchema<TSchema> = string extends keyof ShapeOf<TSchema>\n ? true\n : false;\n\n// The schema a brand is read from: `F`, or one an optional, nullable, default,\n// or readonly wrapper holds.\ntype Branded<F> = F extends\n AuthoredChildBrand<string, unknown> | AuthoredTextBrand | AuthoredNodesBrand\n ? F\n : F extends {\n _zod: {\n def: {\n type: 'optional' | 'nullable' | 'default' | 'readonly';\n innerType: infer Inner;\n };\n };\n }\n ? Branded<Inner>\n : F;\n\ntype AuthoredNames<TSchema> = {\n [K in keyof ShapeOf<TSchema>]: Branded<ShapeOf<TSchema>[K]> extends\n AuthoredChildBrand<string, unknown> | AuthoredTextBrand | AuthoredNodesBrand\n ? K\n : never;\n}[keyof ShapeOf<TSchema>];\n\ntype SlotValue<V> =\n NonNullable<V> extends readonly (infer Item)[] ? Item : NonNullable<V>;\n\n/**\n * A field holding body nodes, or an array of them: its `type` is wide or one of\n * the pack's `TTypes`, so a discriminated config object does not count.\n */\ntype NodeSlotKey<T, TTypes extends string> = {\n [K in keyof T]-?: K extends 'type'\n ? never\n : SlotValue<T[K]> extends { type: infer Type extends string }\n ? string extends Type\n ? K\n : [Type] extends [TTypes]\n ? K\n : never\n : never;\n}[keyof T];\n\ntype IsUnion<T, U = T> = [T] extends [never]\n ? false\n : T extends unknown\n ? [U] extends [T]\n ? false\n : true\n : false;\n\n/** `T` when it is exactly one key. */\ntype Only<T> = [T] extends [never]\n ? never\n : IsUnion<T> extends true\n ? never\n : T;\n\n/**\n * The one unbranded node field JSX children fill. With several, each stays a\n * prop, as at runtime.\n */\ntype PassthroughSlot<TSchema extends ZodObject, TTypes extends string> = Only<\n Exclude<NodeSlotKey<z.infer<TSchema>, TTypes>, AuthoredNames<TSchema>>\n>;\n\ntype FilledNames<TSchema extends ZodObject, TTypes extends string> =\n AuthoredNames<TSchema> | PassthroughSlot<TSchema, TTypes>;\n\ntype AuthorPropsForSchema<TSchema extends ZodObject, TTypes extends string> =\n LooseSchema<TSchema> extends true\n ? Record<string, unknown> & { children?: ReactNode }\n : Omit<z.infer<TSchema>, 'type' | FilledNames<TSchema, TTypes>> &\n Partial<\n Pick<\n z.infer<TSchema>,\n Extract<FilledNames<TSchema, TTypes>, keyof z.infer<TSchema>>\n >\n > & { children?: ReactNode };\n\ntype AuthorPropsFor<P, TTypes extends string> = [SchemaOf<P>] extends [never]\n ? Record<string, unknown> & { children?: ReactNode }\n : AuthorPropsForSchema<SchemaOf<P>, TTypes>;\n\ntype ChildEntry<\n F,\n TOwner extends string,\n TDepth extends unknown[],\n> = 0 extends 1 & F\n ? NoKeys\n : F extends AuthoredChildBrand<infer Name, infer Props>\n ? [Name] extends [string]\n ? {\n [K in Capitalize<Name>]: AuthorComponent<\n Props & { children?: ReactNode },\n `${TOwner}.${K}`\n >;\n } & (F extends AuthoredToItemBrand\n ? NoKeys\n : ChildComponentsOf<ItemSchema<F>, TOwner, [...TDepth, unknown]>)\n : NoKeys\n : NoKeys;\n\ntype UnionToIntersection<T> = (\n T extends unknown ? (value: T) => void : never\n) extends (value: infer R) => void\n ? R\n : never;\n\n/** Child components branded on `TSchema`, then on each child's item schema, five levels deep. */\ntype ChildComponentsOf<\n TSchema,\n TOwner extends string,\n TDepth extends unknown[] = [],\n> = TDepth['length'] extends 5\n ? NoKeys\n : LooseSchema<TSchema> extends true\n ? NoKeys\n : UnionToIntersection<\n {\n [K in keyof ShapeOf<TSchema>]: ChildEntry<\n Branded<ShapeOf<TSchema>[K]>,\n TOwner,\n TDepth\n >;\n }[keyof ShapeOf<TSchema>]\n >;\n\n/** A primitive's child components, as members of its own component. */\ntype MembersOf<P, TType extends string> = [SchemaOf<P>] extends [never]\n ? NoKeys\n : ChildComponentsOf<SchemaOf<P>, TType>;\n\n/**\n * PascalCase authoring components keyed from a pack's primitive `type` list.\n * `slideFrame` becomes `SlideFrame`. Props come from the primitive's schema,\n * and each branded child is a member: `SlideFrame.Footer`.\n */\nexport type PrimitiveComponentMap<\n TPrimitives extends readonly { type: string }[],\n> = {\n [\n P in TPrimitives[number] as Capitalize<LiteralType<P['type'] & string>>\n ]: AuthorComponent<\n AuthorPropsFor<P, LiteralType<TPrimitives[number]['type'] & string>>,\n P['type'] & string\n > &\n MembersOf<P, P['type'] & string>;\n};\n\n/**\n * A pack's JSX authoring front: the root `Composition` element, one\n * PascalCase component per primitive with its branded children as members,\n * and the conversion back to plain data.\n */\nexport type JsxShim<\n TNode extends PrimitiveNode = PrimitiveNode,\n TPrimitives extends readonly { type: string }[] = readonly { type: string }[],\n> = {\n Composition: AuthorComponent<CompositionAuthorProps<TNode>, 'view'>;\n /** Throws when the root is not the `Composition` element, or when a child is not a registered primitive. */\n toComposition: (\n element: ReactElement<CompositionAuthorProps<TNode>>\n ) => AuthorComposition<TNode>;\n} & PrimitiveComponentMap<TPrimitives>;\n\n/**\n * Builds a pack's {@link JsxShim} from its primitive list.\n *\n * Branded schema fields ({@link fromChildren}, {@link fromTextChildren}) fill\n * from JSX children, and each child becomes a member of its primitive's\n * component. Several branded fields share one children list, and each takes\n * the elements of its member.\n * Elements of a registered primitive that match none of them fill the one\n * unbranded child slot from {@link PrimitiveDefinition.children}, or the one\n * {@link fromNodeChildren} field. A primitive with no brand still fills that slot, array or\n * single node, from its children. That field is optional on the component's\n * props.\n */\nexport const buildJsxShim = <\n const TPrimitives extends readonly { type: string }[] = readonly {\n type: string;\n }[],\n TNode extends PrimitiveNode = PrimitiveNode,\n>(\n primitives: TPrimitives = [] as unknown as TPrimitives\n): JsxShim<TNode, TPrimitives> => {\n const primitiveTypes = new Set(primitives.map((primitive) => primitive.type));\n const { authoredByType, membersByType, childSlotsByType } =\n createAuthoringModel(primitives);\n const view = defineAuthorComponent<CompositionAuthorProps<TNode>, 'view'>(\n 'view'\n );\n const env: ParseEnv = {\n authoredByType,\n childSlotsByType,\n primitiveTypes,\n };\n\n return {\n Composition: view,\n toComposition: (element) => toAuthorComposition<TNode>(element, env),\n ...Object.fromEntries(\n primitives.map(({ type }) => [\n capitalize(type),\n Object.assign(\n defineAuthorComponent(type),\n Object.fromEntries(\n (membersByType.get(type) ?? []).map(({ member, authorType }) => [\n member,\n defineAuthorComponent(authorType),\n ])\n )\n ),\n ])\n ),\n } as JsxShim<TNode, TPrimitives>;\n};\n\ninterface ParseEnv {\n authoredByType: ReadonlyMap<string, AuthoredSpec>;\n childSlotsByType: ReadonlyMap<string, readonly ChildSlot[]>;\n primitiveTypes: ReadonlySet<string>;\n}\n\nconst toAuthorComposition = <TNode extends PrimitiveNode>(\n element: ReactElement<CompositionAuthorProps<TNode>>,\n env: ParseEnv\n): AuthorComposition<TNode> => {\n requireAuthorElement<CompositionAuthorProps<TNode>>(element, 'view');\n const props = element.props;\n const resolvedBody =\n props.body ??\n flattenChildren(props.children).map((child) =>\n bodyNodeFromElement<TNode>(child, env)\n );\n const spec: AuthorComposition<TNode> = {\n type: 'view',\n body: resolvedBody,\n };\n\n if (props.version !== undefined) {\n spec.version = props.version;\n }\n if (props.title !== undefined) {\n spec.title = props.title;\n }\n if (props.subtitle !== undefined) {\n spec.subtitle = props.subtitle;\n }\n if (props.theme !== undefined) {\n spec.theme = props.theme;\n }\n if (props.meta !== undefined) {\n spec.meta = props.meta;\n }\n\n return spec;\n};\n\nconst bodyNodeFromElement = <TNode extends PrimitiveNode>(\n node: ReactNode,\n env: ParseEnv\n): TNode => {\n const element = requireAuthorElement<{ children?: ReactNode }>(node);\n const type = getAuthorType(element);\n if (!env.primitiveTypes.has(type)) {\n throw new IsomerError(\n 'INVALID_BODY_NODE',\n `\"${type}\" cannot be used as a composition body node.`\n );\n }\n\n const parseChild = (child: ReactNode): TNode =>\n bodyNodeFromElement<TNode>(child, env);\n const slots = env.childSlotsByType.get(type) ?? [];\n const authored = env.authoredByType.get(type);\n const converted: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(\n withoutChildren<Record<string, unknown>>(element)\n )) {\n const childField = authored?.children.find((field) => field.field === key);\n converted[key] = childField\n ? valueFromChildField(value, childField, env, type)\n : convertPropValue(value, key, slots, parseChild);\n }\n\n const rawChildren = element.props.children;\n if (authored && (authored.children.length > 0 || authored.text.length > 0)) {\n fillAuthoredFields(\n converted,\n authored,\n rawChildren,\n env,\n slots,\n parseChild,\n type\n );\n } else {\n const unique = slots.length === 1 ? slots[0] : undefined;\n if (\n unique &&\n converted[unique.field] === undefined &&\n rawChildren !== undefined\n ) {\n const nested = flattenChildren(rawChildren).map(parseChild);\n converted[unique.field] = slotValue(nested, unique);\n } else if (slots.length === 0 && flattenChildren(rawChildren).length > 0) {\n throw new IsomerError(\n 'UNEXPECTED_CHILDREN',\n `<${capitalize(type)}> takes no JSX children; set its fields through props.`\n );\n }\n }\n\n return omitUndefined({ ...converted, type }) as TNode;\n};\n\nconst fillAuthoredFields = (\n converted: Record<string, unknown>,\n authored: AuthoredSpec,\n rawChildren: ReactNode,\n env: ParseEnv,\n slots: readonly ChildSlot[],\n parseChild: (child: ReactNode) => PrimitiveNode,\n parentType: string\n): void => {\n const unsetChildren = authored.children.filter(\n (field) => converted[field.field] === undefined\n );\n const unsetText = authored.text.filter(\n (field) => converted[field.field] === undefined\n );\n const brandedFields = new Set(authored.children.map((field) => field.field));\n const unbranded = slots.filter(({ field }) => !brandedFields.has(field));\n const slot = unbranded.length === 1 ? unbranded[0] : undefined;\n const slotOpen = slot !== undefined && converted[slot.field] === undefined;\n if (\n rawChildren === undefined ||\n (unsetChildren.length === 0 && unsetText.length === 0 && !slotOpen)\n ) {\n for (const field of unsetText) {\n if (!field.optional) {\n throw new IsomerError(\n 'MISSING_AUTHORED_TEXT',\n `Expected text children for \"${field.field}\".`\n );\n }\n }\n return;\n }\n\n const flat = flattenChildren(rawChildren);\n const elements = flat.filter(isAuthorElement);\n const textNodes = flat.filter((child) => !isAuthorElement(child));\n const claimed = new Set<ReactElement>();\n for (const field of unsetChildren) {\n const matching = elements.filter(\n (child) => getAuthorType(child) === memberType(parentType, field)\n );\n if (matching.length === 0) {\n if (flat.length === 0 && field.array && !field.optional) {\n converted[field.field] = [];\n }\n continue;\n }\n for (const child of matching) {\n claimed.add(child);\n }\n converted[field.field] = valueFromBrand(matching, field, env, parentType);\n }\n\n const brandedTypes = new Set(\n authored.children.map((field) => memberType(parentType, field))\n );\n const stray = elements.filter(\n (child) => brandedTypes.has(getAuthorType(child)) && !claimed.has(child)\n );\n if (stray.length > 0) {\n const childType = getAuthorType(stray[0]!);\n throw new IsomerError(\n 'UNEXPECTED_CHILDREN',\n `<${capitalize(parentType)}> already has its <${capitalize(childType)}>.`\n );\n }\n\n const leftover = elements.filter((child) => !claimed.has(child));\n if (slotOpen && slot && leftover.length > 0) {\n const nested = leftover.map(parseChild);\n converted[slot.field] = slotValue(nested, slot);\n } else if (leftover.length > 0) {\n const childType = getAuthorType(leftover[0]!);\n const [empty, ...moreEmpty] = unsetChildren.filter(\n ({ field }) => converted[field] === undefined\n );\n if (empty && moreEmpty.length === 0 && !slotOpen) {\n throw new IsomerError(\n 'AUTHOR_TYPE_MISMATCH',\n `Expected <${capitalize(memberType(parentType, empty))}> but received <${capitalize(childType)}>.`\n );\n }\n throw new IsomerError(\n 'UNEXPECTED_CHILDREN',\n `<${capitalize(childType)}> is not a child of <${capitalize(parentType)}>.`\n );\n }\n\n if (textNodes.length === 0) {\n for (const field of unsetText) {\n if (!field.optional) {\n throw new IsomerError(\n 'MISSING_AUTHORED_TEXT',\n `Expected text children for \"${field.field}\".`\n );\n }\n }\n return;\n }\n if (unsetText.length === 0) {\n throw new IsomerError(\n 'EXPECTED_JSX_ELEMENT',\n 'Expected an Isomer JSX element.'\n );\n }\n for (const field of unsetText) {\n converted[field.field] = textFromChildren(textNodes, {\n collapseWhitespace: field.collapseWhitespace,\n ...(field.dedent ? { dedent: true } : {}),\n });\n }\n};\n\nconst valueFromChildField = (\n value: unknown,\n field: AuthoredChildField,\n env: ParseEnv,\n owner: string\n): unknown => {\n if (isJsxNodes(value)) {\n return valueFromBrand(flattenChildren(value), field, env, owner);\n }\n return value;\n};\n\nconst isJsxNodes = (value: unknown): value is ReactNode => {\n if (isAuthorElement(value)) {\n return true;\n }\n if (isValidElement(value) && value.type === Fragment) {\n return true;\n }\n return (\n Array.isArray(value) &&\n value.some((item: unknown) => isAuthorElement(item) || isValidElement(item))\n );\n};\n\n/** The field's array of items, or its one item; throws on a second element for a single-item field. */\nconst valueFromBrand = (\n elements: readonly ReactNode[],\n field: AuthoredChildField,\n env: ParseEnv,\n owner: string\n): unknown => {\n const items = elements.map((child) =>\n itemFromElement(child, field, env, owner)\n );\n if (field.array) {\n return items;\n }\n if (items.length > 1) {\n throw new IsomerError(\n 'UNEXPECTED_CHILDREN',\n `\"${field.field}\" takes one <${capitalize(memberType(owner, field))}>, not ${items.length}.`\n );\n }\n return items[0];\n};\n\nconst itemFromElement = (\n child: ReactNode,\n field: AuthoredChildField,\n env: ParseEnv,\n owner: string\n): unknown => {\n const element = requireAuthorElement<Record<string, unknown>>(\n child,\n memberType(owner, field)\n );\n if (field.toItem) {\n return field.toItem(element.props, {\n parseChildren: (nested) =>\n flattenChildren(nested).map((node) => bodyNodeFromElement(node, env)),\n });\n }\n const props = withoutChildren<Record<string, unknown>>(element);\n const nested = flattenChildren(element.props.children);\n const elements = nested.filter(isAuthorElement);\n const text = nested.filter((child) => !isAuthorElement(child));\n if (\n field.textField !== undefined &&\n props[field.textField] === undefined &&\n text.length > 0\n ) {\n props[field.textField] = textFromChildren(text);\n }\n fillNestedBrands(\n field.itemSchema,\n props,\n elements,\n env,\n owner,\n capitalize(memberType(owner, field))\n );\n return props;\n};\n\nconst fillNestedBrands = (\n itemSchema: ZodType,\n props: Record<string, unknown>,\n elements: readonly ReactElement[],\n env: ParseEnv,\n owner: string,\n parent: string\n): void => {\n if (elements.length === 0) {\n return;\n }\n const fields = readAuthoredSpec(itemSchema).children;\n const claimed = new Set<ReactElement>();\n for (const field of fields) {\n if (props[field.field] !== undefined) {\n continue;\n }\n const matching = elements.filter(\n (child) => getAuthorType(child) === memberType(owner, field)\n );\n if (matching.length > 0) {\n matching.forEach((child) => claimed.add(child));\n props[field.field] = valueFromBrand(matching, field, env, owner);\n }\n }\n const [stray] = elements.filter((child) => !claimed.has(child));\n if (stray) {\n const strayType = getAuthorType(stray);\n const held = fields.some((field) => memberType(owner, field) === strayType);\n throw new IsomerError(\n 'UNEXPECTED_CHILDREN',\n held\n ? `<${parent}> already has its <${capitalize(strayType)}>.`\n : `<${capitalize(strayType)}> is not a child of <${parent}>.`\n );\n }\n};\n\n/** The slot's nodes, or its one node; throws on a second node for a single-node slot. */\nconst slotValue = <TNode extends PrimitiveNode>(\n nodes: readonly TNode[],\n { array, field }: ChildSlot\n): readonly TNode[] | TNode | undefined => {\n if (array) {\n return nodes;\n }\n if (nodes.length > 1) {\n throw new IsomerError(\n 'UNEXPECTED_CHILDREN',\n `\"${field}\" takes one node, not ${nodes.length}.`\n );\n }\n return nodes[0];\n};\n\nconst convertPropValue = <TNode extends PrimitiveNode>(\n value: unknown,\n field: string,\n slots: readonly ChildSlot[],\n parseChild: (child: ReactNode) => TNode\n): unknown => {\n const array = slots.some((slot) => slot.field === field && slot.array);\n const fromJsx = nodesFromJsx(value, parseChild);\n if (fromJsx) {\n return slotValue(fromJsx, { array, field });\n }\n if (Array.isArray(value)) {\n return value.flatMap((item: unknown) => {\n const nodes = nodesFromJsx(item, parseChild);\n return nodes ?? [item];\n });\n }\n return value;\n};\n\nconst nodesFromJsx = <TNode extends PrimitiveNode>(\n value: unknown,\n parseChild: (child: ReactNode) => TNode\n): TNode[] | undefined => {\n if (isAuthorElement(value)) {\n return [parseChild(value)];\n }\n if (isValidElement(value) && value.type === Fragment) {\n return flattenChildren(value).map(parseChild);\n }\n return undefined;\n};\n\nconst isAuthorElement = (value: unknown): value is ReactElement => {\n if (!isValidElement(value)) {\n return false;\n }\n const component = value.type as Partial<AuthorComponent<unknown, string>>;\n return typeof component[authorType] === 'string';\n};\n\n/** React children as a flat array, with fragments inlined. */\nexport const flattenChildren = (children: ReactNode): ReactNode[] =>\n Children.toArray(children).flatMap((child) => {\n if (isValidElement(child) && child.type === Fragment) {\n const props = child.props as { children?: ReactNode };\n return flattenChildren(props.children);\n }\n return child;\n });\n\nconst lineBreak = /\\r\\n|[\\n\\r\\u2028\\u2029]/;\n\n// A template literal's source: the break after the opening backtick, the\n// indentation before the closing one, and the indentation every line shares go.\nconst dedentSource = (text: string): string => {\n const all = text.split(lineBreak);\n const start = all.length > 1 && all[0] === '' ? 1 : 0;\n const end =\n all.length - start > 1 && /^ *$/.test(all[all.length - 1]!)\n ? all.length - 1\n : all.length;\n const lines = all.slice(start, end);\n const indents = lines\n .filter((line) => line.trim() !== '')\n .map((line) => line.length - line.trimStart().length);\n const shared = indents.length > 0 ? Math.min(...indents) : 0;\n return lines.map((line) => line.slice(shared)).join('\\n');\n};\n\n/**\n * Children joined into one string. Throws on an element child, so a prop typed as text stays text. Collapses whitespace unless `{ collapseWhitespace: false }`; `{ dedent: true }` reads it as source, lines joined by `\\n`.\n */\nexport const textFromChildren = (\n children: ReactNode,\n options?: { collapseWhitespace?: boolean; dedent?: boolean }\n): string => {\n const text = flattenChildren(children)\n .map((child) => {\n if (typeof child === 'string' || typeof child === 'number') {\n return String(child);\n }\n throw new IsomerError(\n 'EXPECTED_TEXT_CHILDREN',\n 'Expected text children.'\n );\n })\n .join('');\n if (options?.dedent) {\n return dedentSource(text);\n }\n if (options?.collapseWhitespace === false) {\n return text.trim();\n }\n return text.replace(/\\s+/g, ' ').trim();\n};\n\n/** An element's props without `children` and without `undefined` entries. */\nconst withoutChildren = <TProps>(element: ReactElement<unknown>): TProps => {\n const props = { ...(element.props as TProps & { children?: ReactNode }) };\n delete props.children;\n return omitUndefined(props);\n};\n\n/** Narrows `element` to an authoring element, asserting `type` when given. */\nconst requireAuthorElement = <TProps>(\n element: ReactNode,\n type?: string\n): ReactElement<TProps & { children?: ReactNode }> => {\n assertValidElement(element);\n const actual = getAuthorType(element);\n if (type !== undefined && actual !== type) {\n throw new IsomerError(\n 'AUTHOR_TYPE_MISMATCH',\n `Expected <${type}> but received <${actual}>.`\n );\n }\n return element as ReactElement<TProps & { children?: ReactNode }>;\n};\n\n/** The primitive type {@link authorType} brands onto `element`'s component. */\nconst getAuthorType = (element: ReactElement<unknown>): string => {\n const component = element.type as Partial<AuthorComponent<unknown, string>>;\n const type = component[authorType];\n if (!type) {\n throw new IsomerError(\n 'EXPECTED_AUTHOR_COMPONENT',\n 'Expected an Isomer authoring component.'\n );\n }\n return type;\n};\n\nconst assertValidElement: (\n element: ReactNode\n) => asserts element is ReactElement<unknown> = (element) => {\n if (!isValidElement(element)) {\n throw new IsomerError(\n 'EXPECTED_JSX_ELEMENT',\n 'Expected an Isomer JSX element.'\n );\n }\n};\n\nconst omitUndefined = <T extends object>(value: T): T =>\n Object.fromEntries(\n Object.entries(value).filter((entry) => entry[1] !== undefined)\n ) as T;\n"]}
|