@elastic/isomer-sdk 0.1.0 → 0.2.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 (222) hide show
  1. package/README.md +13 -2
  2. package/dist/author/authored_fields.d.ts +61 -11
  3. package/dist/author/authored_fields.d.ts.map +1 -1
  4. package/dist/author/authored_fields.js +73 -29
  5. package/dist/author/authored_fields.js.map +1 -1
  6. package/dist/author/authoring_input.d.ts +7 -0
  7. package/dist/author/authoring_input.d.ts.map +1 -0
  8. package/dist/author/authoring_input.js +60 -0
  9. package/dist/author/authoring_input.js.map +1 -0
  10. package/dist/author/authoring_model.d.ts +27 -0
  11. package/dist/author/authoring_model.d.ts.map +1 -0
  12. package/dist/author/authoring_model.js +98 -0
  13. package/dist/author/authoring_model.js.map +1 -0
  14. package/dist/author/declarations.d.ts +13 -0
  15. package/dist/author/declarations.d.ts.map +1 -0
  16. package/dist/author/declarations.js +277 -0
  17. package/dist/author/declarations.js.map +1 -0
  18. package/dist/author/index.d.ts +3 -1
  19. package/dist/author/index.d.ts.map +1 -1
  20. package/dist/author/index.js +3 -1
  21. package/dist/author/index.js.map +1 -1
  22. package/dist/author/jsx_shim.d.ts +6 -5
  23. package/dist/author/jsx_shim.d.ts.map +1 -1
  24. package/dist/author/jsx_shim.js +28 -111
  25. package/dist/author/jsx_shim.js.map +1 -1
  26. package/dist/author/schema_to_typescript.d.ts +37 -0
  27. package/dist/author/schema_to_typescript.d.ts.map +1 -0
  28. package/dist/author/schema_to_typescript.js +286 -0
  29. package/dist/author/schema_to_typescript.js.map +1 -0
  30. package/dist/cjs/author/authored_fields.js +77 -33
  31. package/dist/cjs/author/authored_fields.js.map +1 -1
  32. package/dist/cjs/author/authoring_input.js +64 -0
  33. package/dist/cjs/author/authoring_input.js.map +1 -0
  34. package/dist/cjs/author/authoring_model.js +104 -0
  35. package/dist/cjs/author/authoring_model.js.map +1 -0
  36. package/dist/cjs/author/declarations.js +281 -0
  37. package/dist/cjs/author/declarations.js.map +1 -0
  38. package/dist/cjs/author/index.js +6 -1
  39. package/dist/cjs/author/index.js.map +1 -1
  40. package/dist/cjs/author/jsx_shim.js +31 -114
  41. package/dist/cjs/author/jsx_shim.js.map +1 -1
  42. package/dist/cjs/author/schema_to_typescript.js +295 -0
  43. package/dist/cjs/author/schema_to_typescript.js.map +1 -0
  44. package/dist/cjs/composition/body_node_base.js +11 -4
  45. package/dist/cjs/composition/body_node_base.js.map +1 -1
  46. package/dist/cjs/composition/error.js +1 -0
  47. package/dist/cjs/composition/error.js.map +1 -1
  48. package/dist/cjs/composition/index.js +2 -1
  49. package/dist/cjs/composition/index.js.map +1 -1
  50. package/dist/cjs/define/frame.js +2 -3
  51. package/dist/cjs/define/frame.js.map +1 -1
  52. package/dist/cjs/define/index.js +7 -1
  53. package/dist/cjs/define/index.js.map +1 -1
  54. package/dist/cjs/define/primitive_example.js +26 -0
  55. package/dist/cjs/define/primitive_example.js.map +1 -0
  56. package/dist/cjs/define/primitive_icon.js +17 -0
  57. package/dist/cjs/define/primitive_icon.js.map +1 -0
  58. package/dist/cjs/define/primitive_module.js +14 -3
  59. package/dist/cjs/define/primitive_module.js.map +1 -1
  60. package/dist/cjs/define/slack_assets.js.map +1 -1
  61. package/dist/cjs/entries/index.js +7 -2
  62. package/dist/cjs/entries/index.js.map +1 -1
  63. package/dist/cjs/entries/slack.js +1 -2
  64. package/dist/cjs/entries/slack.js.map +1 -1
  65. package/dist/cjs/pack/capabilities.js +17 -11
  66. package/dist/cjs/pack/capabilities.js.map +1 -1
  67. package/dist/cjs/pack/compose.js +4 -1
  68. package/dist/cjs/pack/compose.js.map +1 -1
  69. package/dist/cjs/pack/index.js.map +1 -1
  70. package/dist/cjs/pack/primitive_pack.js +14 -2
  71. package/dist/cjs/pack/primitive_pack.js.map +1 -1
  72. package/dist/cjs/render/anchors.js +1 -1
  73. package/dist/cjs/render/anchors.js.map +1 -1
  74. package/dist/cjs/render/html/envelope.js.map +1 -1
  75. package/dist/cjs/render/layout_check.js.map +1 -1
  76. package/dist/cjs/render/markdown/builder.js +14 -8
  77. package/dist/cjs/render/markdown/builder.js.map +1 -1
  78. package/dist/cjs/render/markdown/format.js +30 -12
  79. package/dist/cjs/render/markdown/format.js.map +1 -1
  80. package/dist/cjs/render/primitive_dispatch.js +11 -25
  81. package/dist/cjs/render/primitive_dispatch.js.map +1 -1
  82. package/dist/cjs/render/slack/format.js +1 -601
  83. package/dist/cjs/render/slack/format.js.map +1 -1
  84. package/dist/cjs/render/slack/index.js +1 -2
  85. package/dist/cjs/render/slack/index.js.map +1 -1
  86. package/dist/cjs/render/slack/markdown_content.js +166 -115
  87. package/dist/cjs/render/slack/markdown_content.js.map +1 -1
  88. package/dist/cjs/testing/conformance.js +40 -24
  89. package/dist/cjs/testing/conformance.js.map +1 -1
  90. package/dist/cjs/testing/icon.js +248 -0
  91. package/dist/cjs/testing/icon.js.map +1 -0
  92. package/dist/cjs/testing/index.js +3 -1
  93. package/dist/cjs/testing/index.js.map +1 -1
  94. package/dist/cjs/testing/registration.js +5 -3
  95. package/dist/cjs/testing/registration.js.map +1 -1
  96. package/dist/cjs/validate/authoring_schema.js +17 -1
  97. package/dist/cjs/validate/authoring_schema.js.map +1 -1
  98. package/dist/cjs/validate/index.js +2 -1
  99. package/dist/cjs/validate/index.js.map +1 -1
  100. package/dist/cjs/validate/validation.js +2 -45
  101. package/dist/cjs/validate/validation.js.map +1 -1
  102. package/dist/composition/body_node_base.d.ts +7 -6
  103. package/dist/composition/body_node_base.d.ts.map +1 -1
  104. package/dist/composition/body_node_base.js +10 -3
  105. package/dist/composition/body_node_base.js.map +1 -1
  106. package/dist/composition/error.d.ts +1 -0
  107. package/dist/composition/error.d.ts.map +1 -1
  108. package/dist/composition/error.js +1 -0
  109. package/dist/composition/error.js.map +1 -1
  110. package/dist/composition/index.d.ts +1 -1
  111. package/dist/composition/index.d.ts.map +1 -1
  112. package/dist/composition/index.js +1 -1
  113. package/dist/composition/index.js.map +1 -1
  114. package/dist/define/frame.d.ts +9 -20
  115. package/dist/define/frame.d.ts.map +1 -1
  116. package/dist/define/frame.js +2 -3
  117. package/dist/define/frame.js.map +1 -1
  118. package/dist/define/index.d.ts +3 -1
  119. package/dist/define/index.d.ts.map +1 -1
  120. package/dist/define/index.js +3 -1
  121. package/dist/define/index.js.map +1 -1
  122. package/dist/define/primitive_example.d.ts +30 -0
  123. package/dist/define/primitive_example.d.ts.map +1 -0
  124. package/dist/define/primitive_example.js +21 -0
  125. package/dist/define/primitive_example.js.map +1 -0
  126. package/dist/define/primitive_icon.d.ts +11 -0
  127. package/dist/define/primitive_icon.d.ts.map +1 -0
  128. package/dist/define/primitive_icon.js +14 -0
  129. package/dist/define/primitive_icon.js.map +1 -0
  130. package/dist/define/primitive_module.d.ts +38 -24
  131. package/dist/define/primitive_module.d.ts.map +1 -1
  132. package/dist/define/primitive_module.js +14 -3
  133. package/dist/define/primitive_module.js.map +1 -1
  134. package/dist/define/slack_assets.d.ts +1 -1
  135. package/dist/define/slack_assets.d.ts.map +1 -1
  136. package/dist/define/slack_assets.js.map +1 -1
  137. package/dist/entries/index.d.ts +3 -3
  138. package/dist/entries/index.d.ts.map +1 -1
  139. package/dist/entries/index.js +2 -2
  140. package/dist/entries/index.js.map +1 -1
  141. package/dist/entries/slack.d.ts +1 -1
  142. package/dist/entries/slack.d.ts.map +1 -1
  143. package/dist/entries/slack.js +1 -1
  144. package/dist/entries/slack.js.map +1 -1
  145. package/dist/pack/capabilities.d.ts +24 -10
  146. package/dist/pack/capabilities.d.ts.map +1 -1
  147. package/dist/pack/capabilities.js +17 -11
  148. package/dist/pack/capabilities.js.map +1 -1
  149. package/dist/pack/compose.d.ts +4 -1
  150. package/dist/pack/compose.d.ts.map +1 -1
  151. package/dist/pack/compose.js +4 -1
  152. package/dist/pack/compose.js.map +1 -1
  153. package/dist/pack/index.d.ts +1 -1
  154. package/dist/pack/index.d.ts.map +1 -1
  155. package/dist/pack/index.js +1 -1
  156. package/dist/pack/index.js.map +1 -1
  157. package/dist/pack/primitive_pack.d.ts +11 -2
  158. package/dist/pack/primitive_pack.d.ts.map +1 -1
  159. package/dist/pack/primitive_pack.js +12 -1
  160. package/dist/pack/primitive_pack.js.map +1 -1
  161. package/dist/render/anchors.d.ts +2 -2
  162. package/dist/render/anchors.d.ts.map +1 -1
  163. package/dist/render/anchors.js +1 -1
  164. package/dist/render/anchors.js.map +1 -1
  165. package/dist/render/html/envelope.d.ts +3 -3
  166. package/dist/render/html/envelope.js.map +1 -1
  167. package/dist/render/layout_check.d.ts +1 -1
  168. package/dist/render/layout_check.d.ts.map +1 -1
  169. package/dist/render/layout_check.js.map +1 -1
  170. package/dist/render/markdown/builder.d.ts +2 -4
  171. package/dist/render/markdown/builder.d.ts.map +1 -1
  172. package/dist/render/markdown/builder.js +14 -7
  173. package/dist/render/markdown/builder.js.map +1 -1
  174. package/dist/render/markdown/format.d.ts +7 -0
  175. package/dist/render/markdown/format.d.ts.map +1 -1
  176. package/dist/render/markdown/format.js +27 -11
  177. package/dist/render/markdown/format.js.map +1 -1
  178. package/dist/render/primitive_dispatch.d.ts +6 -6
  179. package/dist/render/primitive_dispatch.d.ts.map +1 -1
  180. package/dist/render/primitive_dispatch.js +12 -26
  181. package/dist/render/primitive_dispatch.js.map +1 -1
  182. package/dist/render/slack/format.d.ts +0 -25
  183. package/dist/render/slack/format.d.ts.map +1 -1
  184. package/dist/render/slack/format.js +1 -599
  185. package/dist/render/slack/format.js.map +1 -1
  186. package/dist/render/slack/index.d.ts +1 -1
  187. package/dist/render/slack/index.d.ts.map +1 -1
  188. package/dist/render/slack/index.js +1 -1
  189. package/dist/render/slack/index.js.map +1 -1
  190. package/dist/render/slack/markdown_content.d.ts +10 -4
  191. package/dist/render/slack/markdown_content.d.ts.map +1 -1
  192. package/dist/render/slack/markdown_content.js +163 -113
  193. package/dist/render/slack/markdown_content.js.map +1 -1
  194. package/dist/testing/conformance.d.ts +19 -14
  195. package/dist/testing/conformance.d.ts.map +1 -1
  196. package/dist/testing/conformance.js +40 -24
  197. package/dist/testing/conformance.js.map +1 -1
  198. package/dist/testing/icon.d.ts +11 -0
  199. package/dist/testing/icon.d.ts.map +1 -0
  200. package/dist/testing/icon.js +244 -0
  201. package/dist/testing/icon.js.map +1 -0
  202. package/dist/testing/index.d.ts +2 -1
  203. package/dist/testing/index.d.ts.map +1 -1
  204. package/dist/testing/index.js +1 -0
  205. package/dist/testing/index.js.map +1 -1
  206. package/dist/testing/registration.d.ts +1 -1
  207. package/dist/testing/registration.d.ts.map +1 -1
  208. package/dist/testing/registration.js +6 -4
  209. package/dist/testing/registration.js.map +1 -1
  210. package/dist/validate/authoring_schema.d.ts +6 -0
  211. package/dist/validate/authoring_schema.d.ts.map +1 -1
  212. package/dist/validate/authoring_schema.js +15 -0
  213. package/dist/validate/authoring_schema.js.map +1 -1
  214. package/dist/validate/index.d.ts +1 -1
  215. package/dist/validate/index.d.ts.map +1 -1
  216. package/dist/validate/index.js +1 -1
  217. package/dist/validate/index.js.map +1 -1
  218. package/dist/validate/validation.d.ts +1 -11
  219. package/dist/validate/validation.d.ts.map +1 -1
  220. package/dist/validate/validation.js +3 -46
  221. package/dist/validate/validation.js.map +1 -1
  222. package/package.json +3 -2
@@ -0,0 +1,286 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ * or more contributor license agreements. Licensed under the Elastic License
4
+ * 2.0; you may not use this file except in compliance with the Elastic License
5
+ * 2.0.
6
+ */
7
+ export const DEF_PREFIX = '#/$defs/';
8
+ /** Ids `z.toJSONSchema` gives a def no one named. */
9
+ export const ANONYMOUS_DEF = /^__schema\d+$/;
10
+ const STRUCTURAL_KEYS = [
11
+ 'type',
12
+ 'const',
13
+ 'enum',
14
+ 'properties',
15
+ 'additionalProperties',
16
+ 'patternProperties',
17
+ 'propertyNames',
18
+ 'items',
19
+ 'prefixItems',
20
+ 'oneOf',
21
+ 'anyOf',
22
+ 'allOf',
23
+ ];
24
+ const INDENT = ' ';
25
+ export const IDENTIFIER = /^[A-Za-z_$][\w$]*$/;
26
+ export const isJsonObject = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
27
+ export const parseDefRef = (ref) => typeof ref === 'string' && ref.startsWith(DEF_PREFIX)
28
+ ? ref.slice(DEF_PREFIX.length)
29
+ : undefined;
30
+ export const ownDef = (defs, id) => Object.hasOwn(defs, id) ? defs[id] : undefined;
31
+ /** `slideStats` becomes `SlideStats`; anything but letters and digits splits words. */
32
+ export const pascalCase = (value) => {
33
+ const name = value
34
+ .split(/[^A-Za-z0-9]+/)
35
+ .filter(Boolean)
36
+ .map((word) => `${word.slice(0, 1).toUpperCase()}${word.slice(1)}`)
37
+ .join('');
38
+ if (name === '') {
39
+ return 'Type';
40
+ }
41
+ return /^\d/.test(name) ? `_${name}` : name;
42
+ };
43
+ /** A JSDoc block for `lines`, or `''` when there are none. */
44
+ export const jsDoc = (lines, pad) => {
45
+ const text = lines
46
+ .flatMap((line) => line.split('\n'))
47
+ .map((line) => line.replaceAll('*/', '*\\/').trimEnd());
48
+ while (text[0] === '') {
49
+ text.shift();
50
+ }
51
+ while (text.at(-1) === '') {
52
+ text.pop();
53
+ }
54
+ if (text.length === 0) {
55
+ return '';
56
+ }
57
+ const [only] = text;
58
+ if (text.length === 1 && only !== undefined) {
59
+ return `${pad}/** ${only} */\n`;
60
+ }
61
+ return `${pad}/**\n${text
62
+ .map((line) => (line === '' ? `${pad} *` : `${pad} * ${line}`))
63
+ .join('\n')}\n${pad} */\n`;
64
+ };
65
+ const propertyKey = (key) => IDENTIFIER.test(key) ? key : JSON.stringify(key);
66
+ const literal = (value) => {
67
+ if (value === null) {
68
+ return 'null';
69
+ }
70
+ switch (typeof value) {
71
+ case 'string':
72
+ return JSON.stringify(value);
73
+ case 'number':
74
+ case 'boolean':
75
+ return String(value);
76
+ default:
77
+ return 'unknown';
78
+ }
79
+ };
80
+ const atom = (text) => ({ text, kind: 'atom' });
81
+ const union = (members) => {
82
+ if (members.some(({ text }) => text === 'unknown'))
83
+ return atom('unknown');
84
+ const unique = new Map(members.map((member) => [member.text, member]));
85
+ const [only] = [...unique.values()];
86
+ if (unique.size === 0) {
87
+ return atom('never');
88
+ }
89
+ return unique.size === 1 && only
90
+ ? only
91
+ : { text: [...unique.keys()].join(' | '), kind: 'union' };
92
+ };
93
+ const intersection = (members) => {
94
+ const unique = new Map(members.map((member) => [member.text, member]));
95
+ const [only] = [...unique.values()];
96
+ if (!only)
97
+ return atom('unknown');
98
+ if (unique.size === 1 && only) {
99
+ return only;
100
+ }
101
+ return {
102
+ text: [...unique.values()]
103
+ .map(({ text, kind }) => (kind === 'union' ? `(${text})` : text))
104
+ .join(' & '),
105
+ kind: 'intersection',
106
+ };
107
+ };
108
+ const arrayOf = ({ text, kind }) => atom(kind === 'atom' ? `${text}[]` : `(${text})[]`);
109
+ /** A TypeScript printer over the subset of JSON Schema `z.toJSONSchema` emits. */
110
+ export const createTypePrinter = ({ defs, names, claim, }) => {
111
+ const promotedNames = new Map();
112
+ const printRef = (id, depth, active) => {
113
+ const named = names.get(id);
114
+ if (named !== undefined) {
115
+ return atom(named);
116
+ }
117
+ const target = ownDef(defs, id);
118
+ if (target === undefined) {
119
+ return atom('unknown');
120
+ }
121
+ if (active.has(id)) {
122
+ const name = promotedNames.get(id) ?? claim(pascalCase(id));
123
+ promotedNames.set(id, name);
124
+ return atom(name);
125
+ }
126
+ return printNode(target, depth, new Set([...active, id]));
127
+ };
128
+ const printNode = (node, depth, active) => {
129
+ if (node === false) {
130
+ return atom('never');
131
+ }
132
+ if (!isJsonObject(node)) {
133
+ return atom('unknown');
134
+ }
135
+ const parts = [];
136
+ const ref = parseDefRef(node.$ref);
137
+ if (ref !== undefined) {
138
+ parts.push(printRef(ref, depth, active));
139
+ }
140
+ if (STRUCTURAL_KEYS.some((key) => Object.hasOwn(node, key))) {
141
+ parts.push(printStructure(node, depth, active));
142
+ }
143
+ return parts.length === 0 ? atom('unknown') : intersection(parts);
144
+ };
145
+ const printStructure = (node, depth, active) => {
146
+ const parts = [];
147
+ const own = printOwn(node, depth, active);
148
+ if (own) {
149
+ parts.push(own);
150
+ }
151
+ for (const key of ['oneOf', 'anyOf']) {
152
+ const members = node[key];
153
+ if (Array.isArray(members)) {
154
+ parts.push(union(members.map((member) => printNode(member, depth, active))));
155
+ }
156
+ }
157
+ if (Array.isArray(node.allOf)) {
158
+ parts.push(intersection(node.allOf.map((member) => printNode(member, depth, active))));
159
+ }
160
+ return parts.length === 0 ? atom('unknown') : intersection(parts);
161
+ };
162
+ // `undefined` when the node only combines other schemas.
163
+ const printOwn = (node, depth, active) => {
164
+ if (Object.hasOwn(node, 'const')) {
165
+ return atom(literal(node.const));
166
+ }
167
+ if (Array.isArray(node.enum)) {
168
+ return union(node.enum.map((value) => atom(literal(value))));
169
+ }
170
+ const { type } = node;
171
+ if (Array.isArray(type)) {
172
+ return union(type.map((member) => printTyped(member, node, depth, active)));
173
+ }
174
+ if (typeof type === 'string') {
175
+ return printTyped(type, node, depth, active);
176
+ }
177
+ if (Object.hasOwn(node, 'properties') ||
178
+ Object.hasOwn(node, 'additionalProperties')) {
179
+ return printObject(node, depth, active);
180
+ }
181
+ if (Object.hasOwn(node, 'items') || Object.hasOwn(node, 'prefixItems')) {
182
+ return printArray(node, depth, active);
183
+ }
184
+ return undefined;
185
+ };
186
+ const printTyped = (type, node, depth, active) => {
187
+ switch (type) {
188
+ case 'string':
189
+ return atom('string');
190
+ case 'number':
191
+ case 'integer':
192
+ return atom('number');
193
+ case 'boolean':
194
+ return atom('boolean');
195
+ case 'null':
196
+ return atom('null');
197
+ case 'array':
198
+ return printArray(node, depth, active);
199
+ case 'object':
200
+ return printObject(node, depth, active);
201
+ default:
202
+ return atom('unknown');
203
+ }
204
+ };
205
+ const printArray = (node, depth, active) => {
206
+ const { prefixItems, items } = node;
207
+ if (Array.isArray(prefixItems)) {
208
+ const required = typeof node.minItems === 'number' ? node.minItems : 0;
209
+ const elements = prefixItems.map((item, index) => {
210
+ const printed = printNode(item, depth, active);
211
+ return index < required
212
+ ? printed.text
213
+ : `${printed.kind === 'atom' ? printed.text : `(${printed.text})`}?`;
214
+ });
215
+ if (items !== undefined && items !== false) {
216
+ elements.push(`...${arrayOf(printNode(items, depth, active)).text}`);
217
+ }
218
+ return atom(`[${elements.join(', ')}]`);
219
+ }
220
+ return arrayOf(items === undefined ? atom('unknown') : printNode(items, depth, active));
221
+ };
222
+ const printObject = (node, depth, active) => {
223
+ const properties = isJsonObject(node.properties) ? node.properties : {};
224
+ const lines = printMembers(node, depth, active, {});
225
+ const extra = node.additionalProperties;
226
+ const patterns = isJsonObject(node.patternProperties)
227
+ ? Object.values(node.patternProperties)
228
+ : [];
229
+ const open = extra !== false;
230
+ const values = [
231
+ ...patterns.map((schema) => printNode(schema, depth, active)),
232
+ ];
233
+ if (open)
234
+ values.push(extra === undefined || extra === true
235
+ ? atom('unknown')
236
+ : printNode(extra, depth, active));
237
+ const index = values.length === 0
238
+ ? Object.keys(properties).length === 0
239
+ ? `${INDENT.repeat(depth + 1)}[key: string]: never;\n`
240
+ : ''
241
+ : `${INDENT.repeat(depth + 1)}[key: string]: ${union([
242
+ ...values,
243
+ ...Object.values(properties).map((schema) => printNode(schema, depth, active)),
244
+ ...(Object.keys(properties).some((key) => !Array.isArray(node.required) || !node.required.includes(key))
245
+ ? [atom('undefined')]
246
+ : []),
247
+ ]).text};\n`;
248
+ return atom(`{\n${lines}${index}${INDENT.repeat(depth)}}`);
249
+ };
250
+ const printMembers = (node, depth, active, { omit, optional }) => {
251
+ const pad = INDENT.repeat(depth + 1);
252
+ const required = new Set(Array.isArray(node.required)
253
+ ? node.required.filter((key) => typeof key === 'string')
254
+ : []);
255
+ const properties = isJsonObject(node.properties) ? node.properties : {};
256
+ return Object.entries(properties)
257
+ .filter(([key]) => !omit?.has(key))
258
+ .map(([key, property]) => {
259
+ const doc = isJsonObject(property)
260
+ ? jsDoc([
261
+ typeof property.description === 'string'
262
+ ? property.description
263
+ : '',
264
+ ...(Object.hasOwn(property, 'default')
265
+ ? [`@default ${JSON.stringify(property.default)}`]
266
+ : []),
267
+ ], pad)
268
+ : '';
269
+ const mark = required.has(key) && !optional?.has(key) ? '' : '?';
270
+ return `${doc}${pad}${propertyKey(key)}${mark}: ${printNode(property, depth + 1, active).text};\n`;
271
+ })
272
+ .join('');
273
+ };
274
+ return {
275
+ print: (schema, depth = 0) => printNode(schema, depth, new Set()).text,
276
+ members: (schema, depth, options = {}) => printMembers(schema, depth, new Set(), options),
277
+ promoted: () => {
278
+ const aliases = [];
279
+ for (const [id, name] of promotedNames) {
280
+ aliases.push(`type ${name} = ${printNode(ownDef(defs, id), 0, new Set([id])).text};`);
281
+ }
282
+ return aliases;
283
+ },
284
+ };
285
+ };
286
+ //# sourceMappingURL=schema_to_typescript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema_to_typescript.js","sourceRoot":"","sources":["../../src/author/schema_to_typescript.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\nexport type JsonObject = Record<string, unknown>;\n\nexport const DEF_PREFIX = '#/$defs/';\n\n/** Ids `z.toJSONSchema` gives a def no one named. */\nexport const ANONYMOUS_DEF = /^__schema\\d+$/;\n\nconst STRUCTURAL_KEYS = [\n 'type',\n 'const',\n 'enum',\n 'properties',\n 'additionalProperties',\n 'patternProperties',\n 'propertyNames',\n 'items',\n 'prefixItems',\n 'oneOf',\n 'anyOf',\n 'allOf',\n] as const;\n\nconst INDENT = ' ';\n\nexport const IDENTIFIER = /^[A-Za-z_$][\\w$]*$/;\n\nexport const isJsonObject = (value: unknown): value is JsonObject =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nexport const parseDefRef = (ref: unknown): string | undefined =>\n typeof ref === 'string' && ref.startsWith(DEF_PREFIX)\n ? ref.slice(DEF_PREFIX.length)\n : undefined;\n\nexport const ownDef = (defs: JsonObject, id: string): unknown =>\n Object.hasOwn(defs, id) ? defs[id] : undefined;\n\n/** `slideStats` becomes `SlideStats`; anything but letters and digits splits words. */\nexport const pascalCase = (value: string): string => {\n const name = value\n .split(/[^A-Za-z0-9]+/)\n .filter(Boolean)\n .map((word) => `${word.slice(0, 1).toUpperCase()}${word.slice(1)}`)\n .join('');\n if (name === '') {\n return 'Type';\n }\n return /^\\d/.test(name) ? `_${name}` : name;\n};\n\n/** A JSDoc block for `lines`, or `''` when there are none. */\nexport const jsDoc = (lines: readonly string[], pad: string): string => {\n const text = lines\n .flatMap((line) => line.split('\\n'))\n .map((line) => line.replaceAll('*/', '*\\\\/').trimEnd());\n while (text[0] === '') {\n text.shift();\n }\n while (text.at(-1) === '') {\n text.pop();\n }\n if (text.length === 0) {\n return '';\n }\n const [only] = text;\n if (text.length === 1 && only !== undefined) {\n return `${pad}/** ${only} */\\n`;\n }\n return `${pad}/**\\n${text\n .map((line) => (line === '' ? `${pad} *` : `${pad} * ${line}`))\n .join('\\n')}\\n${pad} */\\n`;\n};\n\nconst propertyKey = (key: string): string =>\n IDENTIFIER.test(key) ? key : JSON.stringify(key);\n\nconst literal = (value: unknown): string => {\n if (value === null) {\n return 'null';\n }\n switch (typeof value) {\n case 'string':\n return JSON.stringify(value);\n case 'number':\n case 'boolean':\n return String(value);\n default:\n return 'unknown';\n }\n};\n\ninterface Printed {\n text: string;\n kind: 'atom' | 'union' | 'intersection';\n}\n\nconst atom = (text: string): Printed => ({ text, kind: 'atom' });\n\nconst union = (members: readonly Printed[]): Printed => {\n if (members.some(({ text }) => text === 'unknown')) return atom('unknown');\n const unique = new Map(members.map((member) => [member.text, member]));\n const [only] = [...unique.values()];\n if (unique.size === 0) {\n return atom('never');\n }\n return unique.size === 1 && only\n ? only\n : { text: [...unique.keys()].join(' | '), kind: 'union' };\n};\n\nconst intersection = (members: readonly Printed[]): Printed => {\n const unique = new Map(members.map((member) => [member.text, member]));\n const [only] = [...unique.values()];\n if (!only) return atom('unknown');\n if (unique.size === 1 && only) {\n return only;\n }\n return {\n text: [...unique.values()]\n .map(({ text, kind }) => (kind === 'union' ? `(${text})` : text))\n .join(' & '),\n kind: 'intersection',\n };\n};\n\nconst arrayOf = ({ text, kind }: Printed): Printed =>\n atom(kind === 'atom' ? `${text}[]` : `(${text})[]`);\n\n/** What {@link TypePrinter.members} prints and how. */\nexport interface MemberOptions {\n /** Properties left out. */\n omit?: ReadonlySet<string>;\n /** Properties printed optional whether or not the schema requires them. */\n optional?: ReadonlySet<string>;\n}\n\nexport interface TypePrinterOptions {\n defs: JsonObject;\n /** TypeScript names for defs printed by reference; every other def is inlined. */\n names: ReadonlyMap<string, string>;\n /** A fresh, unused name, for a def inlining cannot express. */\n claim: (base: string) => string;\n}\n\nexport interface TypePrinter {\n /** `schema` as a TypeScript type, written at `depth` levels of indent. */\n print: (schema: unknown, depth?: number) => string;\n /** The `key?: Type;` members of an object schema, with their JSDoc, at `depth + 1`. */\n members: (\n schema: JsonObject,\n depth: number,\n options?: MemberOptions\n ) => string;\n /** Type aliases for the anonymous defs that refer to themselves. Call last. */\n promoted: () => string[];\n}\n\n/** A TypeScript printer over the subset of JSON Schema `z.toJSONSchema` emits. */\nexport const createTypePrinter = ({\n defs,\n names,\n claim,\n}: TypePrinterOptions): TypePrinter => {\n const promotedNames = new Map<string, string>();\n\n const printRef = (\n id: string,\n depth: number,\n active: ReadonlySet<string>\n ): Printed => {\n const named = names.get(id);\n if (named !== undefined) {\n return atom(named);\n }\n const target = ownDef(defs, id);\n if (target === undefined) {\n return atom('unknown');\n }\n if (active.has(id)) {\n const name = promotedNames.get(id) ?? claim(pascalCase(id));\n promotedNames.set(id, name);\n return atom(name);\n }\n return printNode(target, depth, new Set([...active, id]));\n };\n\n const printNode = (\n node: unknown,\n depth: number,\n active: ReadonlySet<string>\n ): Printed => {\n if (node === false) {\n return atom('never');\n }\n if (!isJsonObject(node)) {\n return atom('unknown');\n }\n const parts: Printed[] = [];\n const ref = parseDefRef(node.$ref);\n if (ref !== undefined) {\n parts.push(printRef(ref, depth, active));\n }\n if (STRUCTURAL_KEYS.some((key) => Object.hasOwn(node, key))) {\n parts.push(printStructure(node, depth, active));\n }\n return parts.length === 0 ? atom('unknown') : intersection(parts);\n };\n\n const printStructure = (\n node: JsonObject,\n depth: number,\n active: ReadonlySet<string>\n ): Printed => {\n const parts: Printed[] = [];\n const own = printOwn(node, depth, active);\n if (own) {\n parts.push(own);\n }\n for (const key of ['oneOf', 'anyOf'] as const) {\n const members = node[key];\n if (Array.isArray(members)) {\n parts.push(\n union(members.map((member) => printNode(member, depth, active)))\n );\n }\n }\n if (Array.isArray(node.allOf)) {\n parts.push(\n intersection(\n node.allOf.map((member) => printNode(member, depth, active))\n )\n );\n }\n return parts.length === 0 ? atom('unknown') : intersection(parts);\n };\n\n // `undefined` when the node only combines other schemas.\n const printOwn = (\n node: JsonObject,\n depth: number,\n active: ReadonlySet<string>\n ): Printed | undefined => {\n if (Object.hasOwn(node, 'const')) {\n return atom(literal(node.const));\n }\n if (Array.isArray(node.enum)) {\n return union(node.enum.map((value) => atom(literal(value))));\n }\n const { type } = node;\n if (Array.isArray(type)) {\n return union(\n type.map((member) => printTyped(member, node, depth, active))\n );\n }\n if (typeof type === 'string') {\n return printTyped(type, node, depth, active);\n }\n if (\n Object.hasOwn(node, 'properties') ||\n Object.hasOwn(node, 'additionalProperties')\n ) {\n return printObject(node, depth, active);\n }\n if (Object.hasOwn(node, 'items') || Object.hasOwn(node, 'prefixItems')) {\n return printArray(node, depth, active);\n }\n return undefined;\n };\n\n const printTyped = (\n type: unknown,\n node: JsonObject,\n depth: number,\n active: ReadonlySet<string>\n ): Printed => {\n switch (type) {\n case 'string':\n return atom('string');\n case 'number':\n case 'integer':\n return atom('number');\n case 'boolean':\n return atom('boolean');\n case 'null':\n return atom('null');\n case 'array':\n return printArray(node, depth, active);\n case 'object':\n return printObject(node, depth, active);\n default:\n return atom('unknown');\n }\n };\n\n const printArray = (\n node: JsonObject,\n depth: number,\n active: ReadonlySet<string>\n ): Printed => {\n const { prefixItems, items } = node;\n if (Array.isArray(prefixItems)) {\n const required = typeof node.minItems === 'number' ? node.minItems : 0;\n const elements = prefixItems.map((item, index) => {\n const printed = printNode(item, depth, active);\n return index < required\n ? printed.text\n : `${printed.kind === 'atom' ? printed.text : `(${printed.text})`}?`;\n });\n if (items !== undefined && items !== false) {\n elements.push(`...${arrayOf(printNode(items, depth, active)).text}`);\n }\n return atom(`[${elements.join(', ')}]`);\n }\n return arrayOf(\n items === undefined ? atom('unknown') : printNode(items, depth, active)\n );\n };\n\n const printObject = (\n node: JsonObject,\n depth: number,\n active: ReadonlySet<string>\n ): Printed => {\n const properties = isJsonObject(node.properties) ? node.properties : {};\n const lines = printMembers(node, depth, active, {});\n const extra = node.additionalProperties;\n const patterns = isJsonObject(node.patternProperties)\n ? Object.values(node.patternProperties)\n : [];\n const open = extra !== false;\n const values = [\n ...patterns.map((schema) => printNode(schema, depth, active)),\n ];\n if (open)\n values.push(\n extra === undefined || extra === true\n ? atom('unknown')\n : printNode(extra, depth, active)\n );\n const index =\n values.length === 0\n ? Object.keys(properties).length === 0\n ? `${INDENT.repeat(depth + 1)}[key: string]: never;\\n`\n : ''\n : `${INDENT.repeat(depth + 1)}[key: string]: ${\n union([\n ...values,\n ...Object.values(properties).map((schema) =>\n printNode(schema, depth, active)\n ),\n ...(Object.keys(properties).some(\n (key) =>\n !Array.isArray(node.required) || !node.required.includes(key)\n )\n ? [atom('undefined')]\n : []),\n ]).text\n };\\n`;\n return atom(`{\\n${lines}${index}${INDENT.repeat(depth)}}`);\n };\n\n const printMembers = (\n node: JsonObject,\n depth: number,\n active: ReadonlySet<string>,\n { omit, optional }: MemberOptions\n ): string => {\n const pad = INDENT.repeat(depth + 1);\n const required = new Set(\n Array.isArray(node.required)\n ? node.required.filter((key) => typeof key === 'string')\n : []\n );\n const properties = isJsonObject(node.properties) ? node.properties : {};\n return Object.entries(properties)\n .filter(([key]) => !omit?.has(key))\n .map(([key, property]) => {\n const doc = isJsonObject(property)\n ? jsDoc(\n [\n typeof property.description === 'string'\n ? property.description\n : '',\n ...(Object.hasOwn(property, 'default')\n ? [`@default ${JSON.stringify(property.default)}`]\n : []),\n ],\n pad\n )\n : '';\n const mark = required.has(key) && !optional?.has(key) ? '' : '?';\n return `${doc}${pad}${propertyKey(key)}${mark}: ${\n printNode(property, depth + 1, active).text\n };\\n`;\n })\n .join('');\n };\n\n return {\n print: (schema, depth = 0) => printNode(schema, depth, new Set()).text,\n members: (schema, depth, options = {}) =>\n printMembers(schema, depth, new Set(), options),\n promoted: () => {\n const aliases: string[] = [];\n for (const [id, name] of promotedNames) {\n aliases.push(\n `type ${name} = ${printNode(ownDef(defs, id), 0, new Set([id])).text};`\n );\n }\n return aliases;\n },\n };\n};\n"]}
@@ -6,9 +6,11 @@
6
6
  * 2.0.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.readAuthoredSpec = exports.fromTextChildren = exports.authoredText = exports.authoredProps = exports.authoredChild = void 0;
9
+ exports.readAuthoredSpec = exports.fromTextChildren = exports.authoredToItem = exports.authoredText = exports.authoredProps = exports.authoredChild = void 0;
10
10
  exports.fromChildren = fromChildren;
11
+ const zod_1 = require("zod");
11
12
  const error_1 = require("../composition/error");
13
+ const authoring_input_1 = require("./authoring_input");
12
14
  /**
13
15
  * Child-element type a schema field is filled from.
14
16
  *
@@ -19,15 +21,18 @@ exports.authoredChild = Symbol.for('elastic.isomer.authored_child');
19
21
  exports.authoredProps = Symbol.for('elastic.isomer.authored_props');
20
22
  /** Set when a field is filled from text children. */
21
23
  exports.authoredText = Symbol.for('elastic.isomer.authored_text');
22
- const authoredToItem = Symbol.for('elastic.isomer.authored_to_item');
24
+ /** Holds a {@link fromChildren} brand's `toItem`. */
25
+ exports.authoredToItem = Symbol.for('elastic.isomer.authored_to_item');
23
26
  const authoredTextField = Symbol.for('elastic.isomer.authored_text_field');
24
27
  const authoredCollapse = Symbol.for('elastic.isomer.authored_collapse');
28
+ const authoredPropsSchema = Symbol.for('elastic.isomer.authored_props_schema');
25
29
  const BRANDS = [
26
30
  exports.authoredChild,
27
31
  authoredTextField,
28
- authoredToItem,
32
+ exports.authoredToItem,
29
33
  exports.authoredText,
30
34
  authoredCollapse,
35
+ authoredPropsSchema,
31
36
  ];
32
37
  // Applies a complete branding. Branding an instance again is allowed only with
33
38
  // the same configuration, absent options included, since both fields share it.
@@ -51,7 +56,8 @@ function fromChildren(childType, schema, options) {
51
56
  brand('fromChildren', schema, {
52
57
  [exports.authoredChild]: childType,
53
58
  [authoredTextField]: options?.text,
54
- [authoredToItem]: options?.toItem,
59
+ [exports.authoredToItem]: options?.toItem,
60
+ [authoredPropsSchema]: options?.propsSchema,
55
61
  });
56
62
  return schema;
57
63
  }
@@ -102,34 +108,63 @@ const isOptionalSchema = (schema) => {
102
108
  const type = zodDefType(schema);
103
109
  return type === 'optional' || type === 'default';
104
110
  };
105
- const schemaSignature = (schema, seen = new Set()) => {
106
- if (seen.has(schema)) {
107
- return 'cycle';
108
- }
109
- seen.add(schema);
110
- const type = zodDefType(schema) ?? '?';
111
- if (type === 'object' && 'shape' in schema) {
112
- const shape = schema.shape;
113
- const fields = Object.keys(shape)
114
- .sort()
115
- .map((key) => `${key}:${schemaSignature(shape[key], seen)}`);
116
- return `{${fields.join(',')}}`;
117
- }
118
- if (type === 'array' && 'element' in schema) {
119
- return `[${schemaSignature(schema.element, seen)}]`;
120
- }
121
- const inner = innerSchema(schema);
122
- if (inner) {
123
- return `${type}(${schemaSignature(inner, seen)})`;
124
- }
125
- return type;
111
+ const UNORDERED_SCHEMA_ARRAYS = new Set([
112
+ 'allOf',
113
+ 'anyOf',
114
+ 'enum',
115
+ 'oneOf',
116
+ 'required',
117
+ 'type',
118
+ ]);
119
+ const schemaSignature = (schema) => {
120
+ const { schema: input } = (0, authoring_input_1.prepareAuthoringInput)(schema);
121
+ const projected = zod_1.z.toJSONSchema(input, {
122
+ io: 'input',
123
+ target: 'draft-2020-12',
124
+ cycles: 'ref',
125
+ reused: 'inline',
126
+ unrepresentable: 'any',
127
+ metadata: zod_1.z.registry(),
128
+ });
129
+ const active = new Map();
130
+ const canonical = (value, key = '') => {
131
+ if (Array.isArray(value)) {
132
+ const members = value.map((member) => canonical(member));
133
+ if (UNORDERED_SCHEMA_ARRAYS.has(key))
134
+ members.sort();
135
+ return `[${members.join(',')}]`;
136
+ }
137
+ if (typeof value !== 'object' || value === null) {
138
+ return JSON.stringify(value) ?? 'undefined';
139
+ }
140
+ const cycle = active.get(value);
141
+ if (cycle !== undefined)
142
+ return `cycle:${cycle}`;
143
+ const object = value;
144
+ const ref = object.$ref;
145
+ const target = ref === '#'
146
+ ? projected
147
+ : typeof ref === 'string' && ref.startsWith('#/$defs/')
148
+ ? projected.$defs?.[ref.slice('#/$defs/'.length)]
149
+ : undefined;
150
+ if (target && Object.keys(object).length === 1)
151
+ return canonical(target);
152
+ active.set(value, active.size);
153
+ const result = `{${Object.entries(object)
154
+ .filter(([key]) => value !== projected || key !== '$defs')
155
+ .sort(([first], [second]) => first.localeCompare(second))
156
+ .map(([key, member]) => `${JSON.stringify(key)}:${canonical(key === '$ref' && target ? target : member, key)}`)
157
+ .join(',')}}`;
158
+ active.delete(value);
159
+ return result;
160
+ };
161
+ return canonical(projected);
126
162
  };
127
163
  const arrayElement = (schema) => {
128
164
  const inner = unwrapAll(schema);
129
- if (zodDefType(inner) === 'array' && 'element' in inner) {
130
- return inner.element;
131
- }
132
- return inner;
165
+ return zodDefType(inner) === 'array' && 'element' in inner
166
+ ? inner.element
167
+ : undefined;
133
168
  };
134
169
  const readChild = (field, schema) => {
135
170
  const holder = brandHolder(schema, exports.authoredChild);
@@ -138,14 +173,20 @@ const readChild = (field, schema) => {
138
173
  return undefined;
139
174
  }
140
175
  const textField = holder[authoredTextField];
141
- const toItem = holder[authoredToItem];
176
+ const toItem = holder[exports.authoredToItem];
177
+ const propsSchema = holder[authoredPropsSchema];
178
+ const element = arrayElement(holder);
179
+ const itemSchema = element ?? unwrapAll(holder);
142
180
  const child = {
143
181
  field,
144
182
  childType,
145
- itemSchema: arrayElement(holder),
183
+ itemSchema,
184
+ array: element !== undefined,
146
185
  optional: optionalThrough(schema),
147
- signature: schemaSignature(arrayElement(holder)),
186
+ signature: `${schemaSignature(itemSchema)}|${typeof textField === 'string' ? textField : ''}|${propsSchema ? schemaSignature(propsSchema) : ''}`,
148
187
  };
188
+ if (propsSchema)
189
+ child.propsSchema = propsSchema;
149
190
  if (typeof textField === 'string') {
150
191
  child.textField = textField;
151
192
  }
@@ -165,7 +206,10 @@ const readText = (field, schema) => {
165
206
  optional: optionalThrough(schema),
166
207
  };
167
208
  };
168
- /** Top-level branded fields on an object schema. Nested brands stay on the item schema. */
209
+ /**
210
+ * The branded fields on an object schema, top level only: read a child's own
211
+ * brands from its {@link AuthoredChildField.itemSchema}.
212
+ */
169
213
  const readAuthoredSpec = (schema) => {
170
214
  if (zodDefType(schema) !== 'object' || !('shape' in schema)) {
171
215
  return { children: [], text: [] };
@@ -1 +1 @@
1
- {"version":3,"file":"authored_fields.js","sourceRoot":"","sources":["../../../src/author/authored_fields.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 type { ReactNode } from 'react';\nimport type { ZodType } from 'zod';\n\nimport { ISOMER_ERROR_CODES, IsomerError } from '../composition/error';\nimport type { PrimitiveNode } from '../define/primitive_module';\n\n/**\n * Child-element type a schema field is filled from.\n *\n * `Symbol.for`: ESM and CJS builds must agree, same as `authorType`.\n */\nexport const authoredChild = Symbol.for('elastic.isomer.authored_child');\n\n/** Phantom props type for the child component. Not set at runtime. */\nexport const authoredProps = Symbol.for('elastic.isomer.authored_props');\n\n/** Set when a field is filled from text children. */\nexport const authoredText = Symbol.for('elastic.isomer.authored_text');\n\nconst authoredToItem = Symbol.for('elastic.isomer.authored_to_item');\nconst authoredTextField = Symbol.for('elastic.isomer.authored_text_field');\nconst authoredCollapse = Symbol.for('elastic.isomer.authored_collapse');\n\n/**\n * A field filled from child elements of `TName`.\n *\n * Phantom: `z.infer` still reads the underlying schema. The shim reads `TName`\n * and `TProps` off the field type, and the symbols off the schema value.\n */\nexport interface AuthoredChildBrand<TName extends string, TProps> {\n readonly [authoredChild]: TName;\n readonly [authoredProps]: TProps;\n}\n\n/** A field filled from text children. */\nexport interface AuthoredTextBrand {\n readonly [authoredText]: true;\n}\n\n/** What {@link fromChildren}'s `toItem` receives. */\nexport interface AuthorChildContext {\n /** Nested elements, parsed as body nodes. */\n parseChildren: (children: ReactNode) => PrimitiveNode[];\n}\n\ntype ArrayItem<TSchema extends ZodType> =\n NonNullable<zOutput<TSchema>> extends readonly (infer Item)[]\n ? Item\n : NonNullable<zOutput<TSchema>>;\n\ntype zOutput<TSchema> = TSchema extends { _zod: { output: infer Output } }\n ? Output\n : never;\n\n/** `TText` is optional on the child props because leftover text fills it. */\ntype ChildProps<TItem, TText extends string | undefined> = [TText] extends [\n string,\n]\n ? Omit<TItem, TText> &\n Partial<Pick<TItem, Extract<TText, keyof TItem>>> & {\n children?: ReactNode;\n }\n : TItem & { children?: ReactNode };\n\nconst BRANDS = [\n authoredChild,\n authoredTextField,\n authoredToItem,\n authoredText,\n authoredCollapse,\n] as const;\n\n// Applies a complete branding. Branding an instance again is allowed only with\n// the same configuration, absent options included, since both fields share it.\nconst brand = (\n caller: 'fromChildren' | 'fromTextChildren',\n schema: object,\n config: Partial<Record<(typeof BRANDS)[number], unknown>>\n): void => {\n const record = schema as Record<symbol, unknown>;\n if (BRANDS.some((key) => Object.hasOwn(schema, key))) {\n if (BRANDS.every((key) => record[key] === config[key])) return;\n throw new IsomerError(\n ISOMER_ERROR_CODES.AUTHORED_SCHEMA_REUSED,\n `${caller}: this schema instance is already branded another way; pass each field its own schema.`\n );\n }\n for (const key of BRANDS) {\n if (config[key] !== undefined) {\n Object.defineProperty(schema, key, {\n value: config[key],\n enumerable: false,\n });\n }\n }\n};\n\n/**\n * Brands `schema` as JSX children of `childType`.\n *\n * `options.text` copies leftover text onto that field. `options.toItem` replaces\n * the default prop copy; its props annotation is the child component's props.\n * The brand is read through `.optional()`, `.nullable()`, `.default()`, and\n * `.readonly()`; any other method clones without it, so call it on `schema`\n * before passing it in.\n */\nexport function fromChildren<\n const TName extends string,\n TSchema extends ZodType,\n>(\n childType: TName,\n schema: TSchema\n): TSchema &\n AuthoredChildBrand<TName, ChildProps<ArrayItem<TSchema>, undefined>>;\nexport function fromChildren<\n const TName extends string,\n TSchema extends ZodType,\n const TText extends string,\n>(\n childType: TName,\n schema: TSchema,\n options: { text: TText }\n): TSchema & AuthoredChildBrand<TName, ChildProps<ArrayItem<TSchema>, TText>>;\nexport function fromChildren<\n const TName extends string,\n TSchema extends ZodType,\n TProps,\n>(\n childType: TName,\n schema: TSchema,\n options: {\n text?: string;\n toItem(props: TProps, context: AuthorChildContext): unknown;\n }\n): TSchema & AuthoredChildBrand<TName, TProps>;\nexport function fromChildren(\n childType: string,\n schema: ZodType,\n options?: {\n text?: string;\n toItem?: (this: void, props: never, context: AuthorChildContext) => unknown;\n }\n): ZodType {\n brand('fromChildren', schema, {\n [authoredChild]: childType,\n [authoredTextField]: options?.text,\n [authoredToItem]: options?.toItem,\n });\n return schema;\n}\n\n/**\n * Brands `schema` as text children.\n *\n * Whitespace collapses unless `collapseWhitespace` is `false`.\n */\nexport const fromTextChildren = <TSchema extends ZodType>(\n schema: TSchema,\n options?: { collapseWhitespace?: boolean }\n): TSchema & AuthoredTextBrand => {\n brand('fromTextChildren', schema, {\n [authoredText]: true,\n [authoredCollapse]:\n options?.collapseWhitespace === false ? false : undefined,\n });\n return schema as TSchema & AuthoredTextBrand;\n};\n\n/** One {@link fromChildren} field as the shim reads it. */\nexport interface AuthoredChildField {\n field: string;\n childType: string;\n /** Field leftover text children fill. */\n textField?: string;\n /** Replaces the default prop copy. */\n toItem?: (props: object, context: AuthorChildContext) => unknown;\n /** The array element schema, or the field schema itself when it is not an array. */\n itemSchema: ZodType;\n /** Whether the field accepts `undefined`, so children may be omitted. */\n optional: boolean;\n /** Structural fingerprint of `itemSchema`; every field branding one child type must share it. */\n signature: string;\n}\n\n/** One {@link fromTextChildren} field as the shim reads it. */\nexport interface AuthoredTextField {\n field: string;\n /** `true` unless the brand was given `collapseWhitespace: false`. */\n collapseWhitespace: boolean;\n /** Whether the field accepts `undefined`, so text children may be omitted. */\n optional: boolean;\n}\n\n/** The branded fields found on one object schema. */\nexport interface AuthoredSpec {\n children: AuthoredChildField[];\n text: AuthoredTextField[];\n}\n\nconst zodDefType = (schema: object): string | undefined =>\n (schema as { _zod?: { def?: { type?: string } } })._zod?.def?.type;\n\nconst WRAPPER_TYPES = new Set(['optional', 'nullable', 'default', 'readonly']);\n\ninterface WrapperDef {\n type?: string;\n innerType?: ZodType;\n}\n\nconst innerSchema = (schema: ZodType): ZodType | undefined => {\n const def: WrapperDef | undefined = (\n schema as { _zod?: { def?: WrapperDef } }\n )._zod?.def;\n return def?.type && WRAPPER_TYPES.has(def.type) ? def.innerType : undefined;\n};\n\n// The schema holding `brand`: `schema` or one it wraps.\nconst brandHolder = (schema: ZodType, key: symbol): ZodType | undefined => {\n let current: ZodType | undefined = schema;\n while (current && !Object.hasOwn(current, key)) {\n current = innerSchema(current);\n }\n return current;\n};\n\n// Whether any wrapper layer of `schema` accepts `undefined`.\nconst optionalThrough = (schema: ZodType): boolean => {\n for (\n let current: ZodType | undefined = schema;\n current;\n current = innerSchema(current)\n ) {\n if (isOptionalSchema(current)) return true;\n }\n return false;\n};\n\nconst unwrapAll = (schema: ZodType): ZodType => {\n let current = schema;\n for (let inner = innerSchema(current); inner; inner = innerSchema(current)) {\n current = inner;\n }\n return current;\n};\n\n/** `undefined` is a valid value, so children may be omitted. */\nconst isOptionalSchema = (schema: ZodType): boolean => {\n const type = zodDefType(schema);\n return type === 'optional' || type === 'default';\n};\n\nconst schemaSignature = (\n schema: ZodType,\n seen: Set<object> = new Set()\n): string => {\n if (seen.has(schema)) {\n return 'cycle';\n }\n seen.add(schema);\n const type = zodDefType(schema) ?? '?';\n if (type === 'object' && 'shape' in schema) {\n const shape = schema.shape as Record<string, ZodType>;\n const fields = Object.keys(shape)\n .sort()\n .map((key) => `${key}:${schemaSignature(shape[key] as ZodType, seen)}`);\n return `{${fields.join(',')}}`;\n }\n if (type === 'array' && 'element' in schema) {\n return `[${schemaSignature((schema as { element: ZodType }).element, seen)}]`;\n }\n const inner = innerSchema(schema);\n if (inner) {\n return `${type}(${schemaSignature(inner, seen)})`;\n }\n return type;\n};\n\nconst arrayElement = (schema: ZodType): ZodType => {\n const inner = unwrapAll(schema);\n if (zodDefType(inner) === 'array' && 'element' in inner) {\n return (inner as { element: ZodType }).element;\n }\n return inner;\n};\n\nconst readChild = (\n field: string,\n schema: ZodType\n): AuthoredChildField | undefined => {\n const holder = brandHolder(schema, authoredChild);\n const childType = (holder as { [authoredChild]?: unknown } | undefined)?.[\n authoredChild\n ];\n if (!holder || typeof childType !== 'string') {\n return undefined;\n }\n const textField = (holder as { [authoredTextField]?: unknown })[\n authoredTextField\n ];\n const toItem = (holder as { [authoredToItem]?: unknown })[authoredToItem];\n const child: AuthoredChildField = {\n field,\n childType,\n itemSchema: arrayElement(holder),\n optional: optionalThrough(schema),\n signature: schemaSignature(arrayElement(holder)),\n };\n if (typeof textField === 'string') {\n child.textField = textField;\n }\n if (typeof toItem === 'function') {\n child.toItem = toItem as (\n props: object,\n context: AuthorChildContext\n ) => unknown;\n }\n return child;\n};\n\nconst readText = (\n field: string,\n schema: ZodType\n): AuthoredTextField | undefined => {\n const holder = brandHolder(schema, authoredText);\n if (!holder) {\n return undefined;\n }\n return {\n field,\n collapseWhitespace:\n (holder as { [authoredCollapse]?: unknown })[authoredCollapse] !== false,\n optional: optionalThrough(schema),\n };\n};\n\n/** Top-level branded fields on an object schema. Nested brands stay on the item schema. */\nexport const readAuthoredSpec = (schema: ZodType): AuthoredSpec => {\n if (zodDefType(schema) !== 'object' || !('shape' in schema)) {\n return { children: [], text: [] };\n }\n const children: AuthoredChildField[] = [];\n const text: AuthoredTextField[] = [];\n for (const [field, fieldSchema] of Object.entries(\n schema.shape as Record<string, ZodType>\n )) {\n const child = readChild(field, fieldSchema);\n if (child) {\n children.push(child);\n continue;\n }\n const textField = readText(field, fieldSchema);\n if (textField) {\n text.push(textField);\n }\n }\n return { children, text };\n};\n"]}
1
+ {"version":3,"file":"authored_fields.js","sourceRoot":"","sources":["../../../src/author/authored_fields.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 type { ReactNode } from 'react';\nimport { z, type ZodType } from 'zod';\n\nimport { ISOMER_ERROR_CODES, IsomerError } from '../composition/error';\nimport type { PrimitiveNode } from '../define/primitive_module';\n\nimport { prepareAuthoringInput } from './authoring_input';\n\n/**\n * Child-element type a schema field is filled from.\n *\n * `Symbol.for`: ESM and CJS builds must agree, same as `authorType`.\n */\nexport const authoredChild = Symbol.for('elastic.isomer.authored_child');\n\n/** Phantom props type for the child component. Not set at runtime. */\nexport const authoredProps = Symbol.for('elastic.isomer.authored_props');\n\n/** Set when a field is filled from text children. */\nexport const authoredText = Symbol.for('elastic.isomer.authored_text');\n\n/** Holds a {@link fromChildren} brand's `toItem`. */\nexport const authoredToItem = Symbol.for('elastic.isomer.authored_to_item');\nconst authoredTextField = Symbol.for('elastic.isomer.authored_text_field');\nconst authoredCollapse = Symbol.for('elastic.isomer.authored_collapse');\nconst authoredPropsSchema = Symbol.for('elastic.isomer.authored_props_schema');\n\n/**\n * A field filled from child elements of `TName`.\n *\n * Phantom: `z.infer` still reads the underlying schema. The shim reads `TName`\n * and `TProps` off the field type, and the symbols off the schema value.\n */\nexport interface AuthoredChildBrand<TName extends string, TProps> {\n readonly [authoredChild]: TName;\n readonly [authoredProps]: TProps;\n}\n\n/** A child field whose `toItem` builds each item, so the shim fills none of the item's own brands. */\nexport interface AuthoredToItemBrand {\n readonly [authoredToItem]: (\n props: never,\n context: AuthorChildContext\n ) => unknown;\n}\n\n/** A field filled from text children. */\nexport interface AuthoredTextBrand {\n readonly [authoredText]: true;\n}\n\n/** What {@link fromChildren}'s `toItem` receives. */\nexport interface AuthorChildContext {\n /** Nested elements, parsed as body nodes. */\n parseChildren: (children: ReactNode) => PrimitiveNode[];\n}\n\ntype ArrayItem<TSchema extends ZodType> =\n NonNullable<zOutput<TSchema>> extends readonly (infer Item)[]\n ? Item\n : NonNullable<zOutput<TSchema>>;\n\ntype zInput<TSchema> = TSchema extends { _zod: { input: infer Input } }\n ? Input\n : never;\n\ntype zOutput<TSchema> = TSchema extends { _zod: { output: infer Output } }\n ? Output\n : never;\n\ntype WrapperOf<TInner> = {\n _zod: {\n def: {\n type: 'optional' | 'nullable' | 'default' | 'readonly';\n innerType: TInner;\n };\n };\n};\n\ntype Unwrapped<TSchema> =\n TSchema extends WrapperOf<infer Inner> ? Unwrapped<Inner> : TSchema;\n\n/** Whether `F`, or a wrapper layer of it, carries a {@link fromChildren} brand. */\ntype IsChildBranded<F> =\n F extends AuthoredChildBrand<string, unknown>\n ? true\n : F extends WrapperOf<infer Inner>\n ? IsChildBranded<Inner>\n : false;\n\n/** A branded field's item schema: the array element through any wrapper, or the unwrapped schema. */\nexport type ItemSchema<TSchema> =\n Unwrapped<TSchema> extends { element: infer Element }\n ? Element\n : Unwrapped<TSchema>;\n\n/** Item fields a nested {@link fromChildren} brand fills from child elements. */\ntype ChildBrandedKeys<TItemSchema> = TItemSchema extends {\n shape: infer Shape;\n}\n ? string extends keyof Shape\n ? never\n : {\n [K in keyof Shape]: IsChildBranded<Shape[K]> extends true ? K : never;\n }[keyof Shape]\n : never;\n\n/** `TOptional` is optional on the child props because text or child elements fill it. */\ntype ChildProps<TItem, TOptional extends PropertyKey> = [TOptional] extends [\n never,\n]\n ? TItem & { children?: ReactNode }\n : Omit<TItem, TOptional> &\n Partial<Pick<TItem, Extract<TOptional, keyof TItem>>> & {\n children?: ReactNode;\n };\n\nconst BRANDS = [\n authoredChild,\n authoredTextField,\n authoredToItem,\n authoredText,\n authoredCollapse,\n authoredPropsSchema,\n] as const;\n\n// Applies a complete branding. Branding an instance again is allowed only with\n// the same configuration, absent options included, since both fields share it.\nconst brand = (\n caller: 'fromChildren' | 'fromTextChildren',\n schema: object,\n config: Partial<Record<(typeof BRANDS)[number], unknown>>\n): void => {\n const record = schema as Record<symbol, unknown>;\n if (BRANDS.some((key) => Object.hasOwn(schema, key))) {\n if (BRANDS.every((key) => record[key] === config[key])) return;\n throw new IsomerError(\n ISOMER_ERROR_CODES.AUTHORED_SCHEMA_REUSED,\n `${caller}: this schema instance is already branded another way; pass each field its own schema.`\n );\n }\n for (const key of BRANDS) {\n if (config[key] !== undefined) {\n Object.defineProperty(schema, key, {\n value: config[key],\n enumerable: false,\n });\n }\n }\n};\n\n/**\n * Brands `schema` as JSX children of `childType`.\n *\n * `options.text` copies leftover text onto that field. `options.toItem` replaces\n * the default prop copy; its props annotation is the child component's props.\n * The brand is read through `.optional()`, `.nullable()`, `.default()`, and\n * `.readonly()`; any other method clones without it, so call it on `schema`\n * before passing it in.\n */\nexport function fromChildren<\n const TName extends string,\n TSchema extends ZodType,\n>(\n childType: TName,\n schema: TSchema\n): TSchema &\n AuthoredChildBrand<\n TName,\n ChildProps<ArrayItem<TSchema>, ChildBrandedKeys<ItemSchema<TSchema>>>\n >;\nexport function fromChildren<\n const TName extends string,\n TSchema extends ZodType,\n const TText extends string,\n>(\n childType: TName,\n schema: TSchema,\n options: { text: TText; toItem?: never }\n): TSchema &\n AuthoredChildBrand<\n TName,\n ChildProps<\n ArrayItem<TSchema>,\n TText | ChildBrandedKeys<ItemSchema<TSchema>>\n >\n >;\nexport function fromChildren<\n const TName extends string,\n TSchema extends ZodType,\n TPropsSchema extends ZodType,\n>(\n childType: TName,\n schema: TSchema,\n options: {\n text?: string;\n propsSchema: TPropsSchema;\n toItem(\n props: zInput<TPropsSchema> & { children?: ReactNode },\n context: AuthorChildContext\n ): unknown;\n }\n): TSchema &\n AuthoredChildBrand<TName, zInput<TPropsSchema> & { children?: ReactNode }> &\n AuthoredToItemBrand;\nexport function fromChildren<\n const TName extends string,\n TSchema extends ZodType,\n TProps,\n>(\n childType: TName,\n schema: TSchema,\n options: {\n text?: string;\n toItem(props: TProps, context: AuthorChildContext): unknown;\n propsSchema?: never;\n }\n): TSchema & AuthoredChildBrand<TName, TProps> & AuthoredToItemBrand;\nexport function fromChildren(\n childType: string,\n schema: ZodType,\n options?: {\n text?: string;\n toItem?: (this: void, props: never, context: AuthorChildContext) => unknown;\n propsSchema?: ZodType;\n }\n): ZodType {\n brand('fromChildren', schema, {\n [authoredChild]: childType,\n [authoredTextField]: options?.text,\n [authoredToItem]: options?.toItem,\n [authoredPropsSchema]: options?.propsSchema,\n });\n return schema;\n}\n\n/**\n * Brands `schema` as text children.\n *\n * Whitespace collapses unless `collapseWhitespace` is `false`.\n */\nexport const fromTextChildren = <TSchema extends ZodType>(\n schema: TSchema,\n options?: { collapseWhitespace?: boolean }\n): TSchema & AuthoredTextBrand => {\n brand('fromTextChildren', schema, {\n [authoredText]: true,\n [authoredCollapse]:\n options?.collapseWhitespace === false ? false : undefined,\n });\n return schema as TSchema & AuthoredTextBrand;\n};\n\n/** One {@link fromChildren} field as the shim reads it. */\nexport interface AuthoredChildField {\n field: string;\n childType: string;\n /** Field leftover text children fill. */\n textField?: string;\n /** Replaces the default prop copy. */\n toItem?: (props: object, context: AuthorChildContext) => unknown;\n /** The array element schema, or the field schema itself when it is not an array. */\n itemSchema: ZodType;\n /** Input props for a custom `toItem`, excluding JSX children. */\n propsSchema?: ZodType;\n /** Whether the field holds an array of items rather than one item. */\n array: boolean;\n /** Whether the field accepts `undefined`, so children may be omitted. */\n optional: boolean;\n /** Structural input-schema fingerprint shared by fields branding one child type. */\n signature: string;\n}\n\n/** One {@link fromTextChildren} field as the shim reads it. */\nexport interface AuthoredTextField {\n field: string;\n /** `true` unless the brand was given `collapseWhitespace: false`. */\n collapseWhitespace: boolean;\n /** Whether the field accepts `undefined`, so text children may be omitted. */\n optional: boolean;\n}\n\n/** The branded fields found on one object schema. */\nexport interface AuthoredSpec {\n children: AuthoredChildField[];\n text: AuthoredTextField[];\n}\n\nconst zodDefType = (schema: object): string | undefined =>\n (schema as { _zod?: { def?: { type?: string } } })._zod?.def?.type;\n\nconst WRAPPER_TYPES = new Set(['optional', 'nullable', 'default', 'readonly']);\n\ninterface WrapperDef {\n type?: string;\n innerType?: ZodType;\n}\n\nconst innerSchema = (schema: ZodType): ZodType | undefined => {\n const def: WrapperDef | undefined = (\n schema as { _zod?: { def?: WrapperDef } }\n )._zod?.def;\n return def?.type && WRAPPER_TYPES.has(def.type) ? def.innerType : undefined;\n};\n\n// The schema holding `brand`: `schema` or one it wraps.\nconst brandHolder = (schema: ZodType, key: symbol): ZodType | undefined => {\n let current: ZodType | undefined = schema;\n while (current && !Object.hasOwn(current, key)) {\n current = innerSchema(current);\n }\n return current;\n};\n\n// Whether any wrapper layer of `schema` accepts `undefined`.\nconst optionalThrough = (schema: ZodType): boolean => {\n for (\n let current: ZodType | undefined = schema;\n current;\n current = innerSchema(current)\n ) {\n if (isOptionalSchema(current)) return true;\n }\n return false;\n};\n\nconst unwrapAll = (schema: ZodType): ZodType => {\n let current = schema;\n for (let inner = innerSchema(current); inner; inner = innerSchema(current)) {\n current = inner;\n }\n return current;\n};\n\n/** `undefined` is a valid value, so children may be omitted. */\nconst isOptionalSchema = (schema: ZodType): boolean => {\n const type = zodDefType(schema);\n return type === 'optional' || type === 'default';\n};\n\nconst UNORDERED_SCHEMA_ARRAYS = new Set([\n 'allOf',\n 'anyOf',\n 'enum',\n 'oneOf',\n 'required',\n 'type',\n]);\n\nconst schemaSignature = (schema: ZodType): string => {\n const { schema: input } = prepareAuthoringInput(schema);\n const projected = z.toJSONSchema(input, {\n io: 'input',\n target: 'draft-2020-12',\n cycles: 'ref',\n reused: 'inline',\n unrepresentable: 'any',\n metadata: z.registry(),\n });\n const active = new Map<object, number>();\n const canonical = (value: unknown, key = ''): string => {\n if (Array.isArray(value)) {\n const members = value.map((member) => canonical(member));\n if (UNORDERED_SCHEMA_ARRAYS.has(key)) members.sort();\n return `[${members.join(',')}]`;\n }\n if (typeof value !== 'object' || value === null) {\n return JSON.stringify(value) ?? 'undefined';\n }\n const cycle = active.get(value);\n if (cycle !== undefined) return `cycle:${cycle}`;\n const object = value as Record<string, unknown>;\n const ref = object.$ref;\n const target =\n ref === '#'\n ? projected\n : typeof ref === 'string' && ref.startsWith('#/$defs/')\n ? projected.$defs?.[ref.slice('#/$defs/'.length)]\n : undefined;\n if (target && Object.keys(object).length === 1) return canonical(target);\n active.set(value, active.size);\n const result = `{${Object.entries(object)\n .filter(([key]) => value !== projected || key !== '$defs')\n .sort(([first], [second]) => first.localeCompare(second))\n .map(\n ([key, member]) =>\n `${JSON.stringify(key)}:${canonical(key === '$ref' && target ? target : member, key)}`\n )\n .join(',')}}`;\n active.delete(value);\n return result;\n };\n return canonical(projected);\n};\n\nconst arrayElement = (schema: ZodType): ZodType | undefined => {\n const inner = unwrapAll(schema);\n return zodDefType(inner) === 'array' && 'element' in inner\n ? (inner as { element: ZodType }).element\n : undefined;\n};\n\nconst readChild = (\n field: string,\n schema: ZodType\n): AuthoredChildField | undefined => {\n const holder = brandHolder(schema, authoredChild);\n const childType = (holder as { [authoredChild]?: unknown } | undefined)?.[\n authoredChild\n ];\n if (!holder || typeof childType !== 'string') {\n return undefined;\n }\n const textField = (holder as { [authoredTextField]?: unknown })[\n authoredTextField\n ];\n const toItem = (holder as { [authoredToItem]?: unknown })[authoredToItem];\n const propsSchema = (holder as { [authoredPropsSchema]?: ZodType })[\n authoredPropsSchema\n ];\n const element = arrayElement(holder);\n const itemSchema = element ?? unwrapAll(holder);\n const child: AuthoredChildField = {\n field,\n childType,\n itemSchema,\n array: element !== undefined,\n optional: optionalThrough(schema),\n signature: `${schemaSignature(itemSchema)}|${typeof textField === 'string' ? textField : ''}|${propsSchema ? schemaSignature(propsSchema) : ''}`,\n };\n if (propsSchema) child.propsSchema = propsSchema;\n if (typeof textField === 'string') {\n child.textField = textField;\n }\n if (typeof toItem === 'function') {\n child.toItem = toItem as (\n props: object,\n context: AuthorChildContext\n ) => unknown;\n }\n return child;\n};\n\nconst readText = (\n field: string,\n schema: ZodType\n): AuthoredTextField | undefined => {\n const holder = brandHolder(schema, authoredText);\n if (!holder) {\n return undefined;\n }\n return {\n field,\n collapseWhitespace:\n (holder as { [authoredCollapse]?: unknown })[authoredCollapse] !== false,\n optional: optionalThrough(schema),\n };\n};\n\n/**\n * The branded fields on an object schema, top level only: read a child's own\n * brands from its {@link AuthoredChildField.itemSchema}.\n */\nexport const readAuthoredSpec = (schema: ZodType): AuthoredSpec => {\n if (zodDefType(schema) !== 'object' || !('shape' in schema)) {\n return { children: [], text: [] };\n }\n const children: AuthoredChildField[] = [];\n const text: AuthoredTextField[] = [];\n for (const [field, fieldSchema] of Object.entries(\n schema.shape as Record<string, ZodType>\n )) {\n const child = readChild(field, fieldSchema);\n if (child) {\n children.push(child);\n continue;\n }\n const textField = readText(field, fieldSchema);\n if (textField) {\n text.push(textField);\n }\n }\n return { children, text };\n};\n"]}