@elastic/isomer-sdk 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.txt +0 -286
- package/README.md +13 -2
- package/THIRD_PARTY_LICENSES.md +1 -885
- package/dist/author/authored_fields.d.ts +93 -18
- package/dist/author/authored_fields.d.ts.map +1 -1
- package/dist/author/authored_fields.js +63 -43
- package/dist/author/authored_fields.js.map +1 -1
- package/dist/author/authoring_input.d.ts +7 -0
- package/dist/author/authoring_input.d.ts.map +1 -0
- package/dist/author/authoring_input.js +66 -0
- package/dist/author/authoring_input.js.map +1 -0
- package/dist/author/authoring_model.d.ts +33 -0
- package/dist/author/authoring_model.d.ts.map +1 -0
- package/dist/author/authoring_model.js +142 -0
- package/dist/author/authoring_model.js.map +1 -0
- package/dist/author/declarations.d.ts +13 -0
- package/dist/author/declarations.d.ts.map +1 -0
- package/dist/author/declarations.js +288 -0
- package/dist/author/declarations.js.map +1 -0
- package/dist/author/index.d.ts +4 -1
- package/dist/author/index.d.ts.map +1 -1
- package/dist/author/index.js +4 -1
- package/dist/author/index.js.map +1 -1
- package/dist/author/jsx_shim.d.ts +50 -30
- package/dist/author/jsx_shim.d.ts.map +1 -1
- package/dist/author/jsx_shim.js +146 -138
- 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 +37 -0
- package/dist/author/schema_to_typescript.d.ts.map +1 -0
- package/dist/author/schema_to_typescript.js +289 -0
- package/dist/author/schema_to_typescript.js.map +1 -0
- package/dist/cjs/author/authored_fields.js +68 -47
- package/dist/cjs/author/authored_fields.js.map +1 -1
- package/dist/cjs/author/authoring_input.js +70 -0
- package/dist/cjs/author/authoring_input.js.map +1 -0
- package/dist/cjs/author/authoring_model.js +149 -0
- package/dist/cjs/author/authoring_model.js.map +1 -0
- package/dist/cjs/author/declarations.js +292 -0
- package/dist/cjs/author/declarations.js.map +1 -0
- package/dist/cjs/author/index.js +10 -1
- package/dist/cjs/author/index.js.map +1 -1
- package/dist/cjs/author/jsx_shim.js +148 -140
- 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 +298 -0
- package/dist/cjs/author/schema_to_typescript.js.map +1 -0
- package/dist/cjs/composition/body_node_base.js +11 -4
- package/dist/cjs/composition/body_node_base.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/index.js +2 -1
- package/dist/cjs/composition/index.js.map +1 -1
- package/dist/cjs/composition/structured_value.js.map +1 -1
- package/dist/cjs/define/frame.js +2 -3
- package/dist/cjs/define/frame.js.map +1 -1
- package/dist/cjs/define/index.js +7 -1
- package/dist/cjs/define/index.js.map +1 -1
- package/dist/cjs/define/primitive_example.js +26 -0
- package/dist/cjs/define/primitive_example.js.map +1 -0
- package/dist/cjs/define/primitive_icon.js +17 -0
- package/dist/cjs/define/primitive_icon.js.map +1 -0
- package/dist/cjs/define/primitive_module.js +24 -7
- package/dist/cjs/define/primitive_module.js.map +1 -1
- package/dist/cjs/define/slack_assets.js.map +1 -1
- package/dist/cjs/entries/index.js +8 -2
- package/dist/cjs/entries/index.js.map +1 -1
- package/dist/cjs/entries/markdown.js +2 -1
- package/dist/cjs/entries/markdown.js.map +1 -1
- package/dist/cjs/entries/slack.js +1 -2
- package/dist/cjs/entries/slack.js.map +1 -1
- package/dist/cjs/pack/capabilities.js +17 -11
- package/dist/cjs/pack/capabilities.js.map +1 -1
- package/dist/cjs/pack/compose.js +4 -1
- package/dist/cjs/pack/compose.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 +27 -5
- package/dist/cjs/pack/primitive_pack.js.map +1 -1
- package/dist/cjs/render/anchors.js +1 -1
- package/dist/cjs/render/anchors.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/layout_check.js.map +1 -1
- package/dist/cjs/render/markdown/builder.js +18 -8
- package/dist/cjs/render/markdown/builder.js.map +1 -1
- package/dist/cjs/render/markdown/format.js +70 -30
- 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 +3 -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 +11 -25
- 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/slack/format.js +1 -601
- package/dist/cjs/render/slack/format.js.map +1 -1
- package/dist/cjs/render/slack/index.js +1 -2
- package/dist/cjs/render/slack/index.js.map +1 -1
- package/dist/cjs/render/slack/markdown_content.js +172 -115
- package/dist/cjs/render/slack/markdown_content.js.map +1 -1
- package/dist/cjs/testing/conformance.js +40 -24
- package/dist/cjs/testing/conformance.js.map +1 -1
- package/dist/cjs/testing/icon.js +248 -0
- package/dist/cjs/testing/icon.js.map +1 -0
- package/dist/cjs/testing/index.js +3 -1
- package/dist/cjs/testing/index.js.map +1 -1
- package/dist/cjs/testing/registration.js +5 -3
- package/dist/cjs/testing/registration.js.map +1 -1
- package/dist/cjs/validate/authoring_schema.js +17 -1
- package/dist/cjs/validate/authoring_schema.js.map +1 -1
- package/dist/cjs/validate/index.js +2 -1
- package/dist/cjs/validate/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/cjs/validate/validation.js +2 -45
- package/dist/cjs/validate/validation.js.map +1 -1
- package/dist/composition/body_node_base.d.ts +7 -6
- package/dist/composition/body_node_base.d.ts.map +1 -1
- package/dist/composition/body_node_base.js +10 -3
- package/dist/composition/body_node_base.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/index.d.ts +1 -1
- package/dist/composition/index.d.ts.map +1 -1
- package/dist/composition/index.js +1 -1
- package/dist/composition/index.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/frame.d.ts +9 -20
- package/dist/define/frame.d.ts.map +1 -1
- package/dist/define/frame.js +2 -3
- package/dist/define/frame.js.map +1 -1
- package/dist/define/index.d.ts +3 -1
- package/dist/define/index.d.ts.map +1 -1
- package/dist/define/index.js +3 -1
- package/dist/define/index.js.map +1 -1
- package/dist/define/primitive_example.d.ts +30 -0
- package/dist/define/primitive_example.d.ts.map +1 -0
- package/dist/define/primitive_example.js +21 -0
- package/dist/define/primitive_example.js.map +1 -0
- package/dist/define/primitive_icon.d.ts +11 -0
- package/dist/define/primitive_icon.d.ts.map +1 -0
- package/dist/define/primitive_icon.js +14 -0
- package/dist/define/primitive_icon.js.map +1 -0
- package/dist/define/primitive_module.d.ts +45 -24
- package/dist/define/primitive_module.d.ts.map +1 -1
- package/dist/define/primitive_module.js +24 -7
- package/dist/define/primitive_module.js.map +1 -1
- package/dist/define/slack_assets.d.ts +1 -1
- package/dist/define/slack_assets.d.ts.map +1 -1
- package/dist/define/slack_assets.js.map +1 -1
- package/dist/entries/index.d.ts +3 -3
- package/dist/entries/index.d.ts.map +1 -1
- package/dist/entries/index.js +3 -3
- 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/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/capabilities.d.ts +24 -10
- package/dist/pack/capabilities.d.ts.map +1 -1
- package/dist/pack/capabilities.js +17 -11
- package/dist/pack/capabilities.js.map +1 -1
- package/dist/pack/compose.d.ts +4 -1
- package/dist/pack/compose.d.ts.map +1 -1
- package/dist/pack/compose.js +4 -1
- package/dist/pack/compose.js.map +1 -1
- package/dist/pack/index.d.ts +2 -2
- package/dist/pack/index.d.ts.map +1 -1
- package/dist/pack/index.js +2 -2
- package/dist/pack/index.js.map +1 -1
- package/dist/pack/primitive_pack.d.ts +14 -3
- package/dist/pack/primitive_pack.d.ts.map +1 -1
- package/dist/pack/primitive_pack.js +25 -4
- package/dist/pack/primitive_pack.js.map +1 -1
- package/dist/render/anchors.d.ts +2 -2
- package/dist/render/anchors.d.ts.map +1 -1
- package/dist/render/anchors.js +1 -1
- package/dist/render/anchors.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.d.ts +3 -3
- package/dist/render/html/envelope.js +12 -6
- package/dist/render/html/envelope.js.map +1 -1
- package/dist/render/layout_check.d.ts +1 -1
- package/dist/render/layout_check.d.ts.map +1 -1
- package/dist/render/layout_check.js.map +1 -1
- package/dist/render/markdown/builder.d.ts +5 -4
- package/dist/render/markdown/builder.d.ts.map +1 -1
- package/dist/render/markdown/builder.js +16 -7
- package/dist/render/markdown/builder.js.map +1 -1
- package/dist/render/markdown/format.d.ts +9 -0
- package/dist/render/markdown/format.d.ts.map +1 -1
- package/dist/render/markdown/format.js +67 -31
- 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 +1 -0
- package/dist/render/markdown/index.d.ts.map +1 -1
- package/dist/render/markdown/index.js +1 -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 +6 -6
- package/dist/render/primitive_dispatch.d.ts.map +1 -1
- package/dist/render/primitive_dispatch.js +12 -26
- 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/slack/format.d.ts +0 -25
- package/dist/render/slack/format.d.ts.map +1 -1
- package/dist/render/slack/format.js +1 -599
- package/dist/render/slack/format.js.map +1 -1
- package/dist/render/slack/index.d.ts +1 -1
- package/dist/render/slack/index.d.ts.map +1 -1
- package/dist/render/slack/index.js +1 -1
- package/dist/render/slack/index.js.map +1 -1
- package/dist/render/slack/markdown_content.d.ts +10 -4
- package/dist/render/slack/markdown_content.d.ts.map +1 -1
- package/dist/render/slack/markdown_content.js +169 -113
- package/dist/render/slack/markdown_content.js.map +1 -1
- package/dist/testing/conformance.d.ts +19 -14
- package/dist/testing/conformance.d.ts.map +1 -1
- package/dist/testing/conformance.js +40 -24
- package/dist/testing/conformance.js.map +1 -1
- package/dist/testing/icon.d.ts +11 -0
- package/dist/testing/icon.d.ts.map +1 -0
- package/dist/testing/icon.js +244 -0
- package/dist/testing/icon.js.map +1 -0
- package/dist/testing/index.d.ts +2 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +1 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/registration.d.ts +1 -1
- package/dist/testing/registration.d.ts.map +1 -1
- package/dist/testing/registration.js +6 -4
- package/dist/testing/registration.js.map +1 -1
- package/dist/validate/authoring_schema.d.ts +6 -0
- package/dist/validate/authoring_schema.d.ts.map +1 -1
- package/dist/validate/authoring_schema.js +15 -0
- package/dist/validate/authoring_schema.js.map +1 -1
- package/dist/validate/index.d.ts +1 -1
- package/dist/validate/index.d.ts.map +1 -1
- package/dist/validate/index.js +1 -1
- package/dist/validate/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/dist/validate/validation.d.ts +1 -11
- package/dist/validate/validation.d.ts.map +1 -1
- package/dist/validate/validation.js +3 -46
- package/dist/validate/validation.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
4
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
5
|
+
* 2.0; you may not use this file except in compliance with the Elastic License
|
|
6
|
+
* 2.0.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.printCompositionJsx = exports.printNodeJsx = exports.printValue = void 0;
|
|
10
|
+
const react_1 = require("react");
|
|
11
|
+
const authored_fields_1 = require("./authored_fields");
|
|
12
|
+
const authoring_model_1 = require("./authoring_model");
|
|
13
|
+
const jsx_shim_1 = require("./jsx_shim");
|
|
14
|
+
const MAX_LINE = 80;
|
|
15
|
+
const INDENT = ' ';
|
|
16
|
+
const IDENTIFIER = /^[A-Za-z_$][\w$]*$/;
|
|
17
|
+
const UNSAFE_TEXT = /[{}<>&]/;
|
|
18
|
+
const UNSAFE_ATTRIBUTE = /["\\\n\r&]/;
|
|
19
|
+
const TREE = Symbol.for('elastic.isomer.author.jsx_tree');
|
|
20
|
+
const isRecord = (item) => typeof item === 'object' && item !== null && !Array.isArray(item);
|
|
21
|
+
const isTree = (value) => isRecord(value) && value[TREE] === true;
|
|
22
|
+
const tree = (name, attributes, children = []) => ({ [TREE]: true, name, attributes, children });
|
|
23
|
+
const printKey = (key) => {
|
|
24
|
+
if (key === '__proto__') {
|
|
25
|
+
return '["__proto__"]';
|
|
26
|
+
}
|
|
27
|
+
return IDENTIFIER.test(key) ? key : JSON.stringify(key);
|
|
28
|
+
};
|
|
29
|
+
/** A JavaScript literal for `value`, on one line when it fits. */
|
|
30
|
+
const printValue = (value, indent = '') => {
|
|
31
|
+
if (isTree(value)) {
|
|
32
|
+
return printTree(value, indent);
|
|
33
|
+
}
|
|
34
|
+
if (typeof value === 'string') {
|
|
35
|
+
return JSON.stringify(value);
|
|
36
|
+
}
|
|
37
|
+
if (typeof value !== 'object' || value === null) {
|
|
38
|
+
return String(value);
|
|
39
|
+
}
|
|
40
|
+
const inner = indent + INDENT;
|
|
41
|
+
const parts = Array.isArray(value)
|
|
42
|
+
? value.map((item) => (0, exports.printValue)(item, inner))
|
|
43
|
+
: Object.entries(value)
|
|
44
|
+
.filter(([, item]) => item !== undefined)
|
|
45
|
+
.map(([key, item]) => `${printKey(key)}: ${(0, exports.printValue)(item, inner)}`);
|
|
46
|
+
const [open, close] = Array.isArray(value) ? ['[', ']'] : ['{ ', ' }'];
|
|
47
|
+
if (!parts.length) {
|
|
48
|
+
return Array.isArray(value) ? '[]' : '{}';
|
|
49
|
+
}
|
|
50
|
+
const inline = `${open}${parts.join(', ')}${close}`;
|
|
51
|
+
if (inline.length + indent.length <= MAX_LINE && !inline.includes('\n')) {
|
|
52
|
+
return inline;
|
|
53
|
+
}
|
|
54
|
+
return `${open.trim()}\n${parts
|
|
55
|
+
.map((part) => `${inner}${part},`)
|
|
56
|
+
.join('\n')}\n${indent}${close.trim()}`;
|
|
57
|
+
};
|
|
58
|
+
exports.printValue = printValue;
|
|
59
|
+
const printAttribute = (name, value, indent) => {
|
|
60
|
+
if (typeof value === 'string' && !UNSAFE_ATTRIBUTE.test(value)) {
|
|
61
|
+
return `${name}="${value}"`;
|
|
62
|
+
}
|
|
63
|
+
const printed = (0, exports.printValue)(value, indent);
|
|
64
|
+
if (isTree(value) && printed.includes('\n')) {
|
|
65
|
+
const inner = indent + INDENT;
|
|
66
|
+
return `${name}={\n${inner}${(0, exports.printValue)(value, inner)}\n${indent}}`;
|
|
67
|
+
}
|
|
68
|
+
return `${name}={${printed}}`;
|
|
69
|
+
};
|
|
70
|
+
const escapeTemplate = (text) => text.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$\{/g, '\\${');
|
|
71
|
+
/** A template literal's text at `indent`: a line break after the backtick, each line one step in, and the closing one back at `indent`. */
|
|
72
|
+
const templateText = (lines, indent) => `\n${lines.map((line) => (line ? `${indent}${INDENT}${line}` : line)).join('\n')}\n${indent}`;
|
|
73
|
+
/**
|
|
74
|
+
* Ways to write `text` as a child, most readable first. A template literal's value depends on its
|
|
75
|
+
* indent only through leading whitespace every line shares, so it is checked at no indent.
|
|
76
|
+
*/
|
|
77
|
+
const textChildren = (text) => {
|
|
78
|
+
const children = [];
|
|
79
|
+
if (text &&
|
|
80
|
+
text.trim() === text &&
|
|
81
|
+
!UNSAFE_TEXT.test(text) &&
|
|
82
|
+
!/[^\S ]/.test(text)) {
|
|
83
|
+
children.push({ value: text, print: () => text });
|
|
84
|
+
}
|
|
85
|
+
if (text.includes('\n') && !text.includes('\r')) {
|
|
86
|
+
const lines = text.split('\n');
|
|
87
|
+
children.push({
|
|
88
|
+
value: templateText(lines, ''),
|
|
89
|
+
print: (indent) => `{\`${templateText(lines.map(escapeTemplate), indent)}\`}`,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
children.push({
|
|
93
|
+
value: text,
|
|
94
|
+
print: () => `{${JSON.stringify(text)}}`,
|
|
95
|
+
});
|
|
96
|
+
return children;
|
|
97
|
+
};
|
|
98
|
+
const printTree = ({ name, attributes, children }, indent) => {
|
|
99
|
+
const inner = indent + INDENT;
|
|
100
|
+
const inlineAttributes = attributes.map(([key, value]) => printAttribute(key, value, indent));
|
|
101
|
+
const inlineOpen = [name, ...inlineAttributes].join(' ');
|
|
102
|
+
const fits = indent.length + inlineOpen.length + 2 <= MAX_LINE &&
|
|
103
|
+
!inlineAttributes.some((attribute) => attribute.includes('\n'));
|
|
104
|
+
const open = fits
|
|
105
|
+
? `<${inlineOpen}`
|
|
106
|
+
: `<${name}\n${attributes
|
|
107
|
+
.map(([key, value]) => `${inner}${printAttribute(key, value, inner)}`)
|
|
108
|
+
.join('\n')}\n${indent}`;
|
|
109
|
+
if (!children.length) {
|
|
110
|
+
return `${open}${fits ? ' ' : ''}/>`;
|
|
111
|
+
}
|
|
112
|
+
const printed = children.map((child) => isTree(child) ? printTree(child, inner) : child.print(inner));
|
|
113
|
+
const [only = ''] = printed;
|
|
114
|
+
const inline = `${open}>${only}</${name}>`;
|
|
115
|
+
const isText = printed.length === 1 && !only.startsWith('<') && !only.includes('\n');
|
|
116
|
+
if (fits && isText && indent.length + inline.length <= MAX_LINE) {
|
|
117
|
+
return inline;
|
|
118
|
+
}
|
|
119
|
+
return `${open}>\n${printed.map((child) => `${inner}${child}`).join('\n')}\n${indent}</${name}>`;
|
|
120
|
+
};
|
|
121
|
+
/** Deep equality that ignores `undefined` entries and key order. */
|
|
122
|
+
const sameValue = (a, b) => {
|
|
123
|
+
if (Array.isArray(a) || Array.isArray(b)) {
|
|
124
|
+
return (Array.isArray(a) &&
|
|
125
|
+
Array.isArray(b) &&
|
|
126
|
+
a.length === b.length &&
|
|
127
|
+
a.every((item, index) => sameValue(item, b[index])));
|
|
128
|
+
}
|
|
129
|
+
if (isRecord(a) && isRecord(b)) {
|
|
130
|
+
const keys = (record) => Object.keys(record).filter((key) => record[key] !== undefined);
|
|
131
|
+
const [aKeys, bKeys] = [keys(a), keys(b)];
|
|
132
|
+
return (aKeys.length === bKeys.length &&
|
|
133
|
+
aKeys.every((key) => sameValue(a[key], b[key])));
|
|
134
|
+
}
|
|
135
|
+
return a === b;
|
|
136
|
+
};
|
|
137
|
+
/** Round trips one node's printer tries per attribute style before printing every field as a prop. */
|
|
138
|
+
const MAX_CANDIDATES = 256;
|
|
139
|
+
/** The `size`-element subsets of `0..count - 1`, in colexicographic order. */
|
|
140
|
+
function* subsetsOfSize(count, size) {
|
|
141
|
+
if (size === 0) {
|
|
142
|
+
yield [];
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (count < size) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
yield* subsetsOfSize(count - 1, size);
|
|
149
|
+
for (const subset of subsetsOfSize(count - 1, size - 1)) {
|
|
150
|
+
yield [...subset, count - 1];
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/** Every subset of `0..count - 1`, largest first. */
|
|
154
|
+
function* subsetsBySize(count) {
|
|
155
|
+
for (let size = count; size >= 0; size -= 1) {
|
|
156
|
+
yield* subsetsOfSize(count, size);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
const createPrinter = ({ schemaFor, shim, readSpec = authored_fields_1.readAuthoredSpec, }) => {
|
|
160
|
+
const components = shim;
|
|
161
|
+
const trees = new WeakMap();
|
|
162
|
+
const isNode = (value) => isRecord(value) &&
|
|
163
|
+
typeof value.type === 'string' &&
|
|
164
|
+
schemaFor(value.type) !== undefined;
|
|
165
|
+
const toReact = (value) => {
|
|
166
|
+
if (isTree(value)) {
|
|
167
|
+
return toElement(value);
|
|
168
|
+
}
|
|
169
|
+
return Array.isArray(value) ? value.map(toReact) : value;
|
|
170
|
+
};
|
|
171
|
+
const toElement = ({ name, attributes, children }) => {
|
|
172
|
+
const component = name
|
|
173
|
+
.split('.')
|
|
174
|
+
.reduce((scope, part) => typeof scope === 'function' || isRecord(scope)
|
|
175
|
+
? scope[part]
|
|
176
|
+
: undefined, components);
|
|
177
|
+
if (typeof component !== 'function' && !isRecord(component)) {
|
|
178
|
+
throw new Error(`No authoring component <${name}>.`);
|
|
179
|
+
}
|
|
180
|
+
return (0, react_1.createElement)(component, Object.fromEntries(attributes.map(([key, value]) => [key, toReact(value)])), ...children.map((child) => isTree(child) ? toElement(child) : child.value));
|
|
181
|
+
};
|
|
182
|
+
const parseBody = (children) => shim.toComposition((0, react_1.createElement)(shim.Composition, null, children)).body;
|
|
183
|
+
const childContext = { parseChildren: parseBody };
|
|
184
|
+
const roundTrips = (candidate, node) => {
|
|
185
|
+
try {
|
|
186
|
+
const [parsed, ...rest] = parseBody(toElement(candidate));
|
|
187
|
+
return rest.length === 0 && sameValue(parsed, node);
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
/** Nodes as element children, or `undefined` when `value` is not a node or a non-empty list of them. */
|
|
194
|
+
const nodeChildren = (value) => {
|
|
195
|
+
const items = Array.isArray(value) ? value : [value];
|
|
196
|
+
return items.length && items.every(isNode)
|
|
197
|
+
? items.map(nodeTree)
|
|
198
|
+
: undefined;
|
|
199
|
+
};
|
|
200
|
+
/** `value` with each node, alone or in a list, as an element. */
|
|
201
|
+
const jsxAttribute = (value) => {
|
|
202
|
+
if (isNode(value)) {
|
|
203
|
+
return nodeTree(value);
|
|
204
|
+
}
|
|
205
|
+
return Array.isArray(value) && value.length && value.every(isNode)
|
|
206
|
+
? value.map(nodeTree)
|
|
207
|
+
: value;
|
|
208
|
+
};
|
|
209
|
+
const textChild = (text, readBack) => typeof text === 'string'
|
|
210
|
+
? textChildren(text).find(({ value }) => readBack(value) === text)
|
|
211
|
+
: undefined;
|
|
212
|
+
/** Children of a custom `toItem` field's element: the first whose `toItem` gives `item` back. */
|
|
213
|
+
const customItemTree = (item, { textField, toItem, }, name) => {
|
|
214
|
+
const candidates = [];
|
|
215
|
+
const withChildren = (attributes, value) => {
|
|
216
|
+
if (value === '') {
|
|
217
|
+
candidates.push(tree(name, attributes));
|
|
218
|
+
}
|
|
219
|
+
if (typeof value === 'string') {
|
|
220
|
+
textChildren(value).forEach((child) => candidates.push(tree(name, attributes, [child])));
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
if (Array.isArray(value) &&
|
|
224
|
+
value.length &&
|
|
225
|
+
value.every((line) => typeof line === 'string')) {
|
|
226
|
+
withChildren(attributes, value.join('\n'));
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
const nodes = nodeChildren(value);
|
|
230
|
+
if (nodes) {
|
|
231
|
+
candidates.push(tree(name, attributes, nodes));
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
if (isRecord(item) && !isNode(item)) {
|
|
235
|
+
const keys = [
|
|
236
|
+
...new Set([...(textField ? [textField] : []), ...Object.keys(item)]),
|
|
237
|
+
];
|
|
238
|
+
keys.forEach((key) => withChildren(Object.entries(item).filter(([other, value]) => other !== key && value !== undefined), item[key]));
|
|
239
|
+
candidates.push(tree(name, Object.entries(item).filter(([, value]) => value !== undefined)));
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
withChildren([], item);
|
|
243
|
+
}
|
|
244
|
+
return candidates.find((candidate) => {
|
|
245
|
+
try {
|
|
246
|
+
const { props } = toElement(candidate);
|
|
247
|
+
return sameValue(toItem(props, childContext), item);
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
};
|
|
254
|
+
/** One child-field item as an element, or `undefined` when it cannot be one. */
|
|
255
|
+
const itemTree = (item, field, owner) => {
|
|
256
|
+
const name = (0, authoring_model_1.capitalize)((0, authoring_model_1.memberType)(owner, field));
|
|
257
|
+
const { toItem } = field;
|
|
258
|
+
if (toItem) {
|
|
259
|
+
return customItemTree(item, { ...field, toItem }, name);
|
|
260
|
+
}
|
|
261
|
+
if (!isRecord(item)) {
|
|
262
|
+
return undefined;
|
|
263
|
+
}
|
|
264
|
+
const spec = readSpec(field.itemSchema);
|
|
265
|
+
const entries = Object.entries(item).filter(([, value]) => value !== undefined);
|
|
266
|
+
const attributes = [];
|
|
267
|
+
const children = [];
|
|
268
|
+
const claimed = new Set();
|
|
269
|
+
const text = field.textField
|
|
270
|
+
? textChild(item[field.textField], (value) => (0, jsx_shim_1.textFromChildren)(value))
|
|
271
|
+
: undefined;
|
|
272
|
+
entries.forEach(([key, value]) => {
|
|
273
|
+
if (key === field.textField && text) {
|
|
274
|
+
children.unshift(text);
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
const nested = spec?.children.find((child) => child.field === key);
|
|
278
|
+
const sharesName = (other) => other.field !== key &&
|
|
279
|
+
other.name === nested?.name &&
|
|
280
|
+
item[other.field] === undefined;
|
|
281
|
+
if (nested &&
|
|
282
|
+
!claimed.has(nested.name) &&
|
|
283
|
+
!spec?.children.some(sharesName)) {
|
|
284
|
+
const items = Array.isArray(value) ? value : [value];
|
|
285
|
+
const nestedTrees = items.map((entry) => itemTree(entry, nested, owner));
|
|
286
|
+
if (items.length && nestedTrees.every(isTree)) {
|
|
287
|
+
claimed.add(nested.name);
|
|
288
|
+
children.push(...nestedTrees);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
attributes.push([key, value]);
|
|
293
|
+
});
|
|
294
|
+
return tree(name, attributes, children);
|
|
295
|
+
};
|
|
296
|
+
/** What a node's field prints as when it is in children. */
|
|
297
|
+
const fieldChildren = (key, value, spec, owner) => {
|
|
298
|
+
const text = spec.text.find(({ field }) => field === key);
|
|
299
|
+
if (text) {
|
|
300
|
+
const child = textChild(value, (read) => (0, jsx_shim_1.textFromChildren)(read, {
|
|
301
|
+
collapseWhitespace: text.collapseWhitespace,
|
|
302
|
+
...(text.dedent ? { dedent: true } : {}),
|
|
303
|
+
}));
|
|
304
|
+
return child ? [child] : undefined;
|
|
305
|
+
}
|
|
306
|
+
const field = spec.children.find((child) => child.field === key);
|
|
307
|
+
if (field) {
|
|
308
|
+
const items = Array.isArray(value) ? value : [value];
|
|
309
|
+
const itemTrees = items.map((item) => itemTree(item, field, owner));
|
|
310
|
+
return items.length && itemTrees.every(isTree) ? itemTrees : undefined;
|
|
311
|
+
}
|
|
312
|
+
return nodeChildren(value);
|
|
313
|
+
};
|
|
314
|
+
const nodeTree = (node) => {
|
|
315
|
+
const cached = trees.get(node);
|
|
316
|
+
if (cached) {
|
|
317
|
+
return cached;
|
|
318
|
+
}
|
|
319
|
+
const { type } = node;
|
|
320
|
+
const name = (0, authoring_model_1.capitalize)(type);
|
|
321
|
+
const schema = schemaFor(type);
|
|
322
|
+
const spec = schema ? readSpec(schema) : undefined;
|
|
323
|
+
const entries = Object.entries(node).filter(([key, value]) => key !== 'type' && value !== undefined);
|
|
324
|
+
if (!spec) {
|
|
325
|
+
return tree(name, entries);
|
|
326
|
+
}
|
|
327
|
+
const capable = entries.flatMap(([key, value]) => {
|
|
328
|
+
const children = fieldChildren(key, value, spec, type);
|
|
329
|
+
return children ? [{ key, children }] : [];
|
|
330
|
+
});
|
|
331
|
+
const build = (inChildren, attribute) => {
|
|
332
|
+
const children = capable
|
|
333
|
+
.filter(({ key }) => inChildren.has(key))
|
|
334
|
+
.flatMap(({ children: fieldTrees }) => fieldTrees);
|
|
335
|
+
return tree(name, entries
|
|
336
|
+
.filter(([key]) => !inChildren.has(key))
|
|
337
|
+
.map(([key, value]) => [key, attribute(value)]), [
|
|
338
|
+
...children.filter((child) => !isTree(child)),
|
|
339
|
+
...children.filter(isTree),
|
|
340
|
+
]);
|
|
341
|
+
};
|
|
342
|
+
const search = () => {
|
|
343
|
+
for (const attribute of [jsxAttribute, (value) => value]) {
|
|
344
|
+
let tried = 0;
|
|
345
|
+
for (const indexes of subsetsBySize(capable.length)) {
|
|
346
|
+
if (tried++ === MAX_CANDIDATES) {
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
const candidate = build(new Set(indexes.map((index) => capable[index].key)), attribute);
|
|
350
|
+
if (roundTrips(candidate, node)) {
|
|
351
|
+
return candidate;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
return tree(name, entries);
|
|
356
|
+
};
|
|
357
|
+
const found = search();
|
|
358
|
+
trees.set(node, found);
|
|
359
|
+
return found;
|
|
360
|
+
};
|
|
361
|
+
return { nodeTree };
|
|
362
|
+
};
|
|
363
|
+
/** Prints one node as authoring JSX for `buildJsxShim`'s components. */
|
|
364
|
+
const printNodeJsx = (node, env) => printTree(createPrinter(env).nodeTree(node), '');
|
|
365
|
+
exports.printNodeJsx = printNodeJsx;
|
|
366
|
+
/** Prints a composition body as JSX children of `<Composition>`. */
|
|
367
|
+
const printCompositionJsx = (body, env) => {
|
|
368
|
+
const { nodeTree } = createPrinter(env);
|
|
369
|
+
const nodes = body
|
|
370
|
+
.map((node) => printTree(nodeTree(node), ''))
|
|
371
|
+
.join('\n')
|
|
372
|
+
.split('\n')
|
|
373
|
+
.map((line) => (line ? `${INDENT}${line}` : line))
|
|
374
|
+
.join('\n');
|
|
375
|
+
return `<Composition>\n${nodes}\n</Composition>`;
|
|
376
|
+
};
|
|
377
|
+
exports.printCompositionJsx = printCompositionJsx;
|
|
378
|
+
//# sourceMappingURL=print_jsx.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"print_jsx.js","sourceRoot":"","sources":["../../../src/author/print_jsx.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 { createElement, type ReactElement, type ReactNode } from 'react';\nimport type { ZodType } from 'zod';\n\nimport type { PrimitiveNode } from '../define/primitive_module';\n\nimport type {\n AuthorChildContext,\n AuthoredChildField,\n AuthoredSpec,\n} from './authored_fields';\nimport { readAuthoredSpec } from './authored_fields';\nimport { capitalize, memberType } from './authoring_model';\nimport type { JsxShim } from './jsx_shim';\nimport { textFromChildren } from './jsx_shim';\n\n/** What {@link printNodeJsx} reads a pack's authoring from. */\nexport interface PrintJsxEnv {\n schemaFor: (type: string) => ZodType | undefined;\n /** Parses each candidate back, so a field prints as children only when that round-trips. */\n shim: JsxShim;\n /** Reads a schema's authoring brands; returning `undefined` prints every field as a prop. */\n readSpec?: (schema: ZodType) => AuthoredSpec | undefined;\n}\n\nconst MAX_LINE = 80;\nconst INDENT = ' ';\nconst IDENTIFIER = /^[A-Za-z_$][\\w$]*$/;\nconst UNSAFE_TEXT = /[{}<>&]/;\nconst UNSAFE_ATTRIBUTE = /[\"\\\\\\n\\r&]/;\n\nconst TREE = Symbol.for('elastic.isomer.author.jsx_tree');\n\n/** A text child: the value React receives, and how it prints at an indent. */\ninterface TextChild {\n value: string;\n print: (indent: string) => string;\n}\n\n/** An element to print. Attribute values may hold trees, printed as JSX expressions. */\ninterface JsxTree {\n [TREE]: true;\n name: string;\n attributes: ReadonlyArray<[string, unknown]>;\n children: ReadonlyArray<JsxTree | TextChild>;\n}\n\nconst isRecord = (item: unknown): item is Record<string, unknown> =>\n typeof item === 'object' && item !== null && !Array.isArray(item);\n\nconst isTree = (value: unknown): value is JsxTree =>\n isRecord(value) && (value as Partial<JsxTree>)[TREE] === true;\n\nconst tree = (\n name: string,\n attributes: ReadonlyArray<[string, unknown]>,\n children: ReadonlyArray<JsxTree | TextChild> = []\n): JsxTree => ({ [TREE]: true, name, attributes, children });\n\nconst printKey = (key: string): string => {\n if (key === '__proto__') {\n return '[\"__proto__\"]';\n }\n return IDENTIFIER.test(key) ? key : JSON.stringify(key);\n};\n\n/** A JavaScript literal for `value`, on one line when it fits. */\nexport const printValue = (value: unknown, indent = ''): string => {\n if (isTree(value)) {\n return printTree(value, indent);\n }\n if (typeof value === 'string') {\n return JSON.stringify(value);\n }\n if (typeof value !== 'object' || value === null) {\n return String(value);\n }\n\n const inner = indent + INDENT;\n const parts = Array.isArray(value)\n ? value.map((item) => printValue(item, inner))\n : Object.entries(value)\n .filter(([, item]) => item !== undefined)\n .map(([key, item]) => `${printKey(key)}: ${printValue(item, inner)}`);\n const [open, close] = Array.isArray(value) ? ['[', ']'] : ['{ ', ' }'];\n\n if (!parts.length) {\n return Array.isArray(value) ? '[]' : '{}';\n }\n\n const inline = `${open}${parts.join(', ')}${close}`;\n if (inline.length + indent.length <= MAX_LINE && !inline.includes('\\n')) {\n return inline;\n }\n return `${open.trim()}\\n${parts\n .map((part) => `${inner}${part},`)\n .join('\\n')}\\n${indent}${close.trim()}`;\n};\n\nconst printAttribute = (\n name: string,\n value: unknown,\n indent: string\n): string => {\n if (typeof value === 'string' && !UNSAFE_ATTRIBUTE.test(value)) {\n return `${name}=\"${value}\"`;\n }\n const printed = printValue(value, indent);\n if (isTree(value) && printed.includes('\\n')) {\n const inner = indent + INDENT;\n return `${name}={\\n${inner}${printValue(value, inner)}\\n${indent}}`;\n }\n return `${name}={${printed}}`;\n};\n\nconst escapeTemplate = (text: string): string =>\n text.replace(/\\\\/g, '\\\\\\\\').replace(/`/g, '\\\\`').replace(/\\$\\{/g, '\\\\${');\n\n/** A template literal's text at `indent`: a line break after the backtick, each line one step in, and the closing one back at `indent`. */\nconst templateText = (lines: readonly string[], indent: string): string =>\n `\\n${lines.map((line) => (line ? `${indent}${INDENT}${line}` : line)).join('\\n')}\\n${indent}`;\n\n/**\n * Ways to write `text` as a child, most readable first. A template literal's value depends on its\n * indent only through leading whitespace every line shares, so it is checked at no indent.\n */\nconst textChildren = (text: string): TextChild[] => {\n const children: TextChild[] = [];\n if (\n text &&\n text.trim() === text &&\n !UNSAFE_TEXT.test(text) &&\n !/[^\\S ]/.test(text)\n ) {\n children.push({ value: text, print: () => text });\n }\n if (text.includes('\\n') && !text.includes('\\r')) {\n const lines = text.split('\\n');\n children.push({\n value: templateText(lines, ''),\n print: (indent) =>\n `{\\`${templateText(lines.map(escapeTemplate), indent)}\\`}`,\n });\n }\n children.push({\n value: text,\n print: () => `{${JSON.stringify(text)}}`,\n });\n return children;\n};\n\nconst printTree = (\n { name, attributes, children }: JsxTree,\n indent: string\n): string => {\n const inner = indent + INDENT;\n const inlineAttributes = attributes.map(([key, value]) =>\n printAttribute(key, value, indent)\n );\n const inlineOpen = [name, ...inlineAttributes].join(' ');\n const fits =\n indent.length + inlineOpen.length + 2 <= MAX_LINE &&\n !inlineAttributes.some((attribute) => attribute.includes('\\n'));\n\n const open = fits\n ? `<${inlineOpen}`\n : `<${name}\\n${attributes\n .map(([key, value]) => `${inner}${printAttribute(key, value, inner)}`)\n .join('\\n')}\\n${indent}`;\n\n if (!children.length) {\n return `${open}${fits ? ' ' : ''}/>`;\n }\n const printed = children.map((child) =>\n isTree(child) ? printTree(child, inner) : child.print(inner)\n );\n const [only = ''] = printed;\n const inline = `${open}>${only}</${name}>`;\n const isText =\n printed.length === 1 && !only.startsWith('<') && !only.includes('\\n');\n if (fits && isText && indent.length + inline.length <= MAX_LINE) {\n return inline;\n }\n return `${open}>\\n${printed.map((child) => `${inner}${child}`).join('\\n')}\\n${indent}</${name}>`;\n};\n\n/** Deep equality that ignores `undefined` entries and key order. */\nconst sameValue = (a: unknown, b: unknown): boolean => {\n if (Array.isArray(a) || Array.isArray(b)) {\n return (\n Array.isArray(a) &&\n Array.isArray(b) &&\n a.length === b.length &&\n a.every((item, index) => sameValue(item, b[index]))\n );\n }\n if (isRecord(a) && isRecord(b)) {\n const keys = (record: Record<string, unknown>) =>\n Object.keys(record).filter((key) => record[key] !== undefined);\n const [aKeys, bKeys] = [keys(a), keys(b)];\n return (\n aKeys.length === bKeys.length &&\n aKeys.every((key) => sameValue(a[key], b[key]))\n );\n }\n return a === b;\n};\n\n/** A field's children, or `undefined` when they cannot carry it. */\ntype Children = ReadonlyArray<JsxTree | TextChild> | undefined;\n\n/** Round trips one node's printer tries per attribute style before printing every field as a prop. */\nconst MAX_CANDIDATES = 256;\n\n/** The `size`-element subsets of `0..count - 1`, in colexicographic order. */\nfunction* subsetsOfSize(count: number, size: number): Generator<number[]> {\n if (size === 0) {\n yield [];\n return;\n }\n if (count < size) {\n return;\n }\n yield* subsetsOfSize(count - 1, size);\n for (const subset of subsetsOfSize(count - 1, size - 1)) {\n yield [...subset, count - 1];\n }\n}\n\n/** Every subset of `0..count - 1`, largest first. */\nfunction* subsetsBySize(count: number): Generator<number[]> {\n for (let size = count; size >= 0; size -= 1) {\n yield* subsetsOfSize(count, size);\n }\n}\n\ninterface Printer {\n nodeTree: (node: PrimitiveNode) => JsxTree;\n}\n\nconst createPrinter = ({\n schemaFor,\n shim,\n readSpec = readAuthoredSpec,\n}: PrintJsxEnv): Printer => {\n const components = shim as unknown as Record<string, unknown>;\n const trees = new WeakMap<object, JsxTree>();\n\n const isNode = (value: unknown): value is PrimitiveNode =>\n isRecord(value) &&\n typeof value.type === 'string' &&\n schemaFor(value.type) !== undefined;\n\n const toReact = (value: unknown): unknown => {\n if (isTree(value)) {\n return toElement(value);\n }\n return Array.isArray(value) ? value.map(toReact) : value;\n };\n\n const toElement = ({ name, attributes, children }: JsxTree): ReactElement => {\n const component = name\n .split('.')\n .reduce<unknown>(\n (scope, part) =>\n typeof scope === 'function' || isRecord(scope)\n ? (scope as Record<string, unknown>)[part]\n : undefined,\n components\n );\n if (typeof component !== 'function' && !isRecord(component)) {\n throw new Error(`No authoring component <${name}>.`);\n }\n return createElement(\n component as Parameters<typeof createElement>[0],\n Object.fromEntries(\n attributes.map(([key, value]) => [key, toReact(value)])\n ),\n ...children.map((child) =>\n isTree(child) ? toElement(child) : child.value\n )\n );\n };\n\n const parseBody = (children: ReactNode): PrimitiveNode[] =>\n shim.toComposition(createElement(shim.Composition, null, children)).body;\n\n const childContext: AuthorChildContext = { parseChildren: parseBody };\n\n const roundTrips = (candidate: JsxTree, node: PrimitiveNode): boolean => {\n try {\n const [parsed, ...rest] = parseBody(toElement(candidate));\n return rest.length === 0 && sameValue(parsed, node);\n } catch {\n return false;\n }\n };\n\n /** Nodes as element children, or `undefined` when `value` is not a node or a non-empty list of them. */\n const nodeChildren = (value: unknown): JsxTree[] | undefined => {\n const items: unknown[] = Array.isArray(value) ? value : [value];\n return items.length && items.every(isNode)\n ? items.map(nodeTree)\n : undefined;\n };\n\n /** `value` with each node, alone or in a list, as an element. */\n const jsxAttribute = (value: unknown): unknown => {\n if (isNode(value)) {\n return nodeTree(value);\n }\n return Array.isArray(value) && value.length && value.every(isNode)\n ? value.map(nodeTree)\n : value;\n };\n\n const textChild = (\n text: unknown,\n readBack: (value: string) => string\n ): TextChild | undefined =>\n typeof text === 'string'\n ? textChildren(text).find(({ value }) => readBack(value) === text)\n : undefined;\n\n /** Children of a custom `toItem` field's element: the first whose `toItem` gives `item` back. */\n const customItemTree = (\n item: unknown,\n {\n textField,\n toItem,\n }: Pick<AuthoredChildField, 'textField'> & {\n toItem: NonNullable<AuthoredChildField['toItem']>;\n },\n name: string\n ): JsxTree | undefined => {\n const candidates: JsxTree[] = [];\n const withChildren = (\n attributes: ReadonlyArray<[string, unknown]>,\n value: unknown\n ) => {\n if (value === '') {\n candidates.push(tree(name, attributes));\n }\n if (typeof value === 'string') {\n textChildren(value).forEach((child) =>\n candidates.push(tree(name, attributes, [child]))\n );\n return;\n }\n if (\n Array.isArray(value) &&\n value.length &&\n value.every((line) => typeof line === 'string')\n ) {\n withChildren(attributes, value.join('\\n'));\n return;\n }\n const nodes = nodeChildren(value);\n if (nodes) {\n candidates.push(tree(name, attributes, nodes));\n }\n };\n\n if (isRecord(item) && !isNode(item)) {\n const keys = [\n ...new Set([...(textField ? [textField] : []), ...Object.keys(item)]),\n ];\n keys.forEach((key) =>\n withChildren(\n Object.entries(item).filter(\n ([other, value]) => other !== key && value !== undefined\n ),\n item[key]\n )\n );\n candidates.push(\n tree(\n name,\n Object.entries(item).filter(([, value]) => value !== undefined)\n )\n );\n } else {\n withChildren([], item);\n }\n\n return candidates.find((candidate) => {\n try {\n const { props } = toElement(candidate) as ReactElement<object>;\n return sameValue(toItem(props, childContext), item);\n } catch {\n return false;\n }\n });\n };\n\n /** One child-field item as an element, or `undefined` when it cannot be one. */\n const itemTree = (\n item: unknown,\n field: AuthoredChildField,\n owner: string\n ): JsxTree | undefined => {\n const name = capitalize(memberType(owner, field));\n const { toItem } = field;\n if (toItem) {\n return customItemTree(item, { ...field, toItem }, name);\n }\n if (!isRecord(item)) {\n return undefined;\n }\n const spec = readSpec(field.itemSchema);\n const entries = Object.entries(item).filter(\n ([, value]) => value !== undefined\n );\n const attributes: Array<[string, unknown]> = [];\n const children: Array<JsxTree | TextChild> = [];\n const claimed = new Set<string>();\n const text = field.textField\n ? textChild(item[field.textField], (value) => textFromChildren(value))\n : undefined;\n entries.forEach(([key, value]) => {\n if (key === field.textField && text) {\n children.unshift(text);\n return;\n }\n const nested = spec?.children.find((child) => child.field === key);\n const sharesName = (other: AuthoredChildField) =>\n other.field !== key &&\n other.name === nested?.name &&\n item[other.field] === undefined;\n if (\n nested &&\n !claimed.has(nested.name) &&\n !spec?.children.some(sharesName)\n ) {\n const items: unknown[] = Array.isArray(value) ? value : [value];\n const nestedTrees = items.map((entry) =>\n itemTree(entry, nested, owner)\n );\n if (items.length && nestedTrees.every(isTree)) {\n claimed.add(nested.name);\n children.push(...nestedTrees);\n return;\n }\n }\n attributes.push([key, value]);\n });\n return tree(name, attributes, children);\n };\n\n /** What a node's field prints as when it is in children. */\n const fieldChildren = (\n key: string,\n value: unknown,\n spec: AuthoredSpec,\n owner: string\n ): Children => {\n const text = spec.text.find(({ field }) => field === key);\n if (text) {\n const child = textChild(value, (read) =>\n textFromChildren(read, {\n collapseWhitespace: text.collapseWhitespace,\n ...(text.dedent ? { dedent: true } : {}),\n })\n );\n return child ? [child] : undefined;\n }\n const field = spec.children.find((child) => child.field === key);\n if (field) {\n const items: unknown[] = Array.isArray(value) ? value : [value];\n const itemTrees = items.map((item) => itemTree(item, field, owner));\n return items.length && itemTrees.every(isTree) ? itemTrees : undefined;\n }\n return nodeChildren(value);\n };\n\n const nodeTree = (node: PrimitiveNode): JsxTree => {\n const cached = trees.get(node);\n if (cached) {\n return cached;\n }\n const { type } = node;\n const name = capitalize(type);\n const schema = schemaFor(type);\n const spec = schema ? readSpec(schema) : undefined;\n const entries = Object.entries(node).filter(\n ([key, value]) => key !== 'type' && value !== undefined\n );\n if (!spec) {\n return tree(name, entries);\n }\n\n const capable = entries.flatMap(([key, value]) => {\n const children = fieldChildren(key, value, spec, type);\n return children ? [{ key, children }] : [];\n });\n const build = (\n inChildren: ReadonlySet<string>,\n attribute: (value: unknown) => unknown\n ): JsxTree => {\n const children = capable\n .filter(({ key }) => inChildren.has(key))\n .flatMap(({ children: fieldTrees }) => fieldTrees);\n return tree(\n name,\n entries\n .filter(([key]) => !inChildren.has(key))\n .map(([key, value]) => [key, attribute(value)]),\n [\n ...children.filter((child) => !isTree(child)),\n ...children.filter(isTree),\n ]\n );\n };\n\n const search = (): JsxTree => {\n for (const attribute of [jsxAttribute, (value: unknown) => value]) {\n let tried = 0;\n for (const indexes of subsetsBySize(capable.length)) {\n if (tried++ === MAX_CANDIDATES) {\n break;\n }\n const candidate = build(\n new Set(indexes.map((index) => capable[index]!.key)),\n attribute\n );\n if (roundTrips(candidate, node)) {\n return candidate;\n }\n }\n }\n return tree(name, entries);\n };\n const found = search();\n trees.set(node, found);\n return found;\n };\n\n return { nodeTree };\n};\n\n/** Prints one node as authoring JSX for `buildJsxShim`'s components. */\nexport const printNodeJsx = (node: PrimitiveNode, env: PrintJsxEnv): string =>\n printTree(createPrinter(env).nodeTree(node), '');\n\n/** Prints a composition body as JSX children of `<Composition>`. */\nexport const printCompositionJsx = (\n body: readonly PrimitiveNode[],\n env: PrintJsxEnv\n): string => {\n const { nodeTree } = createPrinter(env);\n const nodes = body\n .map((node) => printTree(nodeTree(node), ''))\n .join('\\n')\n .split('\\n')\n .map((line) => (line ? `${INDENT}${line}` : line))\n .join('\\n');\n return `<Composition>\\n${nodes}\\n</Composition>`;\n};\n"]}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.buildAuthoringPrompt = exports.formatPrimitiveEntry = exports.AUTHORING_PROFILE_IDS = void 0;
|
|
10
10
|
const one_line_1 = require("../composition/one_line");
|
|
11
|
+
const primitive_pack_1 = require("../pack/primitive_pack");
|
|
11
12
|
/** Every {@link AuthoringProfileId}. */
|
|
12
13
|
exports.AUTHORING_PROFILE_IDS = [
|
|
13
14
|
'general',
|
|
@@ -15,6 +16,8 @@ exports.AUTHORING_PROFILE_IDS = [
|
|
|
15
16
|
'compose-from-primitives',
|
|
16
17
|
];
|
|
17
18
|
const COMPOSE_INTRO_WITHOUT_SCHEMA = 'You compose views from scratch. Build a single JSON object that answers the question using only the primitives in the catalog below.';
|
|
19
|
+
/** The root shape, which a prompt without the composition schema shows nowhere else. */
|
|
20
|
+
const VIEW_ENVELOPE = 'A view is `{"type":"view","body":[…]}`: primitives go in `body`, and a primitive is never the view itself.';
|
|
18
21
|
const INDEX_INTRO = 'Each primitive is listed by type and purpose. Before using one, request its catalog entry and JSON Schema by type; compose only from primitives whose details you have.';
|
|
19
22
|
const PROFILE_INTROS = {
|
|
20
23
|
general: 'You author views: compact, host-portable operational displays expressed as a single JSON object. Route to a registered view when one answers the question; otherwise compose a view from the primitive catalog below.',
|
|
@@ -78,7 +81,7 @@ const renderIndex = (primitives, groups = []) => {
|
|
|
78
81
|
entries: types.flatMap((type) => byType.get(type) ?? []),
|
|
79
82
|
})),
|
|
80
83
|
{
|
|
81
|
-
title:
|
|
84
|
+
title: primitive_pack_1.UNCATEGORIZED_GROUP_TITLE,
|
|
82
85
|
entries: primitives.filter(({ type }) => !grouped.has(type)),
|
|
83
86
|
},
|
|
84
87
|
];
|
|
@@ -128,7 +131,9 @@ const buildAuthoringPrompt = (profile, context) => {
|
|
|
128
131
|
: PROFILE_INTROS[profile];
|
|
129
132
|
const sections = [
|
|
130
133
|
context.heading ?? '# View authoring',
|
|
131
|
-
|
|
134
|
+
schema === undefined
|
|
135
|
+
? `${context.intro ?? intro} ${VIEW_ENVELOPE}`
|
|
136
|
+
: (context.intro ?? intro),
|
|
132
137
|
`## Guide\n\n${context.guide}`,
|
|
133
138
|
];
|
|
134
139
|
if (context.rules !== undefined && context.rules.length > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../src/author/prompt.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 { oneLine } from '../composition/one_line';\nimport type { PrimitiveCatalogEntry } from '../define/primitive_module';\nimport type { PrimitiveGroup } from '../pack/primitive_pack';\n\ntype JsonSchema = Record<string, unknown>;\n\n/** Which authoring job the prompt frames for the model. */\nexport type AuthoringProfileId =\n 'general' | 'registered-view-router' | 'compose-from-primitives';\n\n/** Every {@link AuthoringProfileId}. */\nexport const AUTHORING_PROFILE_IDS: readonly AuthoringProfileId[] = [\n 'general',\n 'registered-view-router',\n 'compose-from-primitives',\n];\n\n/**\n * A registered view, declared structurally so this module does not import the\n * runtime. {@link RegisteredViewSummary} must stay assignable to this.\n */\nexport interface AuthoringViewSummary {\n id: string;\n title: string;\n description?: string;\n /** Natural-language queries the view answers, printed so the model can route by them. */\n answers: readonly string[];\n /** JSON Schema for the view's input, printed inline when present. */\n inputSchema?: JsonSchema;\n}\n\n/** The pack-supplied material {@link buildAuthoringPrompt} assembles. */\nexport interface AuthoringPromptContext {\n guide: string;\n /** Absent or empty drops the `## Rules` section. */\n rules?: string;\n /** JSON Schema for a whole composition. Absent, or under the router profile, it is not inlined. */\n schema?: JsonSchema;\n /** Rendered as a bullet per entry, with its `useWhen`, `avoidWhen`, and `example`. */\n primitives: readonly PrimitiveCatalogEntry[];\n /** `'index'` lists each primitive's type and purpose only, for a host that serves the rest on request. */\n catalog?: 'full' | 'index';\n /** Headings an index sorts primitives under; a type in none is listed under \"Other\". */\n groups?: readonly PrimitiveGroup[];\n /**\n * Extra host-supplied compositions beyond each primitive's catalog example.\n * Trimmed to the profile's budget. An empty list drops `## Examples`.\n */\n examples: readonly unknown[];\n /** Registered views the model can request by id. An empty list drops the section. */\n views?: readonly AuthoringViewSummary[];\n /** Defaults to `'# View authoring'`. */\n heading?: string;\n /** Replaces the profile's own framing sentence. */\n intro?: string;\n}\n\nconst COMPOSE_INTRO_WITHOUT_SCHEMA =\n 'You compose views from scratch. Build a single JSON object that answers the question using only the primitives in the catalog below.';\n\nconst INDEX_INTRO =\n 'Each primitive is listed by type and purpose. Before using one, request its catalog entry and JSON Schema by type; compose only from primitives whose details you have.';\n\nconst PROFILE_INTROS: Record<AuthoringProfileId, string> = {\n general:\n 'You author views: compact, host-portable operational displays expressed as a single JSON object. Route to a registered view when one answers the question; otherwise compose a view from the primitive catalog below.',\n 'registered-view-router':\n 'You route questions to registered views. Prefer an existing registered view whose answers index matches the question; request it by id with its input. Only fall back to composing a view when no registered view fits, using the catalog below.',\n 'compose-from-primitives':\n 'You compose views from scratch. Build a single JSON object that answers the question using only the primitives in the catalog below, and validate your output mentally against the JSON Schema before responding.',\n};\n\n/** Host-supplied composition examples kept after each primitive already shows its shape. */\nconst PROFILE_EXAMPLE_LIMITS: Record<AuthoringProfileId, number> = {\n general: 1,\n 'registered-view-router': 0,\n 'compose-from-primitives': 1,\n};\n\nconst PROFILE_INCLUDES_SCHEMA: Record<AuthoringProfileId, boolean> = {\n general: true,\n 'registered-view-router': false,\n 'compose-from-primitives': true,\n};\n\n/** Minified JSON with U+2028 and U+2029 escaped, so it always prints on one line. */\nconst compactJson = (value: unknown): string =>\n String(JSON.stringify(value)).replace(\n /[\\u2028\\u2029]/g,\n (separator) => `\\\\u${separator.charCodeAt(0).toString(16)}`\n );\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\n/** Host examples show composition, not provenance. */\nconst withoutMeta = (value: unknown): unknown => {\n if (!isRecord(value) || !('meta' in value)) {\n return value;\n }\n const rest = { ...value };\n delete rest.meta;\n return rest;\n};\n\n/** `text` as a Markdown code span, fenced longer than any backtick run inside it. */\nconst codeSpan = (text: string): string => {\n const longestRun = Math.max(\n 0,\n ...(text.match(/`+/g) ?? []).map(({ length }) => length)\n );\n const fence = '`'.repeat(longestRun + 1);\n const pad = /^`|`$/.test(text) ? ' ' : '';\n return `${fence}${pad}${text}${pad}${fence}`;\n};\n\n/** A lookup key as a code span, JSON-quoted when it would not survive printing bare. */\nconst keySpan = (key: string): string =>\n codeSpan(\n key !== '' && key.trim() === key && !/[\\p{Cc}\\p{Cs}\\u2028\\u2029]/u.test(key)\n ? key\n : compactJson(key)\n );\n\n/** One primitive's catalog bullet: its purpose, `useWhen`, `avoidWhen`, and example. */\nexport const formatPrimitiveEntry = (entry: PrimitiveCatalogEntry): string => {\n const lines = [`- ${keySpan(entry.type)} — ${oneLine(entry.purpose)}`];\n if (entry.useWhen.length > 0) {\n lines.push(` - Use when: ${oneLine(entry.useWhen.join(' '))}`);\n }\n if (entry.avoidWhen.length > 0) {\n lines.push(` - Avoid when: ${oneLine(entry.avoidWhen.join(' '))}`);\n }\n lines.push(` - Example: ${codeSpan(compactJson(entry.example))}`);\n return lines.join('\\n');\n};\n\nconst renderCatalog = (primitives: readonly PrimitiveCatalogEntry[]): string =>\n primitives.map(formatPrimitiveEntry).join('\\n');\n\nconst renderIndex = (\n primitives: readonly PrimitiveCatalogEntry[],\n groups: readonly PrimitiveGroup[] = []\n): string => {\n const byType = new Map(primitives.map((entry) => [entry.type, entry]));\n const grouped = new Set(groups.flatMap(({ types }) => types));\n const sections = [\n ...groups.map(({ title, types }) => ({\n title,\n entries: types.flatMap((type) => byType.get(type) ?? []),\n })),\n {\n title: 'Other',\n entries: primitives.filter(({ type }) => !grouped.has(type)),\n },\n ];\n return [\n INDEX_INTRO,\n ...sections\n .filter(({ entries }) => entries.length > 0)\n .map(\n ({ title, entries }) =>\n `### ${oneLine(title)}\\n\\n${entries\n .map(\n ({ type, purpose }) => `- ${keySpan(type)} — ${oneLine(purpose)}`\n )\n .join('\\n')}`\n ),\n ].join('\\n\\n');\n};\n\nconst renderViews = (views: readonly AuthoringViewSummary[]): string =>\n views\n .map((view) => {\n const lines = [`- ${keySpan(view.id)} — ${oneLine(view.title)}`];\n if (view.description !== undefined && view.description.length > 0) {\n lines.push(` - ${oneLine(view.description)}`);\n }\n if (view.answers.length > 0) {\n lines.push(` - Answers: ${oneLine(view.answers.join('; '))}`);\n }\n if (view.inputSchema !== undefined) {\n lines.push(` - Input: ${codeSpan(compactJson(view.inputSchema))}`);\n }\n return lines.join('\\n');\n })\n .join('\\n');\n\nconst renderExamples = (examples: readonly unknown[]): string =>\n examples\n .map(\n (example) => `\\`\\`\\`json\\n${compactJson(withoutMeta(example))}\\n\\`\\`\\``\n )\n .join('\\n\\n');\n\n/**\n * Assembles `context` into the prompt for `profile`, trimming the examples to\n * that profile's budget.\n *\n * The copy says \"view\" throughout because that is the wire discriminator and\n * the word models are trained and prompted on; pass `heading` and `intro` to\n * override it per host.\n */\nexport const buildAuthoringPrompt = (\n profile: AuthoringProfileId,\n context: AuthoringPromptContext\n): string => {\n const examples = context.examples\n .slice(0, PROFILE_EXAMPLE_LIMITS[profile])\n .map(withoutMeta);\n const views = context.views ?? [];\n const schema = PROFILE_INCLUDES_SCHEMA[profile] ? context.schema : undefined;\n const intro =\n profile === 'compose-from-primitives' && schema === undefined\n ? COMPOSE_INTRO_WITHOUT_SCHEMA\n : PROFILE_INTROS[profile];\n const sections = [\n context.heading ?? '# View authoring',\n context.intro ?? intro,\n `## Guide\\n\\n${context.guide}`,\n ];\n if (context.rules !== undefined && context.rules.length > 0) {\n sections.push(`## Rules\\n\\n${context.rules}`);\n }\n if (views.length > 0) {\n sections.push(`## Registered views\\n\\n${renderViews(views)}`);\n }\n const catalog =\n context.catalog === 'index'\n ? renderIndex(context.primitives, context.groups)\n : renderCatalog(context.primitives);\n sections.push(`## Primitive catalog\\n\\n${catalog}`);\n if (schema !== undefined) {\n sections.push(\n `## JSON Schema\\n\\n\\`\\`\\`json\\n${compactJson(schema)}\\n\\`\\`\\``\n );\n }\n if (examples.length > 0) {\n sections.push(`## Examples\\n\\n${renderExamples(examples)}`);\n }\n return sections.join('\\n\\n');\n};\n"]}
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../src/author/prompt.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 { oneLine } from '../composition/one_line';\nimport type { PrimitiveCatalogEntry } from '../define/primitive_module';\nimport {\n type PrimitiveGroup,\n UNCATEGORIZED_GROUP_TITLE,\n} from '../pack/primitive_pack';\n\ntype JsonSchema = Record<string, unknown>;\n\n/** Which authoring job the prompt frames for the model. */\nexport type AuthoringProfileId =\n 'general' | 'registered-view-router' | 'compose-from-primitives';\n\n/** Every {@link AuthoringProfileId}. */\nexport const AUTHORING_PROFILE_IDS: readonly AuthoringProfileId[] = [\n 'general',\n 'registered-view-router',\n 'compose-from-primitives',\n];\n\n/**\n * A registered view, declared structurally so this module does not import the\n * runtime. {@link RegisteredViewSummary} must stay assignable to this.\n */\nexport interface AuthoringViewSummary {\n id: string;\n title: string;\n description?: string;\n /** Natural-language queries the view answers, printed so the model can route by them. */\n answers: readonly string[];\n /** JSON Schema for the view's input, printed inline when present. */\n inputSchema?: JsonSchema;\n}\n\n/** The pack-supplied material {@link buildAuthoringPrompt} assembles. */\nexport interface AuthoringPromptContext {\n guide: string;\n /** Absent or empty drops the `## Rules` section. */\n rules?: string;\n /** JSON Schema for a whole composition. Absent, or under the router profile, it is not inlined. */\n schema?: JsonSchema;\n /** Rendered as a bullet per entry, with its `useWhen`, `avoidWhen`, and `example`. */\n primitives: readonly PrimitiveCatalogEntry[];\n /** `'index'` lists each primitive's type and purpose only, for a host that serves the rest on request. */\n catalog?: 'full' | 'index';\n /** Headings an index sorts primitives under; a type in none is listed under {@link UNCATEGORIZED_GROUP_TITLE}. */\n groups?: readonly PrimitiveGroup[];\n /**\n * Extra host-supplied compositions beyond each primitive's catalog example.\n * Trimmed to the profile's budget. An empty list drops `## Examples`.\n */\n examples: readonly unknown[];\n /** Registered views the model can request by id. An empty list drops the section. */\n views?: readonly AuthoringViewSummary[];\n /** Defaults to `'# View authoring'`. */\n heading?: string;\n /** Replaces the profile's own framing sentence. */\n intro?: string;\n}\n\nconst COMPOSE_INTRO_WITHOUT_SCHEMA =\n 'You compose views from scratch. Build a single JSON object that answers the question using only the primitives in the catalog below.';\n\n/** The root shape, which a prompt without the composition schema shows nowhere else. */\nconst VIEW_ENVELOPE =\n 'A view is `{\"type\":\"view\",\"body\":[…]}`: primitives go in `body`, and a primitive is never the view itself.';\n\nconst INDEX_INTRO =\n 'Each primitive is listed by type and purpose. Before using one, request its catalog entry and JSON Schema by type; compose only from primitives whose details you have.';\n\nconst PROFILE_INTROS: Record<AuthoringProfileId, string> = {\n general:\n 'You author views: compact, host-portable operational displays expressed as a single JSON object. Route to a registered view when one answers the question; otherwise compose a view from the primitive catalog below.',\n 'registered-view-router':\n 'You route questions to registered views. Prefer an existing registered view whose answers index matches the question; request it by id with its input. Only fall back to composing a view when no registered view fits, using the catalog below.',\n 'compose-from-primitives':\n 'You compose views from scratch. Build a single JSON object that answers the question using only the primitives in the catalog below, and validate your output mentally against the JSON Schema before responding.',\n};\n\n/** Host-supplied composition examples kept after each primitive already shows its shape. */\nconst PROFILE_EXAMPLE_LIMITS: Record<AuthoringProfileId, number> = {\n general: 1,\n 'registered-view-router': 0,\n 'compose-from-primitives': 1,\n};\n\nconst PROFILE_INCLUDES_SCHEMA: Record<AuthoringProfileId, boolean> = {\n general: true,\n 'registered-view-router': false,\n 'compose-from-primitives': true,\n};\n\n/** Minified JSON with U+2028 and U+2029 escaped, so it always prints on one line. */\nconst compactJson = (value: unknown): string =>\n String(JSON.stringify(value)).replace(\n /[\\u2028\\u2029]/g,\n (separator) => `\\\\u${separator.charCodeAt(0).toString(16)}`\n );\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\n/** Host examples show composition, not provenance. */\nconst withoutMeta = (value: unknown): unknown => {\n if (!isRecord(value) || !('meta' in value)) {\n return value;\n }\n const rest = { ...value };\n delete rest.meta;\n return rest;\n};\n\n/** `text` as a Markdown code span, fenced longer than any backtick run inside it. */\nconst codeSpan = (text: string): string => {\n const longestRun = Math.max(\n 0,\n ...(text.match(/`+/g) ?? []).map(({ length }) => length)\n );\n const fence = '`'.repeat(longestRun + 1);\n const pad = /^`|`$/.test(text) ? ' ' : '';\n return `${fence}${pad}${text}${pad}${fence}`;\n};\n\n/** A lookup key as a code span, JSON-quoted when it would not survive printing bare. */\nconst keySpan = (key: string): string =>\n codeSpan(\n key !== '' && key.trim() === key && !/[\\p{Cc}\\p{Cs}\\u2028\\u2029]/u.test(key)\n ? key\n : compactJson(key)\n );\n\n/** One primitive's catalog bullet: its purpose, `useWhen`, `avoidWhen`, and example. */\nexport const formatPrimitiveEntry = (entry: PrimitiveCatalogEntry): string => {\n const lines = [`- ${keySpan(entry.type)} — ${oneLine(entry.purpose)}`];\n if (entry.useWhen.length > 0) {\n lines.push(` - Use when: ${oneLine(entry.useWhen.join(' '))}`);\n }\n if (entry.avoidWhen.length > 0) {\n lines.push(` - Avoid when: ${oneLine(entry.avoidWhen.join(' '))}`);\n }\n lines.push(` - Example: ${codeSpan(compactJson(entry.example))}`);\n return lines.join('\\n');\n};\n\nconst renderCatalog = (primitives: readonly PrimitiveCatalogEntry[]): string =>\n primitives.map(formatPrimitiveEntry).join('\\n');\n\nconst renderIndex = (\n primitives: readonly PrimitiveCatalogEntry[],\n groups: readonly PrimitiveGroup[] = []\n): string => {\n const byType = new Map(primitives.map((entry) => [entry.type, entry]));\n const grouped = new Set(groups.flatMap(({ types }) => types));\n const sections = [\n ...groups.map(({ title, types }) => ({\n title,\n entries: types.flatMap((type) => byType.get(type) ?? []),\n })),\n {\n title: UNCATEGORIZED_GROUP_TITLE,\n entries: primitives.filter(({ type }) => !grouped.has(type)),\n },\n ];\n return [\n INDEX_INTRO,\n ...sections\n .filter(({ entries }) => entries.length > 0)\n .map(\n ({ title, entries }) =>\n `### ${oneLine(title)}\\n\\n${entries\n .map(\n ({ type, purpose }) => `- ${keySpan(type)} — ${oneLine(purpose)}`\n )\n .join('\\n')}`\n ),\n ].join('\\n\\n');\n};\n\nconst renderViews = (views: readonly AuthoringViewSummary[]): string =>\n views\n .map((view) => {\n const lines = [`- ${keySpan(view.id)} — ${oneLine(view.title)}`];\n if (view.description !== undefined && view.description.length > 0) {\n lines.push(` - ${oneLine(view.description)}`);\n }\n if (view.answers.length > 0) {\n lines.push(` - Answers: ${oneLine(view.answers.join('; '))}`);\n }\n if (view.inputSchema !== undefined) {\n lines.push(` - Input: ${codeSpan(compactJson(view.inputSchema))}`);\n }\n return lines.join('\\n');\n })\n .join('\\n');\n\nconst renderExamples = (examples: readonly unknown[]): string =>\n examples\n .map(\n (example) => `\\`\\`\\`json\\n${compactJson(withoutMeta(example))}\\n\\`\\`\\``\n )\n .join('\\n\\n');\n\n/**\n * Assembles `context` into the prompt for `profile`, trimming the examples to\n * that profile's budget.\n *\n * The copy says \"view\" throughout because that is the wire discriminator and\n * the word models are trained and prompted on; pass `heading` and `intro` to\n * override it per host.\n */\nexport const buildAuthoringPrompt = (\n profile: AuthoringProfileId,\n context: AuthoringPromptContext\n): string => {\n const examples = context.examples\n .slice(0, PROFILE_EXAMPLE_LIMITS[profile])\n .map(withoutMeta);\n const views = context.views ?? [];\n const schema = PROFILE_INCLUDES_SCHEMA[profile] ? context.schema : undefined;\n const intro =\n profile === 'compose-from-primitives' && schema === undefined\n ? COMPOSE_INTRO_WITHOUT_SCHEMA\n : PROFILE_INTROS[profile];\n const sections = [\n context.heading ?? '# View authoring',\n schema === undefined\n ? `${context.intro ?? intro} ${VIEW_ENVELOPE}`\n : (context.intro ?? intro),\n `## Guide\\n\\n${context.guide}`,\n ];\n if (context.rules !== undefined && context.rules.length > 0) {\n sections.push(`## Rules\\n\\n${context.rules}`);\n }\n if (views.length > 0) {\n sections.push(`## Registered views\\n\\n${renderViews(views)}`);\n }\n const catalog =\n context.catalog === 'index'\n ? renderIndex(context.primitives, context.groups)\n : renderCatalog(context.primitives);\n sections.push(`## Primitive catalog\\n\\n${catalog}`);\n if (schema !== undefined) {\n sections.push(\n `## JSON Schema\\n\\n\\`\\`\\`json\\n${compactJson(schema)}\\n\\`\\`\\``\n );\n }\n if (examples.length > 0) {\n sections.push(`## Examples\\n\\n${renderExamples(examples)}`);\n }\n return sections.join('\\n\\n');\n};\n"]}
|