@elastic/isomer-sdk 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.txt +0 -286
- package/THIRD_PARTY_LICENSES.md +1 -885
- package/dist/author/authored_fields.d.ts +37 -12
- package/dist/author/authored_fields.d.ts.map +1 -1
- package/dist/author/authored_fields.js +45 -69
- package/dist/author/authored_fields.js.map +1 -1
- package/dist/author/authoring_input.d.ts.map +1 -1
- package/dist/author/authoring_input.js +12 -6
- package/dist/author/authoring_input.js.map +1 -1
- package/dist/author/authoring_model.d.ts +8 -2
- package/dist/author/authoring_model.d.ts.map +1 -1
- package/dist/author/authoring_model.js +67 -23
- package/dist/author/authoring_model.js.map +1 -1
- package/dist/author/declarations.d.ts.map +1 -1
- package/dist/author/declarations.js +45 -34
- package/dist/author/declarations.js.map +1 -1
- package/dist/author/index.d.ts +2 -1
- package/dist/author/index.d.ts.map +1 -1
- package/dist/author/index.js +2 -1
- package/dist/author/index.js.map +1 -1
- package/dist/author/jsx_shim.d.ts +49 -30
- package/dist/author/jsx_shim.d.ts.map +1 -1
- package/dist/author/jsx_shim.js +131 -40
- package/dist/author/jsx_shim.js.map +1 -1
- package/dist/author/print_jsx.d.ts +19 -0
- package/dist/author/print_jsx.d.ts.map +1 -0
- package/dist/author/print_jsx.js +372 -0
- package/dist/author/print_jsx.js.map +1 -0
- package/dist/author/prompt.d.ts +2 -2
- package/dist/author/prompt.d.ts.map +1 -1
- package/dist/author/prompt.js +7 -2
- package/dist/author/prompt.js.map +1 -1
- package/dist/author/schema_to_typescript.d.ts.map +1 -1
- package/dist/author/schema_to_typescript.js +6 -3
- package/dist/author/schema_to_typescript.js.map +1 -1
- package/dist/cjs/author/authored_fields.js +47 -70
- package/dist/cjs/author/authored_fields.js.map +1 -1
- package/dist/cjs/author/authoring_input.js +12 -6
- package/dist/cjs/author/authoring_input.js.map +1 -1
- package/dist/cjs/author/authoring_model.js +69 -24
- package/dist/cjs/author/authoring_model.js.map +1 -1
- package/dist/cjs/author/declarations.js +44 -33
- package/dist/cjs/author/declarations.js.map +1 -1
- package/dist/cjs/author/index.js +5 -1
- package/dist/cjs/author/index.js.map +1 -1
- package/dist/cjs/author/jsx_shim.js +130 -39
- package/dist/cjs/author/jsx_shim.js.map +1 -1
- package/dist/cjs/author/print_jsx.js +378 -0
- package/dist/cjs/author/print_jsx.js.map +1 -0
- package/dist/cjs/author/prompt.js +7 -2
- package/dist/cjs/author/prompt.js.map +1 -1
- package/dist/cjs/author/schema_to_typescript.js +6 -3
- package/dist/cjs/author/schema_to_typescript.js.map +1 -1
- package/dist/cjs/composition/error.js +2 -0
- package/dist/cjs/composition/error.js.map +1 -1
- package/dist/cjs/composition/structured_value.js.map +1 -1
- package/dist/cjs/define/index.js.map +1 -1
- package/dist/cjs/define/primitive_module.js +10 -4
- package/dist/cjs/define/primitive_module.js.map +1 -1
- package/dist/cjs/define/slack_blocks.js.map +1 -1
- package/dist/cjs/entries/index.js +5 -2
- package/dist/cjs/entries/index.js.map +1 -1
- package/dist/cjs/entries/markdown.js +3 -1
- package/dist/cjs/entries/markdown.js.map +1 -1
- package/dist/cjs/entries/react.js +2 -1
- package/dist/cjs/entries/react.js.map +1 -1
- package/dist/cjs/entries/slack.js +5 -1
- package/dist/cjs/entries/slack.js.map +1 -1
- package/dist/cjs/pack/enhancements.js.map +1 -1
- package/dist/cjs/pack/index.js +2 -1
- package/dist/cjs/pack/index.js.map +1 -1
- package/dist/cjs/pack/primitive_pack.js +14 -4
- package/dist/cjs/pack/primitive_pack.js.map +1 -1
- package/dist/cjs/render/format_number.js +2 -1
- package/dist/cjs/render/format_number.js.map +1 -1
- package/dist/cjs/render/html/envelope.js +12 -6
- package/dist/cjs/render/html/envelope.js.map +1 -1
- package/dist/cjs/render/markdown/blocks.js +82 -0
- package/dist/cjs/render/markdown/blocks.js.map +1 -0
- package/dist/cjs/render/markdown/builder.js +6 -2
- package/dist/cjs/render/markdown/builder.js.map +1 -1
- package/dist/cjs/render/markdown/format.js +46 -24
- package/dist/cjs/render/markdown/format.js.map +1 -1
- package/dist/cjs/render/markdown/host_tags.js +67 -0
- package/dist/cjs/render/markdown/host_tags.js.map +1 -0
- package/dist/cjs/render/markdown/index.js +5 -1
- package/dist/cjs/render/markdown/index.js.map +1 -1
- package/dist/cjs/render/markdown/split.js +325 -0
- package/dist/cjs/render/markdown/split.js.map +1 -0
- package/dist/cjs/render/primitive_dispatch.js +36 -6
- package/dist/cjs/render/primitive_dispatch.js.map +1 -1
- package/dist/cjs/render/react/content.js +3 -1
- package/dist/cjs/render/react/content.js.map +1 -1
- package/dist/cjs/render/react/index.js +3 -1
- package/dist/cjs/render/react/index.js.map +1 -1
- package/dist/cjs/render/react/markdown_content.js +143 -0
- package/dist/cjs/render/react/markdown_content.js.map +1 -0
- package/dist/cjs/render/slack/blocks.js +7 -0
- package/dist/cjs/render/slack/blocks.js.map +1 -1
- package/dist/cjs/render/slack/container.js +62 -0
- package/dist/cjs/render/slack/container.js.map +1 -0
- package/dist/cjs/render/slack/envelope.js +70 -14
- package/dist/cjs/render/slack/envelope.js.map +1 -1
- package/dist/cjs/render/slack/format.js +56 -6
- package/dist/cjs/render/slack/format.js.map +1 -1
- package/dist/cjs/render/slack/index.js +7 -1
- package/dist/cjs/render/slack/index.js.map +1 -1
- package/dist/cjs/render/slack/markdown_content.js +36 -77
- package/dist/cjs/render/slack/markdown_content.js.map +1 -1
- package/dist/cjs/render/slack/unmodeled.js +38 -0
- package/dist/cjs/render/slack/unmodeled.js.map +1 -0
- package/dist/cjs/testing/conformance.js +15 -1
- package/dist/cjs/testing/conformance.js.map +1 -1
- package/dist/cjs/testing/index.js +2 -1
- package/dist/cjs/testing/index.js.map +1 -1
- package/dist/cjs/validate/json_schema.js +10 -3
- package/dist/cjs/validate/json_schema.js.map +1 -1
- package/dist/cjs/validate/url.js +2 -1
- package/dist/cjs/validate/url.js.map +1 -1
- package/dist/composition/error.d.ts +2 -0
- package/dist/composition/error.d.ts.map +1 -1
- package/dist/composition/error.js +2 -0
- package/dist/composition/error.js.map +1 -1
- package/dist/composition/structured_value.d.ts +3 -3
- package/dist/composition/structured_value.d.ts.map +1 -1
- package/dist/composition/structured_value.js.map +1 -1
- package/dist/define/index.d.ts +1 -1
- package/dist/define/index.d.ts.map +1 -1
- package/dist/define/index.js.map +1 -1
- package/dist/define/primitive_module.d.ts +14 -5
- package/dist/define/primitive_module.d.ts.map +1 -1
- package/dist/define/primitive_module.js +10 -4
- package/dist/define/primitive_module.js.map +1 -1
- package/dist/define/slack_blocks.d.ts +31 -1
- package/dist/define/slack_blocks.d.ts.map +1 -1
- package/dist/define/slack_blocks.js.map +1 -1
- package/dist/entries/index.d.ts +2 -2
- package/dist/entries/index.d.ts.map +1 -1
- package/dist/entries/index.js +2 -2
- package/dist/entries/index.js.map +1 -1
- package/dist/entries/markdown.d.ts +1 -1
- package/dist/entries/markdown.d.ts.map +1 -1
- package/dist/entries/markdown.js +1 -1
- package/dist/entries/markdown.js.map +1 -1
- package/dist/entries/react.d.ts +1 -1
- package/dist/entries/react.d.ts.map +1 -1
- package/dist/entries/react.js +1 -1
- package/dist/entries/react.js.map +1 -1
- package/dist/entries/slack.d.ts +1 -1
- package/dist/entries/slack.d.ts.map +1 -1
- package/dist/entries/slack.js +1 -1
- package/dist/entries/slack.js.map +1 -1
- package/dist/pack/enhancements.d.ts +4 -0
- package/dist/pack/enhancements.d.ts.map +1 -1
- package/dist/pack/enhancements.js.map +1 -1
- package/dist/pack/index.d.ts +1 -1
- package/dist/pack/index.d.ts.map +1 -1
- package/dist/pack/index.js +1 -1
- package/dist/pack/index.js.map +1 -1
- package/dist/pack/primitive_pack.d.ts +3 -1
- package/dist/pack/primitive_pack.d.ts.map +1 -1
- package/dist/pack/primitive_pack.js +13 -3
- package/dist/pack/primitive_pack.js.map +1 -1
- package/dist/render/format_number.d.ts.map +1 -1
- package/dist/render/format_number.js +2 -1
- package/dist/render/format_number.js.map +1 -1
- package/dist/render/html/envelope.js +12 -6
- package/dist/render/html/envelope.js.map +1 -1
- package/dist/render/markdown/blocks.d.ts +6 -0
- package/dist/render/markdown/blocks.d.ts.map +1 -0
- package/dist/render/markdown/blocks.js +77 -0
- package/dist/render/markdown/blocks.js.map +1 -0
- package/dist/render/markdown/builder.d.ts +3 -0
- package/dist/render/markdown/builder.d.ts.map +1 -1
- package/dist/render/markdown/builder.js +3 -1
- package/dist/render/markdown/builder.js.map +1 -1
- package/dist/render/markdown/format.d.ts +2 -0
- package/dist/render/markdown/format.d.ts.map +1 -1
- package/dist/render/markdown/format.js +42 -22
- package/dist/render/markdown/format.js.map +1 -1
- package/dist/render/markdown/host_tags.d.ts +14 -0
- package/dist/render/markdown/host_tags.d.ts.map +1 -0
- package/dist/render/markdown/host_tags.js +63 -0
- package/dist/render/markdown/host_tags.js.map +1 -0
- package/dist/render/markdown/index.d.ts +2 -0
- package/dist/render/markdown/index.d.ts.map +1 -1
- package/dist/render/markdown/index.js +2 -0
- package/dist/render/markdown/index.js.map +1 -1
- package/dist/render/markdown/split.d.ts +32 -0
- package/dist/render/markdown/split.d.ts.map +1 -0
- package/dist/render/markdown/split.js +321 -0
- package/dist/render/markdown/split.js.map +1 -0
- package/dist/render/primitive_dispatch.d.ts +4 -2
- package/dist/render/primitive_dispatch.d.ts.map +1 -1
- package/dist/render/primitive_dispatch.js +36 -6
- package/dist/render/primitive_dispatch.js.map +1 -1
- package/dist/render/react/content.d.ts +1 -1
- package/dist/render/react/content.d.ts.map +1 -1
- package/dist/render/react/content.js +3 -1
- package/dist/render/react/content.js.map +1 -1
- package/dist/render/react/index.d.ts +1 -0
- package/dist/render/react/index.d.ts.map +1 -1
- package/dist/render/react/index.js +1 -0
- package/dist/render/react/index.js.map +1 -1
- package/dist/render/react/markdown_content.d.ts +9 -0
- package/dist/render/react/markdown_content.d.ts.map +1 -0
- package/dist/render/react/markdown_content.js +139 -0
- package/dist/render/react/markdown_content.js.map +1 -0
- package/dist/render/slack/blocks.d.ts +8 -1
- package/dist/render/slack/blocks.d.ts.map +1 -1
- package/dist/render/slack/blocks.js +7 -0
- package/dist/render/slack/blocks.js.map +1 -1
- package/dist/render/slack/container.d.ts +25 -0
- package/dist/render/slack/container.d.ts.map +1 -0
- package/dist/render/slack/container.js +55 -0
- package/dist/render/slack/container.js.map +1 -0
- package/dist/render/slack/envelope.d.ts +6 -4
- package/dist/render/slack/envelope.d.ts.map +1 -1
- package/dist/render/slack/envelope.js +71 -15
- package/dist/render/slack/envelope.js.map +1 -1
- package/dist/render/slack/format.d.ts +15 -3
- package/dist/render/slack/format.d.ts.map +1 -1
- package/dist/render/slack/format.js +54 -5
- package/dist/render/slack/format.js.map +1 -1
- package/dist/render/slack/index.d.ts +4 -2
- package/dist/render/slack/index.d.ts.map +1 -1
- package/dist/render/slack/index.js +2 -0
- package/dist/render/slack/index.js.map +1 -1
- package/dist/render/slack/markdown_content.d.ts +3 -2
- package/dist/render/slack/markdown_content.d.ts.map +1 -1
- package/dist/render/slack/markdown_content.js +27 -68
- package/dist/render/slack/markdown_content.js.map +1 -1
- package/dist/render/slack/unmodeled.d.ts +16 -0
- package/dist/render/slack/unmodeled.d.ts.map +1 -0
- package/dist/render/slack/unmodeled.js +32 -0
- package/dist/render/slack/unmodeled.js.map +1 -0
- package/dist/testing/conformance.d.ts +3 -1
- package/dist/testing/conformance.d.ts.map +1 -1
- package/dist/testing/conformance.js +14 -0
- package/dist/testing/conformance.js.map +1 -1
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +1 -1
- package/dist/testing/index.js.map +1 -1
- package/dist/validate/json_schema.d.ts.map +1 -1
- package/dist/validate/json_schema.js +10 -3
- package/dist/validate/json_schema.js.map +1 -1
- package/dist/validate/url.d.ts.map +1 -1
- package/dist/validate/url.js +2 -1
- package/dist/validate/url.js.map +1 -1
- package/package.json +2 -2
|
@@ -7,10 +7,9 @@
|
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.gfmToSlackBlocks = exports.markdownContentToSlackBlocks = void 0;
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const format_2 = require("./format");
|
|
10
|
+
const blocks_1 = require("../markdown/blocks");
|
|
11
|
+
const blocks_2 = require("./blocks");
|
|
12
|
+
const format_1 = require("./format");
|
|
14
13
|
const footnoteLabel = ({ identifier, label, }) => `[^${label ?? identifier}]`;
|
|
15
14
|
const plainText = (node) => {
|
|
16
15
|
if ('value' in node) {
|
|
@@ -34,7 +33,7 @@ const textElement = (text, style) => {
|
|
|
34
33
|
// One link element per styled run of the label, so its formatting survives;
|
|
35
34
|
// an empty label is a bare link. A URL Slack cannot link leaves the label.
|
|
36
35
|
const linkRuns = (href, runs, style) => {
|
|
37
|
-
const url = (0,
|
|
36
|
+
const url = (0, format_1.slackLinkUrl)(href);
|
|
38
37
|
if (url === null) {
|
|
39
38
|
return runs;
|
|
40
39
|
}
|
|
@@ -68,7 +67,7 @@ const inline = (nodes, style = {}) => nodes.flatMap((node) => {
|
|
|
68
67
|
const inlineText = (element) => element.type === 'link' ? (element.text ?? element.url) : element.text;
|
|
69
68
|
// The envelope leaves rich text alone, so a section keeps to the budget of a
|
|
70
69
|
// `section` block's text.
|
|
71
|
-
const clampInline = (elements, budget =
|
|
70
|
+
const clampInline = (elements, budget = blocks_2.SLACK_LIMITS.sectionTextChars) => {
|
|
72
71
|
const kept = [];
|
|
73
72
|
let spent = 0;
|
|
74
73
|
for (const element of elements) {
|
|
@@ -79,7 +78,7 @@ const clampInline = (elements, budget = blocks_1.SLACK_LIMITS.sectionTextChars)
|
|
|
79
78
|
spent += length;
|
|
80
79
|
continue;
|
|
81
80
|
}
|
|
82
|
-
const text = rest > 0 ? (0,
|
|
81
|
+
const text = rest > 0 ? (0, format_1.clampSlackText)(inlineText(element), rest) : '';
|
|
83
82
|
if (text !== '') {
|
|
84
83
|
kept.push({ ...element, text });
|
|
85
84
|
}
|
|
@@ -110,7 +109,8 @@ const unquoted = (node) => node.type === 'blockquote' ? node.children.flatMap(un
|
|
|
110
109
|
// nested list follows at the next indent; any other block, such as a table,
|
|
111
110
|
// follows on its own; what the item holds after either follows unbulleted,
|
|
112
111
|
// since a Slack list item cannot resume; and the list resumes at its next
|
|
113
|
-
// number.
|
|
112
|
+
// number. An empty item keeps its number, so the list resumes past it. A task
|
|
113
|
+
// item's first line leads with its box.
|
|
114
114
|
const listPieces = (list, indent) => {
|
|
115
115
|
const style = list.ordered ? 'ordered' : 'bullet';
|
|
116
116
|
const out = [];
|
|
@@ -161,7 +161,7 @@ const listPieces = (list, indent) => {
|
|
|
161
161
|
continue;
|
|
162
162
|
}
|
|
163
163
|
const pieces = child.type === 'list'
|
|
164
|
-
? listPieces(child, Math.min(indent + 1,
|
|
164
|
+
? listPieces(child, Math.min(indent + 1, blocks_2.SLACK_LIMITS.richTextListMaxIndent))
|
|
165
165
|
: blockPieces(child);
|
|
166
166
|
if (pieces.length > 0) {
|
|
167
167
|
emit();
|
|
@@ -170,6 +170,11 @@ const listPieces = (list, indent) => {
|
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
172
|
emit();
|
|
173
|
+
if (item.children.length === 0) {
|
|
174
|
+
flush();
|
|
175
|
+
number += 1;
|
|
176
|
+
offset = number - 1;
|
|
177
|
+
}
|
|
173
178
|
}
|
|
174
179
|
flush();
|
|
175
180
|
return out;
|
|
@@ -188,9 +193,9 @@ const tableCell = (cell) => {
|
|
|
188
193
|
// whose header has none prints nothing.
|
|
189
194
|
const tableBlock = (table) => {
|
|
190
195
|
const rows = table.children
|
|
191
|
-
.slice(0,
|
|
196
|
+
.slice(0, blocks_2.SLACK_LIMITS.tableRows)
|
|
192
197
|
.map((row) => row.children
|
|
193
|
-
.slice(0,
|
|
198
|
+
.slice(0, blocks_2.SLACK_LIMITS.tableColumns)
|
|
194
199
|
.map((cell) => tableCell(cell.children)));
|
|
195
200
|
const [header] = rows;
|
|
196
201
|
if (header === undefined || header.length === 0) {
|
|
@@ -275,7 +280,7 @@ const blockPieces = (node) => {
|
|
|
275
280
|
: [
|
|
276
281
|
{
|
|
277
282
|
type: 'rich_text_preformatted',
|
|
278
|
-
elements: textElement((0,
|
|
283
|
+
elements: textElement((0, format_1.clampSlackText)(node.value, blocks_2.SLACK_LIMITS.sectionTextChars), {}),
|
|
279
284
|
},
|
|
280
285
|
];
|
|
281
286
|
case 'list':
|
|
@@ -292,68 +297,22 @@ const blockPieces = (node) => {
|
|
|
292
297
|
return [];
|
|
293
298
|
}
|
|
294
299
|
};
|
|
295
|
-
// Each
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
switch (node.type) {
|
|
312
|
-
case 'linkReference':
|
|
313
|
-
return {
|
|
314
|
-
type: 'link',
|
|
315
|
-
url: definitions.get(node.identifier)?.url ?? '',
|
|
316
|
-
children: node.children.map(resolve),
|
|
317
|
-
};
|
|
318
|
-
case 'imageReference':
|
|
319
|
-
return {
|
|
320
|
-
type: 'image',
|
|
321
|
-
url: definitions.get(node.identifier)?.url ?? '',
|
|
322
|
-
alt: node.alt ?? null,
|
|
323
|
-
};
|
|
324
|
-
default:
|
|
325
|
-
return 'children' in node
|
|
326
|
-
? { ...node, children: node.children.map(resolve) }
|
|
327
|
-
: node;
|
|
328
|
-
}
|
|
329
|
-
};
|
|
330
|
-
return blocks.map(resolve);
|
|
331
|
-
};
|
|
332
|
-
const lines = (text) => text.replace(/\r\n?/g, '\n');
|
|
333
|
-
const literalParagraphs = (text) => lines(text)
|
|
334
|
-
.split(/\n[ \t]*\n/)
|
|
335
|
-
.filter((paragraph) => paragraph.trim() !== '')
|
|
336
|
-
.map((paragraph) => ({
|
|
337
|
-
type: 'paragraph',
|
|
338
|
-
children: [{ type: 'text', value: paragraph.trim() }],
|
|
339
|
-
}));
|
|
340
|
-
// Source past the parse budget prints as its literal paragraphs.
|
|
341
|
-
const gfmBlocks = (gfm) => {
|
|
342
|
-
const parsed = (0, format_1.parseGfmBlocks)(lines(gfm));
|
|
343
|
-
return parsed === null ? literalParagraphs(gfm) : withReferences(parsed);
|
|
344
|
-
};
|
|
345
|
-
// Markdown printed as written is read as the GFM it holds; authored source
|
|
346
|
-
// that sanitizing left inert is never parsed.
|
|
347
|
-
const expanded = (node) => {
|
|
348
|
-
if (node.type === builder_1.VERBATIM_TYPE) {
|
|
349
|
-
const { value, source } = node;
|
|
350
|
-
return source === undefined ? gfmBlocks(value) : literalParagraphs(source);
|
|
351
|
-
}
|
|
352
|
-
return 'children' in node
|
|
353
|
-
? [{ ...node, children: node.children.flatMap(expanded) }]
|
|
354
|
-
: [node];
|
|
355
|
-
};
|
|
356
|
-
const toSlackBlocks = (nodes) => {
|
|
300
|
+
// Each relative link resolved against `baseUrl`, ahead of `linkRuns`. An
|
|
301
|
+
// image's source is left alone: Slack draws none inline.
|
|
302
|
+
const rebased = (node, baseUrl) => ({
|
|
303
|
+
...node,
|
|
304
|
+
...('children' in node && {
|
|
305
|
+
children: node.children.map((child) => rebased(child, baseUrl)),
|
|
306
|
+
}),
|
|
307
|
+
...(node.type === 'link' && {
|
|
308
|
+
url: (0, format_1.slackLinkUrl)(node.url, baseUrl) ?? node.url,
|
|
309
|
+
}),
|
|
310
|
+
});
|
|
311
|
+
const toSlackBlocks = (input, { baseUrl }) => {
|
|
312
|
+
(0, format_1.assertSlackBaseUrl)(baseUrl);
|
|
313
|
+
const nodes = baseUrl === undefined
|
|
314
|
+
? input
|
|
315
|
+
: input.map((node) => rebased(node, baseUrl));
|
|
357
316
|
const blocks = [];
|
|
358
317
|
let elements = [];
|
|
359
318
|
const flush = () => {
|
|
@@ -367,7 +326,7 @@ const toSlackBlocks = (nodes) => {
|
|
|
367
326
|
? {
|
|
368
327
|
...element,
|
|
369
328
|
elements: [
|
|
370
|
-
...clampInline(element.elements,
|
|
329
|
+
...clampInline(element.elements, blocks_2.SLACK_LIMITS.sectionTextChars - 1),
|
|
371
330
|
{ type: 'text', text: '\n' },
|
|
372
331
|
],
|
|
373
332
|
}
|
|
@@ -397,13 +356,13 @@ const toSlackBlocks = (nodes) => {
|
|
|
397
356
|
* item's. A run of rich-text blocks shares one `rich_text` block. Source from
|
|
398
357
|
* `md.authored` is parsed as GFM and translated the same way.
|
|
399
358
|
*/
|
|
400
|
-
const markdownContentToSlackBlocks = (content) => toSlackBlocks((0,
|
|
359
|
+
const markdownContentToSlackBlocks = (content, options = {}) => toSlackBlocks((0, blocks_1.resolvedMarkdownBlocks)(content), options);
|
|
401
360
|
exports.markdownContentToSlackBlocks = markdownContentToSlackBlocks;
|
|
402
361
|
/**
|
|
403
362
|
* GFM as Block Kit, parsed as CommonMark with GFM and translated as
|
|
404
363
|
* {@link markdownContentToSlackBlocks} translates builder content. Source past
|
|
405
364
|
* the parse budget that `md.authored` applies prints as literal paragraphs.
|
|
406
365
|
*/
|
|
407
|
-
const gfmToSlackBlocks = (gfm) => toSlackBlocks(gfmBlocks(gfm));
|
|
366
|
+
const gfmToSlackBlocks = (gfm, options = {}) => toSlackBlocks((0, blocks_1.gfmBlocks)(gfm), options);
|
|
408
367
|
exports.gfmToSlackBlocks = gfmToSlackBlocks;
|
|
409
368
|
//# sourceMappingURL=markdown_content.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown_content.js","sourceRoot":"","sources":["../../../../src/render/slack/markdown_content.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\n// Markdown to Block Kit, read from the tree rather than re-parsed line by\n// line. Rich text carries formatting as style flags beside literal text, so\n// nothing is escaped and nesting survives exactly.\n\nimport type {\n Blockquote,\n Definition,\n FootnoteDefinition,\n List,\n ListItem,\n Nodes,\n Paragraph,\n PhrasingContent,\n RootContent,\n Table,\n} from 'mdast';\n\nimport type { MarkdownContent } from '../../define/markdown_content';\nimport { markdownBlocks, VERBATIM_TYPE } from '../markdown/builder';\nimport { parseGfmBlocks } from '../markdown/format';\n\nimport {\n SLACK_LIMITS,\n type SlackBlock,\n type SlackRichTextBlockElement,\n type SlackRichTextInline,\n type SlackRichTextSection,\n type SlackRichTextStyle,\n type SlackTableBlock,\n type SlackTableCell,\n} from './blocks';\nimport { clampSlackText, slackLinkUrl } from './format';\n\nconst footnoteLabel = ({\n identifier,\n label,\n}: Pick<FootnoteDefinition, 'identifier' | 'label'>): string =>\n `[^${label ?? identifier}]`;\n\nconst plainText = (node: Nodes): string => {\n if ('value' in node) {\n return node.value;\n }\n if (node.type === 'image') {\n return node.alt ?? '';\n }\n if (node.type === 'footnoteReference') {\n return footnoteLabel(node);\n }\n return 'children' in node ? node.children.map(plainText).join('') : '';\n};\n\nconst styled = (style: SlackRichTextStyle): SlackRichTextStyle | undefined =>\n Object.keys(style).length === 0 ? undefined : style;\n\nconst textElement = (\n text: string,\n style: SlackRichTextStyle\n): SlackRichTextInline[] => {\n const withStyle = styled(style);\n return text === ''\n ? []\n : [{ type: 'text', text, ...(withStyle ? { style: withStyle } : {}) }];\n};\n\n// One link element per styled run of the label, so its formatting survives;\n// an empty label is a bare link. A URL Slack cannot link leaves the label.\nconst linkRuns = (\n href: string,\n runs: SlackRichTextInline[],\n style: SlackRichTextStyle\n): SlackRichTextInline[] => {\n const url = slackLinkUrl(href);\n if (url === null) {\n return runs;\n }\n if (runs.length === 0) {\n const withStyle = styled(style);\n return [{ type: 'link', url, ...(withStyle ? { style: withStyle } : {}) }];\n }\n return runs.map((run) =>\n run.type === 'text' ? { ...run, type: 'link', url } : run\n );\n};\n\nconst inline = (\n nodes: readonly PhrasingContent[],\n style: SlackRichTextStyle = {}\n): SlackRichTextInline[] =>\n nodes.flatMap((node): SlackRichTextInline[] => {\n switch (node.type) {\n case 'strong':\n return inline(node.children, { ...style, bold: true });\n case 'emphasis':\n return inline(node.children, { ...style, italic: true });\n case 'delete':\n return inline(node.children, { ...style, strike: true });\n case 'inlineCode':\n return textElement(node.value, { ...style, code: true });\n case 'link':\n return linkRuns(node.url, inline(node.children, style), style);\n // Slack draws no inline image, so it links to the source.\n case 'image':\n return linkRuns(node.url, textElement(node.alt ?? '', style), style);\n case 'break':\n return textElement('\\n', style);\n default:\n return textElement(plainText(node), style);\n }\n });\n\nconst inlineText = (element: SlackRichTextInline): string =>\n element.type === 'link' ? (element.text ?? element.url) : element.text;\n\n// The envelope leaves rich text alone, so a section keeps to the budget of a\n// `section` block's text.\nconst clampInline = (\n elements: readonly SlackRichTextInline[],\n budget: number = SLACK_LIMITS.sectionTextChars\n): SlackRichTextInline[] => {\n const kept: SlackRichTextInline[] = [];\n let spent = 0;\n for (const element of elements) {\n const length = inlineText(element).length;\n const rest = budget - spent;\n if (length <= rest) {\n kept.push(element);\n spent += length;\n continue;\n }\n const text = rest > 0 ? clampSlackText(inlineText(element), rest) : '';\n if (text !== '') {\n kept.push({ ...element, text });\n }\n break;\n }\n return kept;\n};\n\nconst section = (elements: SlackRichTextInline[]): SlackRichTextSection[] => {\n const clamped = clampInline(elements);\n return clamped.length === 0\n ? []\n : [{ type: 'rich_text_section', elements: clamped }];\n};\n\ntype Piece = SlackRichTextBlockElement | SlackBlock;\n\nconst isElement = (piece: Piece): piece is SlackRichTextBlockElement =>\n piece.type.startsWith('rich_text_');\n\n// Blocks a rich-text list item holds as lines of its text.\nconst ITEM_LINES: ReadonlySet<string> = new Set([\n 'paragraph',\n 'heading',\n 'code',\n 'html',\n]);\n\nconst childInline = (\n child: ListItem['children'][number]\n): SlackRichTextInline[] =>\n 'children' in child\n ? inline(\n child.children as PhrasingContent[],\n child.type === 'heading' ? { bold: true } : {}\n )\n : textElement(\n plainText(child),\n child.type === 'code' ? { code: true } : {}\n );\n\n// A quote holds its blocks at one level.\nconst unquoted = (node: RootContent): RootContent[] =>\n node.type === 'blockquote' ? node.children.flatMap(unquoted) : [node];\n\n// An item's children are read in order. Its lines of text share one bullet; a\n// nested list follows at the next indent; any other block, such as a table,\n// follows on its own; what the item holds after either follows unbulleted,\n// since a Slack list item cannot resume; and the list resumes at its next\n// number. A task item's first line leads with its box.\nconst listPieces = (list: List, indent: number): Piece[] => {\n const style = list.ordered ? 'ordered' : 'bullet';\n const out: Piece[] = [];\n let current: SlackRichTextSection[] = [];\n let number = list.start ?? 1;\n let offset = number - 1;\n const flush = (): void => {\n if (current.length > 0) {\n out.push({\n type: 'rich_text_list',\n style,\n ...(indent > 0 ? { indent } : {}),\n // A list starting at 0 would need a negative offset, which Slack\n // may reject along with the whole message; it starts at 1 instead.\n ...(list.ordered && offset > 0 ? { offset } : {}),\n elements: current,\n });\n }\n current = [];\n offset = number - 1;\n };\n for (const item of list.children) {\n let runs: SlackRichTextInline[] = [];\n let numbered = false;\n let box =\n typeof item.checked === 'boolean'\n ? textElement(item.checked ? '☑ ' : '☐ ', {})\n : [];\n const emit = (): void => {\n const sections = section(runs);\n runs = [];\n if (sections.length === 0) {\n return;\n }\n if (numbered) {\n flush();\n out.push(...sections);\n } else {\n current.push(...sections);\n number += 1;\n numbered = true;\n }\n };\n for (const child of item.children.flatMap(\n unquoted\n ) as ListItem['children']) {\n if (ITEM_LINES.has(child.type)) {\n runs.push(\n ...(runs.length > 0 ? textElement('\\n', {}) : box),\n ...childInline(child)\n );\n box = [];\n continue;\n }\n const pieces =\n child.type === 'list'\n ? listPieces(\n child,\n Math.min(indent + 1, SLACK_LIMITS.richTextListMaxIndent)\n )\n : blockPieces(child);\n if (pieces.length > 0) {\n emit();\n flush();\n out.push(...pieces);\n }\n }\n emit();\n }\n flush();\n return out;\n};\n\nconst tableCell = (cell: PhrasingContent[]): SlackTableCell => {\n const elements = inline(cell);\n const plain = elements.every(\n (element) => element.type === 'text' && element.style === undefined\n );\n return plain\n ? { type: 'raw_text', text: cell.map(plainText).join('') }\n : {\n type: 'rich_text',\n elements: section(elements),\n };\n};\n\n// Slack rejects a row with no cells, so such rows are dropped, and a table\n// whose header has none prints nothing.\nconst tableBlock = (table: Table): SlackTableBlock[] => {\n const rows = table.children\n .slice(0, SLACK_LIMITS.tableRows)\n .map((row) =>\n row.children\n .slice(0, SLACK_LIMITS.tableColumns)\n .map((cell) => tableCell(cell.children))\n );\n const [header] = rows;\n if (header === undefined || header.length === 0) {\n return [];\n }\n return [\n {\n type: 'table',\n rows: rows.filter((cells) => cells.length > 0),\n column_settings: header.map((_cell, index) => ({\n align: table.align?.[index] ?? 'left',\n is_wrapped: true,\n })),\n },\n ];\n};\n\n// A footnote's label leads its first paragraph.\nconst footnotePieces = ({\n children,\n ...footnote\n}: FootnoteDefinition): Piece[] => {\n const [first, ...rest] = children;\n const label: PhrasingContent = {\n type: 'text',\n value: `${footnoteLabel(footnote)}: `,\n };\n const lead: Paragraph = {\n type: 'paragraph',\n children: [label, ...(first?.type === 'paragraph' ? first.children : [])],\n };\n return [lead, ...(first?.type === 'paragraph' ? rest : children)].flatMap(\n blockPieces\n );\n};\n\nconst borderedElement = (\n element: SlackRichTextBlockElement\n): SlackRichTextBlockElement => {\n switch (element.type) {\n case 'rich_text_list':\n case 'rich_text_preformatted':\n return { ...element, border: 1 };\n case 'rich_text_section':\n return { type: 'rich_text_quote', elements: element.elements };\n default:\n return element;\n }\n};\n\n// What a quote holds besides text keeps a quote's border; a table or divider\n// has none.\nconst bordered = (piece: Piece): Piece =>\n isElement(piece) ? borderedElement(piece) : piece;\n\n// A quote is one level, nested quotes spread into it: its text as\n// `rich_text_quote`, and any other block it holds with a border.\nconst quotePieces = (quote: Blockquote): Piece[] => {\n const out: Piece[] = [];\n let runs: SlackRichTextInline[] = [];\n const flush = (): void => {\n const elements = clampInline(runs);\n runs = [];\n if (elements.length > 0) {\n out.push({ type: 'rich_text_quote', elements });\n }\n };\n for (const child of quote.children.flatMap(unquoted)) {\n if (child.type === 'paragraph' || child.type === 'heading') {\n const line = childInline(child);\n runs.push(\n ...(runs.length > 0 && line.length > 0 ? textElement('\\n', {}) : []),\n ...line\n );\n } else {\n const pieces = blockPieces(child);\n if (pieces.length > 0) {\n flush();\n out.push(...pieces.map(bordered));\n }\n }\n }\n flush();\n return out;\n};\n\nconst blockPieces = (node: RootContent): Piece[] => {\n switch (node.type) {\n case 'paragraph':\n case 'html':\n return section(childInline(node));\n case 'heading':\n return section(inline(node.children, { bold: true }));\n case 'code':\n return node.value === ''\n ? []\n : [\n {\n type: 'rich_text_preformatted',\n elements: textElement(\n clampSlackText(node.value, SLACK_LIMITS.sectionTextChars),\n {}\n ),\n },\n ];\n case 'list':\n return listPieces(node, 0);\n case 'blockquote':\n return quotePieces(node);\n case 'table':\n return tableBlock(node);\n case 'thematicBreak':\n return [{ type: 'divider' }];\n case 'footnoteDefinition':\n return footnotePieces(node);\n default:\n return [];\n }\n};\n\n// Each reference resolved to its document's first definition.\nconst withReferences = (blocks: readonly RootContent[]): RootContent[] => {\n const definitions = new Map<string, Definition>();\n const collect = (node: Nodes): void => {\n if (node.type === 'definition' && !definitions.has(node.identifier)) {\n definitions.set(node.identifier, node);\n }\n if ('children' in node) {\n node.children.forEach(collect);\n }\n };\n blocks.forEach(collect);\n if (definitions.size === 0) {\n return [...blocks];\n }\n const resolve = (node: Nodes): Nodes => {\n switch (node.type) {\n case 'linkReference':\n return {\n type: 'link',\n url: definitions.get(node.identifier)?.url ?? '',\n children: node.children.map(resolve) as PhrasingContent[],\n };\n case 'imageReference':\n return {\n type: 'image',\n url: definitions.get(node.identifier)?.url ?? '',\n alt: node.alt ?? null,\n };\n default:\n return 'children' in node\n ? ({ ...node, children: node.children.map(resolve) } as Nodes)\n : node;\n }\n };\n return blocks.map(resolve) as RootContent[];\n};\n\nconst lines = (text: string): string => text.replace(/\\r\\n?/g, '\\n');\n\nconst literalParagraphs = (text: string): RootContent[] =>\n lines(text)\n .split(/\\n[ \\t]*\\n/)\n .filter((paragraph) => paragraph.trim() !== '')\n .map((paragraph) => ({\n type: 'paragraph',\n children: [{ type: 'text', value: paragraph.trim() }],\n }));\n\n// Source past the parse budget prints as its literal paragraphs.\nconst gfmBlocks = (gfm: string): RootContent[] => {\n const parsed = parseGfmBlocks(lines(gfm)) as RootContent[] | null;\n return parsed === null ? literalParagraphs(gfm) : withReferences(parsed);\n};\n\n// Markdown printed as written is read as the GFM it holds; authored source\n// that sanitizing left inert is never parsed.\nconst expanded = (node: Nodes): Nodes[] => {\n if ((node.type as string) === VERBATIM_TYPE) {\n const { value, source } = node as unknown as {\n value: string;\n source?: string;\n };\n return source === undefined ? gfmBlocks(value) : literalParagraphs(source);\n }\n return 'children' in node\n ? [{ ...node, children: node.children.flatMap(expanded) } as Nodes]\n : [node];\n};\n\nconst toSlackBlocks = (nodes: readonly RootContent[]): SlackBlock[] => {\n const blocks: SlackBlock[] = [];\n let elements: SlackRichTextBlockElement[] = [];\n const flush = (): void => {\n if (elements.length > 0) {\n // A section followed by another ends in a line break, so paragraphs\n // never run together.\n blocks.push({\n type: 'rich_text',\n elements: elements.map((element, index) =>\n element.type === 'rich_text_section' &&\n elements[index + 1]?.type === 'rich_text_section'\n ? {\n ...element,\n elements: [\n ...clampInline(\n element.elements,\n SLACK_LIMITS.sectionTextChars - 1\n ),\n { type: 'text', text: '\\n' },\n ],\n }\n : element\n ),\n });\n }\n elements = [];\n };\n for (const node of nodes) {\n for (const piece of blockPieces(node)) {\n if (isElement(piece)) {\n elements.push(piece);\n } else {\n flush();\n blocks.push(piece);\n }\n }\n }\n flush();\n return blocks;\n};\n\n/**\n * Builder content as Block Kit: paragraphs, headings, lists, quotes, and code\n * as `rich_text`, tables as `table` blocks, and thematic breaks as `divider`\n * blocks. A quote is one level, and inside a list item its blocks are the\n * item's. A run of rich-text blocks shares one `rich_text` block. Source from\n * `md.authored` is parsed as GFM and translated the same way.\n */\nexport const markdownContentToSlackBlocks = (\n content: MarkdownContent\n): SlackBlock[] =>\n toSlackBlocks(\n (markdownBlocks(content) as RootContent[]).flatMap(\n expanded\n ) as RootContent[]\n );\n\n/**\n * GFM as Block Kit, parsed as CommonMark with GFM and translated as\n * {@link markdownContentToSlackBlocks} translates builder content. Source past\n * the parse budget that `md.authored` applies prints as literal paragraphs.\n */\nexport const gfmToSlackBlocks = (gfm: string): SlackBlock[] =>\n toSlackBlocks(gfmBlocks(gfm));\n"]}
|
|
1
|
+
{"version":3,"file":"markdown_content.js","sourceRoot":"","sources":["../../../../src/render/slack/markdown_content.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\n// Markdown to Block Kit, read from the tree rather than re-parsed line by\n// line. Rich text carries formatting as style flags beside literal text, so\n// nothing is escaped and nesting survives exactly.\n\nimport type {\n Blockquote,\n FootnoteDefinition,\n List,\n ListItem,\n Nodes,\n Paragraph,\n PhrasingContent,\n RootContent,\n Table,\n} from 'mdast';\n\nimport type { MarkdownContent } from '../../define/markdown_content';\nimport { gfmBlocks, resolvedMarkdownBlocks } from '../markdown/blocks';\n\nimport {\n SLACK_LIMITS,\n type SlackBlock,\n type SlackRichTextBlockElement,\n type SlackRichTextInline,\n type SlackRichTextSection,\n type SlackRichTextStyle,\n type SlackTableBlock,\n type SlackTableCell,\n} from './blocks';\nimport {\n assertSlackBaseUrl,\n clampSlackText,\n type SlackLinkOptions,\n slackLinkUrl,\n} from './format';\n\nconst footnoteLabel = ({\n identifier,\n label,\n}: Pick<FootnoteDefinition, 'identifier' | 'label'>): string =>\n `[^${label ?? identifier}]`;\n\nconst plainText = (node: Nodes): string => {\n if ('value' in node) {\n return node.value;\n }\n if (node.type === 'image') {\n return node.alt ?? '';\n }\n if (node.type === 'footnoteReference') {\n return footnoteLabel(node);\n }\n return 'children' in node ? node.children.map(plainText).join('') : '';\n};\n\nconst styled = (style: SlackRichTextStyle): SlackRichTextStyle | undefined =>\n Object.keys(style).length === 0 ? undefined : style;\n\nconst textElement = (\n text: string,\n style: SlackRichTextStyle\n): SlackRichTextInline[] => {\n const withStyle = styled(style);\n return text === ''\n ? []\n : [{ type: 'text', text, ...(withStyle ? { style: withStyle } : {}) }];\n};\n\n// One link element per styled run of the label, so its formatting survives;\n// an empty label is a bare link. A URL Slack cannot link leaves the label.\nconst linkRuns = (\n href: string,\n runs: SlackRichTextInline[],\n style: SlackRichTextStyle\n): SlackRichTextInline[] => {\n const url = slackLinkUrl(href);\n if (url === null) {\n return runs;\n }\n if (runs.length === 0) {\n const withStyle = styled(style);\n return [{ type: 'link', url, ...(withStyle ? { style: withStyle } : {}) }];\n }\n return runs.map((run) =>\n run.type === 'text' ? { ...run, type: 'link', url } : run\n );\n};\n\nconst inline = (\n nodes: readonly PhrasingContent[],\n style: SlackRichTextStyle = {}\n): SlackRichTextInline[] =>\n nodes.flatMap((node): SlackRichTextInline[] => {\n switch (node.type) {\n case 'strong':\n return inline(node.children, { ...style, bold: true });\n case 'emphasis':\n return inline(node.children, { ...style, italic: true });\n case 'delete':\n return inline(node.children, { ...style, strike: true });\n case 'inlineCode':\n return textElement(node.value, { ...style, code: true });\n case 'link':\n return linkRuns(node.url, inline(node.children, style), style);\n // Slack draws no inline image, so it links to the source.\n case 'image':\n return linkRuns(node.url, textElement(node.alt ?? '', style), style);\n case 'break':\n return textElement('\\n', style);\n default:\n return textElement(plainText(node), style);\n }\n });\n\nconst inlineText = (element: SlackRichTextInline): string =>\n element.type === 'link' ? (element.text ?? element.url) : element.text;\n\n// The envelope leaves rich text alone, so a section keeps to the budget of a\n// `section` block's text.\nconst clampInline = (\n elements: readonly SlackRichTextInline[],\n budget: number = SLACK_LIMITS.sectionTextChars\n): SlackRichTextInline[] => {\n const kept: SlackRichTextInline[] = [];\n let spent = 0;\n for (const element of elements) {\n const length = inlineText(element).length;\n const rest = budget - spent;\n if (length <= rest) {\n kept.push(element);\n spent += length;\n continue;\n }\n const text = rest > 0 ? clampSlackText(inlineText(element), rest) : '';\n if (text !== '') {\n kept.push({ ...element, text });\n }\n break;\n }\n return kept;\n};\n\nconst section = (elements: SlackRichTextInline[]): SlackRichTextSection[] => {\n const clamped = clampInline(elements);\n return clamped.length === 0\n ? []\n : [{ type: 'rich_text_section', elements: clamped }];\n};\n\ntype Piece = SlackRichTextBlockElement | SlackBlock;\n\nconst isElement = (piece: Piece): piece is SlackRichTextBlockElement =>\n piece.type.startsWith('rich_text_');\n\n// Blocks a rich-text list item holds as lines of its text.\nconst ITEM_LINES: ReadonlySet<string> = new Set([\n 'paragraph',\n 'heading',\n 'code',\n 'html',\n]);\n\nconst childInline = (\n child: ListItem['children'][number]\n): SlackRichTextInline[] =>\n 'children' in child\n ? inline(\n child.children as PhrasingContent[],\n child.type === 'heading' ? { bold: true } : {}\n )\n : textElement(\n plainText(child),\n child.type === 'code' ? { code: true } : {}\n );\n\n// A quote holds its blocks at one level.\nconst unquoted = (node: RootContent): RootContent[] =>\n node.type === 'blockquote' ? node.children.flatMap(unquoted) : [node];\n\n// An item's children are read in order. Its lines of text share one bullet; a\n// nested list follows at the next indent; any other block, such as a table,\n// follows on its own; what the item holds after either follows unbulleted,\n// since a Slack list item cannot resume; and the list resumes at its next\n// number. An empty item keeps its number, so the list resumes past it. A task\n// item's first line leads with its box.\nconst listPieces = (list: List, indent: number): Piece[] => {\n const style = list.ordered ? 'ordered' : 'bullet';\n const out: Piece[] = [];\n let current: SlackRichTextSection[] = [];\n let number = list.start ?? 1;\n let offset = number - 1;\n const flush = (): void => {\n if (current.length > 0) {\n out.push({\n type: 'rich_text_list',\n style,\n ...(indent > 0 ? { indent } : {}),\n // A list starting at 0 would need a negative offset, which Slack\n // may reject along with the whole message; it starts at 1 instead.\n ...(list.ordered && offset > 0 ? { offset } : {}),\n elements: current,\n });\n }\n current = [];\n offset = number - 1;\n };\n for (const item of list.children) {\n let runs: SlackRichTextInline[] = [];\n let numbered = false;\n let box =\n typeof item.checked === 'boolean'\n ? textElement(item.checked ? '☑ ' : '☐ ', {})\n : [];\n const emit = (): void => {\n const sections = section(runs);\n runs = [];\n if (sections.length === 0) {\n return;\n }\n if (numbered) {\n flush();\n out.push(...sections);\n } else {\n current.push(...sections);\n number += 1;\n numbered = true;\n }\n };\n for (const child of item.children.flatMap(\n unquoted\n ) as ListItem['children']) {\n if (ITEM_LINES.has(child.type)) {\n runs.push(\n ...(runs.length > 0 ? textElement('\\n', {}) : box),\n ...childInline(child)\n );\n box = [];\n continue;\n }\n const pieces =\n child.type === 'list'\n ? listPieces(\n child,\n Math.min(indent + 1, SLACK_LIMITS.richTextListMaxIndent)\n )\n : blockPieces(child);\n if (pieces.length > 0) {\n emit();\n flush();\n out.push(...pieces);\n }\n }\n emit();\n if (item.children.length === 0) {\n flush();\n number += 1;\n offset = number - 1;\n }\n }\n flush();\n return out;\n};\n\nconst tableCell = (cell: PhrasingContent[]): SlackTableCell => {\n const elements = inline(cell);\n const plain = elements.every(\n (element) => element.type === 'text' && element.style === undefined\n );\n return plain\n ? { type: 'raw_text', text: cell.map(plainText).join('') }\n : {\n type: 'rich_text',\n elements: section(elements),\n };\n};\n\n// Slack rejects a row with no cells, so such rows are dropped, and a table\n// whose header has none prints nothing.\nconst tableBlock = (table: Table): SlackTableBlock[] => {\n const rows = table.children\n .slice(0, SLACK_LIMITS.tableRows)\n .map((row) =>\n row.children\n .slice(0, SLACK_LIMITS.tableColumns)\n .map((cell) => tableCell(cell.children))\n );\n const [header] = rows;\n if (header === undefined || header.length === 0) {\n return [];\n }\n return [\n {\n type: 'table',\n rows: rows.filter((cells) => cells.length > 0),\n column_settings: header.map((_cell, index) => ({\n align: table.align?.[index] ?? 'left',\n is_wrapped: true,\n })),\n },\n ];\n};\n\n// A footnote's label leads its first paragraph.\nconst footnotePieces = ({\n children,\n ...footnote\n}: FootnoteDefinition): Piece[] => {\n const [first, ...rest] = children;\n const label: PhrasingContent = {\n type: 'text',\n value: `${footnoteLabel(footnote)}: `,\n };\n const lead: Paragraph = {\n type: 'paragraph',\n children: [label, ...(first?.type === 'paragraph' ? first.children : [])],\n };\n return [lead, ...(first?.type === 'paragraph' ? rest : children)].flatMap(\n blockPieces\n );\n};\n\nconst borderedElement = (\n element: SlackRichTextBlockElement\n): SlackRichTextBlockElement => {\n switch (element.type) {\n case 'rich_text_list':\n case 'rich_text_preformatted':\n return { ...element, border: 1 };\n case 'rich_text_section':\n return { type: 'rich_text_quote', elements: element.elements };\n default:\n return element;\n }\n};\n\n// What a quote holds besides text keeps a quote's border; a table or divider\n// has none.\nconst bordered = (piece: Piece): Piece =>\n isElement(piece) ? borderedElement(piece) : piece;\n\n// A quote is one level, nested quotes spread into it: its text as\n// `rich_text_quote`, and any other block it holds with a border.\nconst quotePieces = (quote: Blockquote): Piece[] => {\n const out: Piece[] = [];\n let runs: SlackRichTextInline[] = [];\n const flush = (): void => {\n const elements = clampInline(runs);\n runs = [];\n if (elements.length > 0) {\n out.push({ type: 'rich_text_quote', elements });\n }\n };\n for (const child of quote.children.flatMap(unquoted)) {\n if (child.type === 'paragraph' || child.type === 'heading') {\n const line = childInline(child);\n runs.push(\n ...(runs.length > 0 && line.length > 0 ? textElement('\\n', {}) : []),\n ...line\n );\n } else {\n const pieces = blockPieces(child);\n if (pieces.length > 0) {\n flush();\n out.push(...pieces.map(bordered));\n }\n }\n }\n flush();\n return out;\n};\n\nconst blockPieces = (node: RootContent): Piece[] => {\n switch (node.type) {\n case 'paragraph':\n case 'html':\n return section(childInline(node));\n case 'heading':\n return section(inline(node.children, { bold: true }));\n case 'code':\n return node.value === ''\n ? []\n : [\n {\n type: 'rich_text_preformatted',\n elements: textElement(\n clampSlackText(node.value, SLACK_LIMITS.sectionTextChars),\n {}\n ),\n },\n ];\n case 'list':\n return listPieces(node, 0);\n case 'blockquote':\n return quotePieces(node);\n case 'table':\n return tableBlock(node);\n case 'thematicBreak':\n return [{ type: 'divider' }];\n case 'footnoteDefinition':\n return footnotePieces(node);\n default:\n return [];\n }\n};\n\n// Each relative link resolved against `baseUrl`, ahead of `linkRuns`. An\n// image's source is left alone: Slack draws none inline.\nconst rebased = (node: Nodes, baseUrl: string): Nodes =>\n ({\n ...node,\n ...('children' in node && {\n children: node.children.map((child) => rebased(child, baseUrl)),\n }),\n ...(node.type === 'link' && {\n url: slackLinkUrl(node.url, baseUrl) ?? node.url,\n }),\n }) as Nodes;\n\nconst toSlackBlocks = (\n input: readonly RootContent[],\n { baseUrl }: SlackLinkOptions\n): SlackBlock[] => {\n assertSlackBaseUrl(baseUrl);\n const nodes =\n baseUrl === undefined\n ? input\n : input.map((node) => rebased(node, baseUrl) as RootContent);\n const blocks: SlackBlock[] = [];\n let elements: SlackRichTextBlockElement[] = [];\n const flush = (): void => {\n if (elements.length > 0) {\n // A section followed by another ends in a line break, so paragraphs\n // never run together.\n blocks.push({\n type: 'rich_text',\n elements: elements.map((element, index) =>\n element.type === 'rich_text_section' &&\n elements[index + 1]?.type === 'rich_text_section'\n ? {\n ...element,\n elements: [\n ...clampInline(\n element.elements,\n SLACK_LIMITS.sectionTextChars - 1\n ),\n { type: 'text', text: '\\n' },\n ],\n }\n : element\n ),\n });\n }\n elements = [];\n };\n for (const node of nodes) {\n for (const piece of blockPieces(node)) {\n if (isElement(piece)) {\n elements.push(piece);\n } else {\n flush();\n blocks.push(piece);\n }\n }\n }\n flush();\n return blocks;\n};\n\n/**\n * Builder content as Block Kit: paragraphs, headings, lists, quotes, and code\n * as `rich_text`, tables as `table` blocks, and thematic breaks as `divider`\n * blocks. A quote is one level, and inside a list item its blocks are the\n * item's. A run of rich-text blocks shares one `rich_text` block. Source from\n * `md.authored` is parsed as GFM and translated the same way.\n */\nexport const markdownContentToSlackBlocks = (\n content: MarkdownContent,\n options: SlackLinkOptions = {}\n): SlackBlock[] =>\n toSlackBlocks(resolvedMarkdownBlocks(content) as RootContent[], options);\n\n/**\n * GFM as Block Kit, parsed as CommonMark with GFM and translated as\n * {@link markdownContentToSlackBlocks} translates builder content. Source past\n * the parse budget that `md.authored` applies prints as literal paragraphs.\n */\nexport const gfmToSlackBlocks = (\n gfm: string,\n options: SlackLinkOptions = {}\n): SlackBlock[] => toSlackBlocks(gfmBlocks(gfm) as RootContent[], options);\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
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.isUnmodeledSlackBlock = exports.unmodeledSlackBlock = exports.isModeledSlackBlockType = void 0;
|
|
10
|
+
const UNMODELED = Symbol.for('elastic.isomer.slack_unmodeled_block');
|
|
11
|
+
const MODELED_BLOCK_TYPES = {
|
|
12
|
+
actions: true,
|
|
13
|
+
container: true,
|
|
14
|
+
context: true,
|
|
15
|
+
divider: true,
|
|
16
|
+
header: true,
|
|
17
|
+
image: true,
|
|
18
|
+
rich_text: true,
|
|
19
|
+
section: true,
|
|
20
|
+
table: true,
|
|
21
|
+
video: true,
|
|
22
|
+
};
|
|
23
|
+
/** Whether Isomer models Block Kit blocks of `type`, so a renderer returns them as a {@link SlackBlock} without {@link unmodeledSlackBlock}. */
|
|
24
|
+
const isModeledSlackBlockType = (type) => Object.prototype.hasOwnProperty.call(MODELED_BLOCK_TYPES, type);
|
|
25
|
+
exports.isModeledSlackBlockType = isModeledSlackBlockType;
|
|
26
|
+
/**
|
|
27
|
+
* A Block Kit block Isomer does not model yet, typed so a `slack` renderer can return it or put it in a container's `child_blocks`.
|
|
28
|
+
*
|
|
29
|
+
* The envelope passes it through unfitted, so Slack rejects the whole message if it breaks a limit, or if Slack does not accept it inside a container. A literal `type` Isomer models does not compile: return that block unwrapped. Pass the block's interface as `TBlock` to check its fields.
|
|
30
|
+
*/
|
|
31
|
+
const unmodeledSlackBlock = (block) => ({ ...block, [UNMODELED]: true });
|
|
32
|
+
exports.unmodeledSlackBlock = unmodeledSlackBlock;
|
|
33
|
+
/** Whether `block` came from {@link unmodeledSlackBlock}. The mark is a symbol key, so it never reaches the JSON sent to Slack. */
|
|
34
|
+
const isUnmodeledSlackBlock = (block) => typeof block === 'object' &&
|
|
35
|
+
block !== null &&
|
|
36
|
+
block[UNMODELED] === true;
|
|
37
|
+
exports.isUnmodeledSlackBlock = isUnmodeledSlackBlock;
|
|
38
|
+
//# sourceMappingURL=unmodeled.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unmodeled.js","sourceRoot":"","sources":["../../../../src/render/slack/unmodeled.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAIH,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;AAErE,MAAM,mBAAmB,GAA+C;IACtE,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,IAAI;IACf,OAAO,EAAE,IAAI;IACb,OAAO,EAAE,IAAI;IACb,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,SAAS,EAAE,IAAI;IACf,OAAO,EAAE,IAAI;IACb,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,IAAI;CACZ,CAAC;AAEF,gJAAgJ;AACzI,MAAM,uBAAuB,GAAG,CACrC,IAAY,EACgB,EAAE,CAC9B,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;AAHrD,QAAA,uBAAuB,2BAG8B;AAElE;;;;GAIG;AACI,MAAM,mBAAmB,GAAG,CAGjC,KAKc,EACY,EAAE,CAC5B,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAwC,CAAC;AAV9D,QAAA,mBAAmB,uBAU2C;AAE3E,mIAAmI;AAC5H,MAAM,qBAAqB,GAAG,CAAC,KAAc,EAAW,EAAE,CAC/D,OAAO,KAAK,KAAK,QAAQ;IACzB,KAAK,KAAK,IAAI;IACb,KAAmC,CAAC,SAAS,CAAC,KAAK,IAAI,CAAC;AAH9C,QAAA,qBAAqB,yBAGyB","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 { SlackBlock, SlackContainerChildBlock } from './blocks';\n\nconst UNMODELED = Symbol.for('elastic.isomer.slack_unmodeled_block');\n\nconst MODELED_BLOCK_TYPES: Readonly<Record<SlackBlock['type'], true>> = {\n actions: true,\n container: true,\n context: true,\n divider: true,\n header: true,\n image: true,\n rich_text: true,\n section: true,\n table: true,\n video: true,\n};\n\n/** Whether Isomer models Block Kit blocks of `type`, so a renderer returns them as a {@link SlackBlock} without {@link unmodeledSlackBlock}. */\nexport const isModeledSlackBlockType = (\n type: string\n): type is SlackBlock['type'] =>\n Object.prototype.hasOwnProperty.call(MODELED_BLOCK_TYPES, type);\n\n/**\n * A Block Kit block Isomer does not model yet, typed so a `slack` renderer can return it or put it in a container's `child_blocks`.\n *\n * The envelope passes it through unfitted, so Slack rejects the whole message if it breaks a limit, or if Slack does not accept it inside a container. A literal `type` Isomer models does not compile: return that block unwrapped. Pass the block's interface as `TBlock` to check its fields.\n */\nexport const unmodeledSlackBlock = <\n const TBlock extends { readonly type: string },\n>(\n block: TBlock &\n (TBlock['type'] extends SlackBlock['type']\n ? {\n readonly 'Isomer models this block type: return it without unmodeledSlackBlock': never;\n }\n : unknown)\n): SlackContainerChildBlock =>\n ({ ...block, [UNMODELED]: true }) as unknown as SlackContainerChildBlock;\n\n/** Whether `block` came from {@link unmodeledSlackBlock}. The mark is a symbol key, so it never reaches the JSON sent to Slack. */\nexport const isUnmodeledSlackBlock = (block: unknown): boolean =>\n typeof block === 'object' &&\n block !== null &&\n (block as { [UNMODELED]?: unknown })[UNMODELED] === true;\n"]}
|
|
@@ -9,7 +9,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
9
9
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.primitiveConformanceCases = exports.runPrimitiveInventoryConformance = exports.primitiveConformanceRows = exports.examplesFromDefinitions = exports.CONFORMANCE_FOREIGN_MARKER = void 0;
|
|
12
|
+
exports.primitiveConformanceCases = exports.runPrimitiveInventoryConformance = exports.primitiveConformanceRows = exports.examplesFromDefinitions = exports.CONFORMANCE_FIXTURE_TITLE = exports.CONFORMANCE_FOREIGN_MARKER = void 0;
|
|
13
13
|
// The behaviour every primitive definition owes its callers, expressed once.
|
|
14
14
|
//
|
|
15
15
|
// Framework-agnostic on purpose: only `node:assert/strict` and Node builtins,
|
|
@@ -19,6 +19,7 @@ exports.primitiveConformanceCases = exports.runPrimitiveInventoryConformance = e
|
|
|
19
19
|
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
20
20
|
const primitive_example_1 = require("../define/primitive_example");
|
|
21
21
|
const anchors_1 = require("../render/anchors");
|
|
22
|
+
const unmodeled_1 = require("../render/slack/unmodeled");
|
|
22
23
|
const input_budget_1 = require("../validate/input_budget");
|
|
23
24
|
/**
|
|
24
25
|
* The foreign node {@link PrimitiveConformanceHarness.nestForeignChild}
|
|
@@ -26,6 +27,8 @@ const input_budget_1 = require("../validate/input_budget");
|
|
|
26
27
|
* cross-pack nesting case cannot tell a dropped child from an empty one.
|
|
27
28
|
*/
|
|
28
29
|
exports.CONFORMANCE_FOREIGN_MARKER = 'isomerConformanceForeign';
|
|
30
|
+
/** The `title` {@link PrimitiveConformanceHarness.wrapComposition} must give its composition. */
|
|
31
|
+
exports.CONFORMANCE_FIXTURE_TITLE = 'Conformance fixture';
|
|
29
32
|
/** Every definition's examples, flattened to one row each. */
|
|
30
33
|
const examplesFromDefinitions = (definitions) => definitions.flatMap((definition) => (0, primitive_example_1.primitiveExamples)(definition).map(({ name, node }, exampleIndex) => ({
|
|
31
34
|
definition,
|
|
@@ -177,6 +180,17 @@ exports.primitiveConformanceCases = [
|
|
|
177
180
|
}
|
|
178
181
|
},
|
|
179
182
|
},
|
|
183
|
+
{
|
|
184
|
+
name: 'wraps only Slack blocks Isomer does not model',
|
|
185
|
+
run: (example, harness) => {
|
|
186
|
+
for (const { type } of harness
|
|
187
|
+
.renderSlack(example.node)
|
|
188
|
+
.flatMap((block) => block.type === 'container' ? [block, ...block.child_blocks] : [block])
|
|
189
|
+
.filter(unmodeled_1.isUnmodeledSlackBlock)) {
|
|
190
|
+
strict_1.default.ok(!(0, unmodeled_1.isModeledSlackBlockType)(type), `Isomer models \`${type}\` blocks: return this one without \`unmodeledSlackBlock\`. ${previewHint(example)}`);
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
},
|
|
180
194
|
{
|
|
181
195
|
name: 'renders through snapshot primitive dispatch without throwing',
|
|
182
196
|
run: ({ type, exampleIndex, node }, harness) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conformance.js","sourceRoot":"","sources":["../../../src/testing/conformance.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\n// The behaviour every primitive definition owes its callers, expressed once.\n//\n// Framework-agnostic on purpose: only `node:assert/strict` and Node builtins,\n// so this ships on a public entry without dragging vitest into a vocabulary\n// package's dependency set. Each pack drives the array with `it.each`, so a\n// second vocabulary costs one package and one test file.\n\nimport assert from 'node:assert/strict';\n\nimport type { ChildNodeWalker } from '../composition/body_node_base';\nimport type { Composition } from '../composition/composition';\nimport type { ValidationError } from '../composition/validation_error';\nimport { exampleNodes, primitiveExamples } from '../define/primitive_example';\nimport type {\n AnyPrimitiveDefinition,\n PrimitiveNode,\n} from '../define/primitive_module';\nimport {\n anchoredNodes,\n anchorValue,\n NODE_ANCHOR_ATTRIBUTE,\n nodeType,\n} from '../render/anchors';\nimport type { HTMLRenderResult } from '../render/html/envelope';\nimport type { SlackBlock } from '../render/slack/blocks';\nimport { checkInputBudget } from '../validate/input_budget';\nimport type { ValidationResult } from '../validate/validation';\n\n/**\n * The foreign node {@link PrimitiveConformanceHarness.nestForeignChild}\n * hands a container must render text/markdown containing this string, or the\n * cross-pack nesting case cannot tell a dropped child from an empty one.\n */\nexport const CONFORMANCE_FOREIGN_MARKER = 'isomerConformanceForeign';\n\n/** One example node, paired with the definition that published it. */\nexport interface PrimitiveConformanceExample {\n readonly definition: AnyPrimitiveDefinition;\n /** Always `definition.type`, lifted onto the row so `it.each` titles can read it. */\n readonly type: string;\n /** Index into {@link AnyPrimitiveDefinition.examples}, and half of the preview hint a failure prints. */\n readonly exampleIndex: number;\n /** The example's `name`, absent for a bare node. */\n readonly exampleName?: string;\n readonly node: PrimitiveNode;\n}\n\n/** The subset of a host's HTML render options the cases exercise. */\nexport interface PrimitiveConformanceHtmlOptions {\n /** `'separate'` must move the stylesheet out of the markup and into `css`; the CSS cases assert against that field. */\n readonly css?: 'inline' | 'separate';\n /** `'readable'` must emit human-legible class names, which the CSS coverage case matches back against the emitted selectors. */\n readonly names?: string;\n /** Must render node anchors, as the `anchors` HTML render option does. */\n readonly anchors?: boolean;\n}\n\n/** The subset of a host's `snapshot` render result the cases assert on. */\nexport interface PrimitiveConformanceSnapshotResult {\n /** Must be empty for every published example. */\n readonly validationErrors: readonly ValidationError[];\n /** The frame's markup, stylesheet included or not. */\n readonly html: string;\n /** `total` is the rendered byte size, and must be positive. */\n readonly measurement: { readonly total: number };\n}\n\n/** The subset of a host's Slack render result the cases assert on. */\nexport interface PrimitiveConformanceSlackResult {\n readonly blocks: readonly SlackBlock[];\n /** Notification fallback text. Must be non-empty. */\n readonly text: string;\n}\n\n/**\n * Pack-owned render and validation bindings. The cases cannot import a\n * vocabulary package, so the pack closes over its dispatcher, frame, and\n * theme when it builds this object.\n *\n * Unsuffixed members take a single node; the `Composition`-suffixed ones take\n * a whole {@link Composition}. Optional members gate the cases that need\n * them, so a pack supplies only what its surfaces can answer.\n */\nexport interface PrimitiveConformanceHarness {\n /**\n * The smallest composition that carries one node. Its `title` must be\n * `'Conformance fixture'`, which the envelope cases look for as\n * `CONFORMANCE FIXTURE` in text and `# Conformance fixture` in markdown.\n */\n wrapComposition(node: PrimitiveNode): Composition;\n /** Validation errors for the node on its own. Must be empty for every published example. */\n validateNode(node: PrimitiveNode): readonly ValidationError[];\n /** Whole-composition validation. Must be `valid` with no `errors` for a wrapped example. */\n validateComposition(composition: Composition): ValidationResult;\n /** Must return something other than `undefined`; the case does not mount the element. */\n renderReact(node: PrimitiveNode): unknown;\n /** Drives the pack's style collection for one node. Must not throw. */\n collectStyles(node: PrimitiveNode): void;\n /** Must return a string with non-whitespace content. */\n renderText(node: PrimitiveNode): string;\n /** Must return a string with non-whitespace content. */\n renderMarkdown(node: PrimitiveNode): string;\n /** Must return at least one block, each an object with a string `type`. */\n renderSlack(node: PrimitiveNode): readonly SlackBlock[];\n /** `key` is unique per example and only has to survive into the React tree. Must not throw. Omit for a pack with no `snapshot` path. */\n renderSnapshot?(node: PrimitiveNode, key: string): unknown;\n /** Must be finite and greater than zero, so a frame can lay the node out unrendered. Omit for a pack with no `snapshot` path. */\n estimateSnapshotHeight?(node: PrimitiveNode): number;\n /**\n * Set `false` for a pack whose frame is a fixed size, so its primitives are\n * not required to report a positive `metrics.snapshotHeight`. Skips the\n * positive-finite height assertion.\n */\n sizesFromNodeHeights?: boolean;\n /**\n * For a container example, returns `container` with one of its children\n * replaced by a node from a pack the harness composed in only for this\n * check — never one `container`'s own pack registers. That node's `text`\n * and `markdown` renderers must emit {@link CONFORMANCE_FOREIGN_MARKER}.\n * Omit to skip the cross-pack nesting case.\n */\n nestForeignChild?(container: PrimitiveNode): PrimitiveNode;\n /**\n * Must honor {@link PrimitiveConformanceHtmlOptions}. Cases assert the\n * markup wraps the body in a `<section>`, that `measurement.js` is zero, and\n * that `validationErrors` is empty. Omit to skip the HTML cases.\n */\n renderHTML?(\n composition: Composition,\n options?: PrimitiveConformanceHtmlOptions\n ): HTMLRenderResult;\n /**\n * The child walker over every definition the harness renders with. Set it\n * once every `react` renderer spreads `nodeAnchor` on its root; the anchor\n * case then asserts each node renders one.\n */\n anchorWalk?: ChildNodeWalker;\n /** Must throw when `css` references a `var(--name)` it never declares. Omit to skip the CSS variable case. */\n assertVarRefsHaveDeclarations?(css: string): void;\n /** Whole-composition text render, title envelope included. */\n renderTextComposition(composition: Composition): string;\n /** Whole-composition markdown render, title heading included. */\n renderMarkdownComposition(composition: Composition): string;\n /** Must lead with a `plain_text` header block carrying the composition title. */\n renderSlackComposition(\n composition: Composition\n ): PrimitiveConformanceSlackResult;\n /** Must resolve to non-empty markup with no validation errors. Omit for a pack with no frame. */\n renderSnapshotComposition?(\n composition: Composition\n ): Promise<PrimitiveConformanceSnapshotResult>;\n}\n\n/** One assertion, run once per example. */\nexport interface PrimitiveConformanceCase {\n readonly name: string;\n /** Signals failure by throwing. May be async, so a pack must await it. */\n readonly run: (\n example: PrimitiveConformanceExample,\n harness: PrimitiveConformanceHarness\n ) => void | Promise<void>;\n}\n\n/** Every definition's examples, flattened to one row each. */\nexport const examplesFromDefinitions = (\n definitions: readonly AnyPrimitiveDefinition[]\n): readonly PrimitiveConformanceExample[] =>\n definitions.flatMap((definition) =>\n primitiveExamples(definition).map(({ name, node }, exampleIndex) => ({\n definition,\n type: definition.type,\n exampleIndex,\n ...(name === undefined ? {} : { exampleName: name }),\n node,\n }))\n );\n\n/** Every example crossed with every case, shaped for `it.each`. */\nexport const primitiveConformanceRows = (\n definitions: readonly AnyPrimitiveDefinition[]\n): readonly (PrimitiveConformanceExample & PrimitiveConformanceCase)[] =>\n examplesFromDefinitions(definitions).flatMap((example) =>\n primitiveConformanceCases.map((conformanceCase) => ({\n ...example,\n ...conformanceCase,\n }))\n );\n\n/**\n * Asserts the inventory itself holds up: the pack has examples, every\n * definition contributes one, `catalog.name` and example names are non-empty,\n * example names are unique within their definition, each example's `type` matches its definition, and\n * `catalog.example` is within the input budget and parses or matches a\n * published example.\n */\nexport const runPrimitiveInventoryConformance = (\n definitions: readonly AnyPrimitiveDefinition[]\n): void => {\n const examples = examplesFromDefinitions(definitions);\n assert.ok(examples.length > 0, 'expected at least one primitive example');\n for (const definition of definitions) {\n assert.ok(\n definition.examples.length > 0,\n `${definition.type} primitive must expose at least one example`\n );\n const { name: catalogName } = definition.catalog;\n assert.ok(\n catalogName === undefined || catalogName.trim().length > 0,\n `${definition.type} catalog.name must be non-empty when present`\n );\n const names = new Set<string>();\n for (const { name } of primitiveExamples(definition)) {\n if (name === undefined) {\n continue;\n }\n assert.ok(\n name.trim().length > 0,\n `${definition.type} example names must be non-empty`\n );\n assert.ok(\n !names.has(name),\n `${definition.type} has two examples named ${JSON.stringify(name)}`\n );\n names.add(name);\n }\n const checked = checkInputBudget(definition.catalog.example);\n if (!checked.valid) {\n assert.fail(\n `${definition.type} catalog.example must be within the input budget: ${checked.error.message}`\n );\n }\n const catalogExample = checked.value;\n const matchesPublished = exampleNodes(definition).some((node) => {\n const published = checkInputBudget(node);\n return (\n published.valid &&\n JSON.stringify(published.value) === JSON.stringify(catalogExample)\n );\n });\n if (matchesPublished) {\n continue;\n }\n const parsed = definition.schema.safeParse(catalogExample);\n assert.ok(\n parsed.success,\n `${definition.type} catalog.example must parse against its schema or match a published example`\n );\n }\n for (const { type, node } of examples) {\n assert.equal(node.type, type);\n }\n};\n\nconst previewHint = ({\n type,\n exampleIndex,\n exampleName,\n}: PrimitiveConformanceExample): string =>\n `Failing example: \\`${type}\\` definition, examples[${exampleIndex}]` +\n `${exampleName === undefined ? '' : ` (${JSON.stringify(exampleName)})`}.`;\n\nconst renderedClassNames = (html: string): string[] => {\n const classNames = new Set<string>();\n for (const match of html.matchAll(/\\bclass=\"([^\"]+)\"/g)) {\n match[1]!\n .split(/\\s+/)\n .filter(Boolean)\n .forEach((className) => classNames.add(className));\n }\n return [...classNames].sort();\n};\n\n/** The node anchor values in serialized `html`, in document order. */\nconst renderedAnchors = (html: string): string[] => {\n const attribute = new RegExp(`\\\\s${NODE_ANCHOR_ATTRIBUTE}=\"([^\"]*)\"`);\n // Only opening tags: the serializer escapes `<`, `>`, and `\"` in text and attribute values.\n return [...html.matchAll(/<[a-zA-Z][^>]*>/g)].flatMap(([tag]) => {\n const [, value] = attribute.exec(tag) ?? [];\n return value === undefined ? [] : [value];\n });\n};\n\nconst cssEscapeClass = (className: string): string =>\n className.replace(/([!\"#$%&'()*+,./:;<=>?@[\\\\\\]^`{|}~])/g, '\\\\$1');\n\nconst cssHasClassSelector = (css: string, className: string): boolean =>\n new RegExp(`\\\\.${cssEscapeClass(className)}(?![\\\\w-])`).test(css);\n\n/**\n * Every assertion a primitive owes its callers, for a pack to drive with\n * `it.each`.\n */\nexport const primitiveConformanceCases: readonly PrimitiveConformanceCase[] = [\n {\n name: 'validates as a primitive node and inside a composition',\n run: (example, harness) => {\n const { node } = example;\n const hint = previewHint(example);\n const primitiveErrors = [...harness.validateNode(node)];\n assert.deepEqual(primitiveErrors, [], hint);\n const result = harness.validateComposition(harness.wrapComposition(node));\n assert.equal(result.valid, true, hint);\n assert.deepEqual(result.errors, [], hint);\n },\n },\n {\n name: 'renders through React without throwing',\n run: ({ node }, harness) => {\n const rendered = harness.renderReact(node);\n assert.notEqual(rendered, undefined);\n },\n },\n {\n name: 'collects styles without throwing',\n run: ({ node }, harness) => {\n assert.doesNotThrow(() => harness.collectStyles(node));\n },\n },\n {\n name: 'a container recurses through scope for a node from another pack',\n run: ({ definition, node }, harness) => {\n if (!definition.children || !harness.nestForeignChild) {\n return;\n }\n const nested = harness.nestForeignChild(node);\n assert.notEqual(harness.renderReact(nested), undefined);\n assert.ok(\n harness.renderText(nested).includes(CONFORMANCE_FOREIGN_MARKER)\n );\n assert.ok(\n harness.renderMarkdown(nested).includes(CONFORMANCE_FOREIGN_MARKER)\n );\n },\n },\n {\n name: 'renders through plain text with non-empty output',\n run: ({ node }, harness) => {\n const text = harness.renderText(node);\n assert.equal(typeof text, 'string');\n assert.ok(text.trim().length > 0);\n },\n },\n {\n name: 'renders through markdown with non-empty output',\n run: ({ node }, harness) => {\n const markdown = harness.renderMarkdown(node);\n assert.equal(typeof markdown, 'string');\n assert.ok(markdown.trim().length > 0);\n },\n },\n {\n name: 'renders through Slack dispatch returning at least one block',\n run: ({ node }, harness) => {\n const blocks = harness.renderSlack(node);\n assert.ok(blocks.length > 0);\n for (const block of blocks) {\n assert.equal(typeof block, 'object');\n assert.equal(typeof block.type, 'string');\n }\n },\n },\n {\n name: 'renders through snapshot primitive dispatch without throwing',\n run: ({ type, exampleIndex, node }, harness) => {\n if (!harness.renderSnapshot) {\n return;\n }\n assert.doesNotThrow(() =>\n harness.renderSnapshot?.(node, `conformance-${type}-${exampleIndex}`)\n );\n },\n },\n {\n name: 'reports a positive finite snapshot height estimate',\n run: ({ node }, harness) => {\n if (\n harness.sizesFromNodeHeights === false ||\n !harness.estimateSnapshotHeight\n ) {\n return;\n }\n const height = harness.estimateSnapshotHeight(node);\n assert.equal(Number.isFinite(height), true);\n assert.ok(height > 0);\n },\n },\n {\n name: 'renders through renderHTML wrapped in a minimal composition',\n run: ({ node }, harness) => {\n if (!harness.renderHTML) {\n return;\n }\n const result = harness.renderHTML(harness.wrapComposition(node));\n assert.deepEqual(result.validationErrors, []);\n assert.ok(result.html.includes('<section'));\n assert.equal(result.measurement.js, 0);\n assert.ok(result.measurement.total > 0);\n },\n },\n {\n name: 'renders no node anchors unless asked',\n run: ({ node }, harness) => {\n if (!harness.renderHTML) {\n return;\n }\n const { body } = harness.renderHTML(harness.wrapComposition(node));\n assert.deepEqual(renderedAnchors(body), []);\n },\n },\n {\n name: 'renders a node anchor on every node when asked',\n run: (example, harness) => {\n if (!harness.renderHTML || !harness.anchorWalk) {\n return;\n }\n const composition = harness.wrapComposition(example.node);\n const { body } = harness.renderHTML(composition, { anchors: true });\n const expected = anchoredNodes(\n composition.body,\n harness.anchorWalk\n ).flatMap((anchored) => {\n const anchoredType = nodeType(anchored);\n return anchoredType === undefined ? [] : [anchorValue(anchoredType)];\n });\n assert.deepEqual(\n renderedAnchors(body),\n expected,\n `Expected one anchor per node, in walker order. ${previewHint(example)}`\n );\n },\n },\n {\n name: 'emits CSS where every var(...) reference has a matching declaration',\n run: ({ node }, harness) => {\n if (!harness.renderHTML || !harness.assertVarRefsHaveDeclarations) {\n return;\n }\n const result = harness.renderHTML(harness.wrapComposition(node), {\n css: 'separate',\n });\n harness.assertVarRefsHaveDeclarations(result.css);\n },\n },\n {\n name: 'reaches every rendered readable class in compact CSS collection',\n run: (example, harness) => {\n if (!harness.renderHTML) {\n return;\n }\n const { type, exampleIndex, node } = example;\n const result = harness.renderHTML(harness.wrapComposition(node), {\n css: 'separate',\n names: 'readable',\n });\n const missing = renderedClassNames(result.body).filter(\n (className) => !cssHasClassSelector(result.css, className)\n );\n const hint =\n `Missing CSS for ${type} example #${exampleIndex}: ` +\n `${missing.join(', ') || '(none)'}. ` +\n previewHint(example);\n assert.deepEqual(missing, [], hint);\n },\n },\n {\n name: 'renders through renderText wrapped in a minimal composition',\n run: ({ node }, harness) => {\n const text = harness.renderTextComposition(harness.wrapComposition(node));\n assert.ok(text.length > 0);\n assert.ok(text.includes('CONFORMANCE FIXTURE'));\n },\n },\n {\n name: 'renders through renderMarkdown wrapped in a minimal composition',\n run: ({ node }, harness) => {\n const markdown = harness.renderMarkdownComposition(\n harness.wrapComposition(node)\n );\n assert.ok(markdown.length > 0);\n assert.ok(markdown.includes('# Conformance fixture'));\n },\n },\n {\n name: 'renders through renderSlack wrapped in a minimal composition',\n run: ({ node }, harness) => {\n const result = harness.renderSlackComposition(\n harness.wrapComposition(node)\n );\n assert.ok(result.blocks.length > 0);\n assert.ok(result.text.length > 0);\n const first = result.blocks[0];\n assert.ok(first);\n if (first.type !== 'header') {\n assert.fail(`expected a header block, got ${first.type}`);\n }\n assert.equal(first.text.type, 'plain_text');\n },\n },\n {\n name: 'renders a snapshot wrapped in a minimal composition',\n run: async ({ node }, harness) => {\n if (!harness.renderSnapshotComposition) {\n return;\n }\n const result = await harness.renderSnapshotComposition(\n harness.wrapComposition(node)\n );\n assert.deepEqual(result.validationErrors, []);\n assert.ok(result.html.trim().length > 0);\n assert.ok(result.measurement.total > 0);\n },\n },\n];\n"]}
|
|
1
|
+
{"version":3,"file":"conformance.js","sourceRoot":"","sources":["../../../src/testing/conformance.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;AAEH,6EAA6E;AAC7E,EAAE;AACF,8EAA8E;AAC9E,4EAA4E;AAC5E,4EAA4E;AAC5E,yDAAyD;AAEzD,gEAAwC;AAKxC,mEAA8E;AAK9E,+CAK2B;AAG3B,yDAGmC;AACnC,2DAA4D;AAG5D;;;;GAIG;AACU,QAAA,0BAA0B,GAAG,0BAA0B,CAAC;AAErE,iGAAiG;AACpF,QAAA,yBAAyB,GAAG,qBAAqB,CAAC;AAkI/D,8DAA8D;AACvD,MAAM,uBAAuB,GAAG,CACrC,WAA8C,EACN,EAAE,CAC1C,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CACjC,IAAA,qCAAiB,EAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC;IACnE,UAAU;IACV,IAAI,EAAE,UAAU,CAAC,IAAI;IACrB,YAAY;IACZ,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IACpD,IAAI;CACL,CAAC,CAAC,CACJ,CAAC;AAXS,QAAA,uBAAuB,2BAWhC;AAEJ,mEAAmE;AAC5D,MAAM,wBAAwB,GAAG,CACtC,WAA8C,EACuB,EAAE,CACvE,IAAA,+BAAuB,EAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CACvD,iCAAyB,CAAC,GAAG,CAAC,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IAClD,GAAG,OAAO;IACV,GAAG,eAAe;CACnB,CAAC,CAAC,CACJ,CAAC;AARS,QAAA,wBAAwB,4BAQjC;AAEJ;;;;;;GAMG;AACI,MAAM,gCAAgC,GAAG,CAC9C,WAA8C,EACxC,EAAE;IACR,MAAM,QAAQ,GAAG,IAAA,+BAAuB,EAAC,WAAW,CAAC,CAAC;IACtD,gBAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,yCAAyC,CAAC,CAAC;IAC1E,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,gBAAM,CAAC,EAAE,CACP,UAAU,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAC9B,GAAG,UAAU,CAAC,IAAI,6CAA6C,CAChE,CAAC;QACF,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC;QACjD,gBAAM,CAAC,EAAE,CACP,WAAW,KAAK,SAAS,IAAI,WAAW,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAC1D,GAAG,UAAU,CAAC,IAAI,8CAA8C,CACjE,CAAC;QACF,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;QAChC,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,IAAA,qCAAiB,EAAC,UAAU,CAAC,EAAE,CAAC;YACrD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,SAAS;YACX,CAAC;YACD,gBAAM,CAAC,EAAE,CACP,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EACtB,GAAG,UAAU,CAAC,IAAI,kCAAkC,CACrD,CAAC;YACF,gBAAM,CAAC,EAAE,CACP,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAChB,GAAG,UAAU,CAAC,IAAI,2BAA2B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CACpE,CAAC;YACF,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,OAAO,GAAG,IAAA,+BAAgB,EAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7D,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACnB,gBAAM,CAAC,IAAI,CACT,GAAG,UAAU,CAAC,IAAI,qDAAqD,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAC/F,CAAC;QACJ,CAAC;QACD,MAAM,cAAc,GAAG,OAAO,CAAC,KAAK,CAAC;QACrC,MAAM,gBAAgB,GAAG,IAAA,gCAAY,EAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YAC9D,MAAM,SAAS,GAAG,IAAA,+BAAgB,EAAC,IAAI,CAAC,CAAC;YACzC,OAAO,CACL,SAAS,CAAC,KAAK;gBACf,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CACnE,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,IAAI,gBAAgB,EAAE,CAAC;YACrB,SAAS;QACX,CAAC;QACD,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QAC3D,gBAAM,CAAC,EAAE,CACP,MAAM,CAAC,OAAO,EACd,GAAG,UAAU,CAAC,IAAI,6EAA6E,CAChG,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,QAAQ,EAAE,CAAC;QACtC,gBAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAChC,CAAC;AACH,CAAC,CAAC;AAxDW,QAAA,gCAAgC,oCAwD3C;AAEF,MAAM,WAAW,GAAG,CAAC,EACnB,IAAI,EACJ,YAAY,EACZ,WAAW,GACiB,EAAU,EAAE,CACxC,sBAAsB,IAAI,2BAA2B,YAAY,GAAG;IACpE,GAAG,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC;AAE7E,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAY,EAAE;IACpD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC;QACxD,KAAK,CAAC,CAAC,CAAE;aACN,KAAK,CAAC,KAAK,CAAC;aACZ,MAAM,CAAC,OAAO,CAAC;aACf,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;AAChC,CAAC,CAAC;AAEF,sEAAsE;AACtE,MAAM,eAAe,GAAG,CAAC,IAAY,EAAY,EAAE;IACjD,MAAM,SAAS,GAAG,IAAI,MAAM,CAAC,MAAM,+BAAqB,YAAY,CAAC,CAAC;IACtE,4FAA4F;IAC5F,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE;QAC9D,MAAM,CAAC,EAAE,KAAK,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAC5C,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,SAAiB,EAAU,EAAE,CACnD,SAAS,CAAC,OAAO,CAAC,uCAAuC,EAAE,MAAM,CAAC,CAAC;AAErE,MAAM,mBAAmB,GAAG,CAAC,GAAW,EAAE,SAAiB,EAAW,EAAE,CACtE,IAAI,MAAM,CAAC,MAAM,cAAc,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEpE;;;GAGG;AACU,QAAA,yBAAyB,GAAwC;IAC5E;QACE,IAAI,EAAE,wDAAwD;QAC9D,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;YACxB,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;YACzB,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;YAClC,MAAM,eAAe,GAAG,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;YACxD,gBAAM,CAAC,SAAS,CAAC,eAAe,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;YAC1E,gBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YACvC,gBAAM,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;QAC5C,CAAC;KACF;IACD;QACE,IAAI,EAAE,wCAAwC;QAC9C,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE;YACzB,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YAC3C,gBAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QACvC,CAAC;KACF;IACD;QACE,IAAI,EAAE,kCAAkC;QACxC,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE;YACzB,gBAAM,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;QACzD,CAAC;KACF;IACD;QACE,IAAI,EAAE,iEAAiE;QACvE,GAAG,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE;YACrC,IAAI,CAAC,UAAU,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC;gBACtD,OAAO;YACT,CAAC;YACD,MAAM,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;YAC9C,gBAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC;YACxD,gBAAM,CAAC,EAAE,CACP,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,kCAA0B,CAAC,CAChE,CAAC;YACF,gBAAM,CAAC,EAAE,CACP,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,kCAA0B,CAAC,CACpE,CAAC;QACJ,CAAC;KACF;IACD;QACE,IAAI,EAAE,kDAAkD;QACxD,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE;YACzB,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACtC,gBAAM,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,QAAQ,CAAC,CAAC;YACpC,gBAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACpC,CAAC;KACF;IACD;QACE,IAAI,EAAE,gDAAgD;QACtD,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE;YACzB,MAAM,QAAQ,GAAG,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;YAC9C,gBAAM,CAAC,KAAK,CAAC,OAAO,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACxC,gBAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACxC,CAAC;KACF;IACD;QACE,IAAI,EAAE,6DAA6D;QACnE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE;YACzB,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YACzC,gBAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAC7B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,gBAAM,CAAC,KAAK,CAAC,OAAO,KAAK,EAAE,QAAQ,CAAC,CAAC;gBACrC,gBAAM,CAAC,KAAK,CAAC,OAAO,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;KACF;IACD;QACE,IAAI,EAAE,+CAA+C;QACrD,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;YACxB,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,OAAO;iBAC3B,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;iBACzB,OAAO,CAAC,CAAC,KAAK,EAAyB,EAAE,CACxC,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CACtE;iBACA,MAAM,CAAC,iCAAqB,CAAC,EAAE,CAAC;gBACjC,gBAAM,CAAC,EAAE,CACP,CAAC,IAAA,mCAAuB,EAAC,IAAI,CAAC,EAC9B,mBAAmB,IAAI,+DAA+D,WAAW,CAAC,OAAO,CAAC,EAAE,CAC7G,CAAC;YACJ,CAAC;QACH,CAAC;KACF;IACD;QACE,IAAI,EAAE,8DAA8D;QACpE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE;YAC7C,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;gBAC5B,OAAO;YACT,CAAC;YACD,gBAAM,CAAC,YAAY,CAAC,GAAG,EAAE,CACvB,OAAO,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,eAAe,IAAI,IAAI,YAAY,EAAE,CAAC,CACtE,CAAC;QACJ,CAAC;KACF;IACD;QACE,IAAI,EAAE,oDAAoD;QAC1D,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE;YACzB,IACE,OAAO,CAAC,oBAAoB,KAAK,KAAK;gBACtC,CAAC,OAAO,CAAC,sBAAsB,EAC/B,CAAC;gBACD,OAAO;YACT,CAAC;YACD,MAAM,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;YACpD,gBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;YAC5C,gBAAM,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACxB,CAAC;KACF;IACD;QACE,IAAI,EAAE,6DAA6D;QACnE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE;YACzB,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;gBACxB,OAAO;YACT,CAAC;YACD,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;YACjE,gBAAM,CAAC,SAAS,CAAC,MAAM,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;YAC9C,gBAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;YAC5C,gBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YACvC,gBAAM,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAC1C,CAAC;KACF;IACD;QACE,IAAI,EAAE,sCAAsC;QAC5C,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE;YACzB,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;gBACxB,OAAO;YACT,CAAC;YACD,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;YACnE,gBAAM,CAAC,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9C,CAAC;KACF;IACD;QACE,IAAI,EAAE,gDAAgD;QACtD,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;YACxB,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;gBAC/C,OAAO;YACT,CAAC;YACD,MAAM,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC1D,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACpE,MAAM,QAAQ,GAAG,IAAA,uBAAa,EAC5B,WAAW,CAAC,IAAI,EAChB,OAAO,CAAC,UAAU,CACnB,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;gBACrB,MAAM,YAAY,GAAG,IAAA,kBAAQ,EAAC,QAAQ,CAAC,CAAC;gBACxC,OAAO,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAA,qBAAW,EAAC,YAAY,CAAC,CAAC,CAAC;YACvE,CAAC,CAAC,CAAC;YACH,gBAAM,CAAC,SAAS,CACd,eAAe,CAAC,IAAI,CAAC,EACrB,QAAQ,EACR,kDAAkD,WAAW,CAAC,OAAO,CAAC,EAAE,CACzE,CAAC;QACJ,CAAC;KACF;IACD;QACE,IAAI,EAAE,qEAAqE;QAC3E,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE;YACzB,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC,OAAO,CAAC,6BAA6B,EAAE,CAAC;gBAClE,OAAO;YACT,CAAC;YACD,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE;gBAC/D,GAAG,EAAE,UAAU;aAChB,CAAC,CAAC;YACH,OAAO,CAAC,6BAA6B,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACpD,CAAC;KACF;IACD;QACE,IAAI,EAAE,iEAAiE;QACvE,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;YACxB,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;gBACxB,OAAO;YACT,CAAC;YACD,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;YAC7C,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE;gBAC/D,GAAG,EAAE,UAAU;gBACf,KAAK,EAAE,UAAU;aAClB,CAAC,CAAC;YACH,MAAM,OAAO,GAAG,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CACpD,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,CAC3D,CAAC;YACF,MAAM,IAAI,GACR,mBAAmB,IAAI,aAAa,YAAY,IAAI;gBACpD,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,IAAI;gBACrC,WAAW,CAAC,OAAO,CAAC,CAAC;YACvB,gBAAM,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;QACtC,CAAC;KACF;IACD;QACE,IAAI,EAAE,6DAA6D;QACnE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE;YACzB,MAAM,IAAI,GAAG,OAAO,CAAC,qBAAqB,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;YAC1E,gBAAM,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAC3B,gBAAM,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,CAAC;QAClD,CAAC;KACF;IACD;QACE,IAAI,EAAE,iEAAiE;QACvE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE;YACzB,MAAM,QAAQ,GAAG,OAAO,CAAC,yBAAyB,CAChD,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAC9B,CAAC;YACF,gBAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAC/B,gBAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC,CAAC;QACxD,CAAC;KACF;IACD;QACE,IAAI,EAAE,8DAA8D;QACpE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE;YACzB,MAAM,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAC3C,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAC9B,CAAC;YACF,gBAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACpC,gBAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAClC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC/B,gBAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;YACjB,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC5B,gBAAM,CAAC,IAAI,CAAC,gCAAgC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5D,CAAC;YACD,gBAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QAC9C,CAAC;KACF;IACD;QACE,IAAI,EAAE,qDAAqD;QAC3D,GAAG,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE;YAC/B,IAAI,CAAC,OAAO,CAAC,yBAAyB,EAAE,CAAC;gBACvC,OAAO;YACT,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,yBAAyB,CACpD,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAC9B,CAAC;YACF,gBAAM,CAAC,SAAS,CAAC,MAAM,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;YAC9C,gBAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACzC,gBAAM,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAC1C,CAAC;KACF;CACF,CAAC","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\n// The behaviour every primitive definition owes its callers, expressed once.\n//\n// Framework-agnostic on purpose: only `node:assert/strict` and Node builtins,\n// so this ships on a public entry without dragging vitest into a vocabulary\n// package's dependency set. Each pack drives the array with `it.each`, so a\n// second vocabulary costs one package and one test file.\n\nimport assert from 'node:assert/strict';\n\nimport type { ChildNodeWalker } from '../composition/body_node_base';\nimport type { Composition } from '../composition/composition';\nimport type { ValidationError } from '../composition/validation_error';\nimport { exampleNodes, primitiveExamples } from '../define/primitive_example';\nimport type {\n AnyPrimitiveDefinition,\n PrimitiveNode,\n} from '../define/primitive_module';\nimport {\n anchoredNodes,\n anchorValue,\n NODE_ANCHOR_ATTRIBUTE,\n nodeType,\n} from '../render/anchors';\nimport type { HTMLRenderResult } from '../render/html/envelope';\nimport type { SlackBlock } from '../render/slack/blocks';\nimport {\n isModeledSlackBlockType,\n isUnmodeledSlackBlock,\n} from '../render/slack/unmodeled';\nimport { checkInputBudget } from '../validate/input_budget';\nimport type { ValidationResult } from '../validate/validation';\n\n/**\n * The foreign node {@link PrimitiveConformanceHarness.nestForeignChild}\n * hands a container must render text/markdown containing this string, or the\n * cross-pack nesting case cannot tell a dropped child from an empty one.\n */\nexport const CONFORMANCE_FOREIGN_MARKER = 'isomerConformanceForeign';\n\n/** The `title` {@link PrimitiveConformanceHarness.wrapComposition} must give its composition. */\nexport const CONFORMANCE_FIXTURE_TITLE = 'Conformance fixture';\n\n/** One example node, paired with the definition that published it. */\nexport interface PrimitiveConformanceExample {\n readonly definition: AnyPrimitiveDefinition;\n /** Always `definition.type`, lifted onto the row so `it.each` titles can read it. */\n readonly type: string;\n /** Index into {@link AnyPrimitiveDefinition.examples}, and half of the preview hint a failure prints. */\n readonly exampleIndex: number;\n /** The example's `name`, absent for a bare node. */\n readonly exampleName?: string;\n readonly node: PrimitiveNode;\n}\n\n/** The subset of a host's HTML render options the cases exercise. */\nexport interface PrimitiveConformanceHtmlOptions {\n /** `'separate'` must move the stylesheet out of the markup and into `css`; the CSS cases assert against that field. */\n readonly css?: 'inline' | 'separate';\n /** `'readable'` must emit human-legible class names, which the CSS coverage case matches back against the emitted selectors. */\n readonly names?: string;\n /** Must render node anchors, as the `anchors` HTML render option does. */\n readonly anchors?: boolean;\n}\n\n/** The subset of a host's `snapshot` render result the cases assert on. */\nexport interface PrimitiveConformanceSnapshotResult {\n /** Must be empty for every published example. */\n readonly validationErrors: readonly ValidationError[];\n /** The frame's markup, stylesheet included or not. */\n readonly html: string;\n /** `total` is the rendered byte size, and must be positive. */\n readonly measurement: { readonly total: number };\n}\n\n/** The subset of a host's Slack render result the cases assert on. */\nexport interface PrimitiveConformanceSlackResult {\n readonly blocks: readonly SlackBlock[];\n /** Notification fallback text. Must be non-empty. */\n readonly text: string;\n}\n\n/**\n * Pack-owned render and validation bindings. The cases cannot import a\n * vocabulary package, so the pack closes over its dispatcher, frame, and\n * theme when it builds this object.\n *\n * Unsuffixed members take a single node; the `Composition`-suffixed ones take\n * a whole {@link Composition}. Optional members gate the cases that need\n * them, so a pack supplies only what its surfaces can answer.\n */\nexport interface PrimitiveConformanceHarness {\n /**\n * The smallest composition that carries one node. Its `title` must be\n * {@link CONFORMANCE_FIXTURE_TITLE}, which the envelope cases look for as\n * `CONFORMANCE FIXTURE` in text and `# Conformance fixture` in markdown.\n */\n wrapComposition(node: PrimitiveNode): Composition;\n /** Validation errors for the node on its own. Must be empty for every published example. */\n validateNode(node: PrimitiveNode): readonly ValidationError[];\n /** Whole-composition validation. Must be `valid` with no `errors` for a wrapped example. */\n validateComposition(composition: Composition): ValidationResult;\n /** Must return something other than `undefined`; the case does not mount the element. */\n renderReact(node: PrimitiveNode): unknown;\n /** Drives the pack's style collection for one node. Must not throw. */\n collectStyles(node: PrimitiveNode): void;\n /** Must return a string with non-whitespace content. */\n renderText(node: PrimitiveNode): string;\n /** Must return a string with non-whitespace content. */\n renderMarkdown(node: PrimitiveNode): string;\n /** Must return at least one block, each an object with a string `type`. */\n renderSlack(node: PrimitiveNode): readonly SlackBlock[];\n /** `key` is unique per example and only has to survive into the React tree. Must not throw. Omit for a pack with no `snapshot` path. */\n renderSnapshot?(node: PrimitiveNode, key: string): unknown;\n /** Must be finite and greater than zero, so a frame can lay the node out unrendered. Omit for a pack with no `snapshot` path. */\n estimateSnapshotHeight?(node: PrimitiveNode): number;\n /**\n * Set `false` for a pack whose frame is a fixed size, so its primitives are\n * not required to report a positive `metrics.snapshotHeight`. Skips the\n * positive-finite height assertion.\n */\n sizesFromNodeHeights?: boolean;\n /**\n * For a container example, returns `container` with one of its children\n * replaced by a node from a pack the harness composed in only for this\n * check — never one `container`'s own pack registers. That node's `text`\n * and `markdown` renderers must emit {@link CONFORMANCE_FOREIGN_MARKER}.\n * Omit to skip the cross-pack nesting case.\n */\n nestForeignChild?(container: PrimitiveNode): PrimitiveNode;\n /**\n * Must honor {@link PrimitiveConformanceHtmlOptions}. Cases assert the\n * markup wraps the body in a `<section>`, that `measurement.js` is zero, and\n * that `validationErrors` is empty. Omit to skip the HTML cases.\n */\n renderHTML?(\n composition: Composition,\n options?: PrimitiveConformanceHtmlOptions\n ): HTMLRenderResult;\n /**\n * The child walker over every definition the harness renders with. Set it\n * once every `react` renderer spreads `nodeAnchor` on its root; the anchor\n * case then asserts each node renders one.\n */\n anchorWalk?: ChildNodeWalker;\n /** Must throw when `css` references a `var(--name)` it never declares. Omit to skip the CSS variable case. */\n assertVarRefsHaveDeclarations?(css: string): void;\n /** Whole-composition text render, title envelope included. */\n renderTextComposition(composition: Composition): string;\n /** Whole-composition markdown render, title heading included. */\n renderMarkdownComposition(composition: Composition): string;\n /** Must lead with a `plain_text` header block carrying the composition title. */\n renderSlackComposition(\n composition: Composition\n ): PrimitiveConformanceSlackResult;\n /** Must resolve to non-empty markup with no validation errors. Omit for a pack with no frame. */\n renderSnapshotComposition?(\n composition: Composition\n ): Promise<PrimitiveConformanceSnapshotResult>;\n}\n\n/** One assertion, run once per example. */\nexport interface PrimitiveConformanceCase {\n readonly name: string;\n /** Signals failure by throwing. May be async, so a pack must await it. */\n readonly run: (\n example: PrimitiveConformanceExample,\n harness: PrimitiveConformanceHarness\n ) => void | Promise<void>;\n}\n\n/** Every definition's examples, flattened to one row each. */\nexport const examplesFromDefinitions = (\n definitions: readonly AnyPrimitiveDefinition[]\n): readonly PrimitiveConformanceExample[] =>\n definitions.flatMap((definition) =>\n primitiveExamples(definition).map(({ name, node }, exampleIndex) => ({\n definition,\n type: definition.type,\n exampleIndex,\n ...(name === undefined ? {} : { exampleName: name }),\n node,\n }))\n );\n\n/** Every example crossed with every case, shaped for `it.each`. */\nexport const primitiveConformanceRows = (\n definitions: readonly AnyPrimitiveDefinition[]\n): readonly (PrimitiveConformanceExample & PrimitiveConformanceCase)[] =>\n examplesFromDefinitions(definitions).flatMap((example) =>\n primitiveConformanceCases.map((conformanceCase) => ({\n ...example,\n ...conformanceCase,\n }))\n );\n\n/**\n * Asserts the inventory itself holds up: the pack has examples, every\n * definition contributes one, `catalog.name` and example names are non-empty,\n * example names are unique within their definition, each example's `type` matches its definition, and\n * `catalog.example` is within the input budget and parses or matches a\n * published example.\n */\nexport const runPrimitiveInventoryConformance = (\n definitions: readonly AnyPrimitiveDefinition[]\n): void => {\n const examples = examplesFromDefinitions(definitions);\n assert.ok(examples.length > 0, 'expected at least one primitive example');\n for (const definition of definitions) {\n assert.ok(\n definition.examples.length > 0,\n `${definition.type} primitive must expose at least one example`\n );\n const { name: catalogName } = definition.catalog;\n assert.ok(\n catalogName === undefined || catalogName.trim().length > 0,\n `${definition.type} catalog.name must be non-empty when present`\n );\n const names = new Set<string>();\n for (const { name } of primitiveExamples(definition)) {\n if (name === undefined) {\n continue;\n }\n assert.ok(\n name.trim().length > 0,\n `${definition.type} example names must be non-empty`\n );\n assert.ok(\n !names.has(name),\n `${definition.type} has two examples named ${JSON.stringify(name)}`\n );\n names.add(name);\n }\n const checked = checkInputBudget(definition.catalog.example);\n if (!checked.valid) {\n assert.fail(\n `${definition.type} catalog.example must be within the input budget: ${checked.error.message}`\n );\n }\n const catalogExample = checked.value;\n const matchesPublished = exampleNodes(definition).some((node) => {\n const published = checkInputBudget(node);\n return (\n published.valid &&\n JSON.stringify(published.value) === JSON.stringify(catalogExample)\n );\n });\n if (matchesPublished) {\n continue;\n }\n const parsed = definition.schema.safeParse(catalogExample);\n assert.ok(\n parsed.success,\n `${definition.type} catalog.example must parse against its schema or match a published example`\n );\n }\n for (const { type, node } of examples) {\n assert.equal(node.type, type);\n }\n};\n\nconst previewHint = ({\n type,\n exampleIndex,\n exampleName,\n}: PrimitiveConformanceExample): string =>\n `Failing example: \\`${type}\\` definition, examples[${exampleIndex}]` +\n `${exampleName === undefined ? '' : ` (${JSON.stringify(exampleName)})`}.`;\n\nconst renderedClassNames = (html: string): string[] => {\n const classNames = new Set<string>();\n for (const match of html.matchAll(/\\bclass=\"([^\"]+)\"/g)) {\n match[1]!\n .split(/\\s+/)\n .filter(Boolean)\n .forEach((className) => classNames.add(className));\n }\n return [...classNames].sort();\n};\n\n/** The node anchor values in serialized `html`, in document order. */\nconst renderedAnchors = (html: string): string[] => {\n const attribute = new RegExp(`\\\\s${NODE_ANCHOR_ATTRIBUTE}=\"([^\"]*)\"`);\n // Only opening tags: the serializer escapes `<`, `>`, and `\"` in text and attribute values.\n return [...html.matchAll(/<[a-zA-Z][^>]*>/g)].flatMap(([tag]) => {\n const [, value] = attribute.exec(tag) ?? [];\n return value === undefined ? [] : [value];\n });\n};\n\nconst cssEscapeClass = (className: string): string =>\n className.replace(/([!\"#$%&'()*+,./:;<=>?@[\\\\\\]^`{|}~])/g, '\\\\$1');\n\nconst cssHasClassSelector = (css: string, className: string): boolean =>\n new RegExp(`\\\\.${cssEscapeClass(className)}(?![\\\\w-])`).test(css);\n\n/**\n * Every assertion a primitive owes its callers, for a pack to drive with\n * `it.each`.\n */\nexport const primitiveConformanceCases: readonly PrimitiveConformanceCase[] = [\n {\n name: 'validates as a primitive node and inside a composition',\n run: (example, harness) => {\n const { node } = example;\n const hint = previewHint(example);\n const primitiveErrors = [...harness.validateNode(node)];\n assert.deepEqual(primitiveErrors, [], hint);\n const result = harness.validateComposition(harness.wrapComposition(node));\n assert.equal(result.valid, true, hint);\n assert.deepEqual(result.errors, [], hint);\n },\n },\n {\n name: 'renders through React without throwing',\n run: ({ node }, harness) => {\n const rendered = harness.renderReact(node);\n assert.notEqual(rendered, undefined);\n },\n },\n {\n name: 'collects styles without throwing',\n run: ({ node }, harness) => {\n assert.doesNotThrow(() => harness.collectStyles(node));\n },\n },\n {\n name: 'a container recurses through scope for a node from another pack',\n run: ({ definition, node }, harness) => {\n if (!definition.children || !harness.nestForeignChild) {\n return;\n }\n const nested = harness.nestForeignChild(node);\n assert.notEqual(harness.renderReact(nested), undefined);\n assert.ok(\n harness.renderText(nested).includes(CONFORMANCE_FOREIGN_MARKER)\n );\n assert.ok(\n harness.renderMarkdown(nested).includes(CONFORMANCE_FOREIGN_MARKER)\n );\n },\n },\n {\n name: 'renders through plain text with non-empty output',\n run: ({ node }, harness) => {\n const text = harness.renderText(node);\n assert.equal(typeof text, 'string');\n assert.ok(text.trim().length > 0);\n },\n },\n {\n name: 'renders through markdown with non-empty output',\n run: ({ node }, harness) => {\n const markdown = harness.renderMarkdown(node);\n assert.equal(typeof markdown, 'string');\n assert.ok(markdown.trim().length > 0);\n },\n },\n {\n name: 'renders through Slack dispatch returning at least one block',\n run: ({ node }, harness) => {\n const blocks = harness.renderSlack(node);\n assert.ok(blocks.length > 0);\n for (const block of blocks) {\n assert.equal(typeof block, 'object');\n assert.equal(typeof block.type, 'string');\n }\n },\n },\n {\n name: 'wraps only Slack blocks Isomer does not model',\n run: (example, harness) => {\n for (const { type } of harness\n .renderSlack(example.node)\n .flatMap((block): readonly SlackBlock[] =>\n block.type === 'container' ? [block, ...block.child_blocks] : [block]\n )\n .filter(isUnmodeledSlackBlock)) {\n assert.ok(\n !isModeledSlackBlockType(type),\n `Isomer models \\`${type}\\` blocks: return this one without \\`unmodeledSlackBlock\\`. ${previewHint(example)}`\n );\n }\n },\n },\n {\n name: 'renders through snapshot primitive dispatch without throwing',\n run: ({ type, exampleIndex, node }, harness) => {\n if (!harness.renderSnapshot) {\n return;\n }\n assert.doesNotThrow(() =>\n harness.renderSnapshot?.(node, `conformance-${type}-${exampleIndex}`)\n );\n },\n },\n {\n name: 'reports a positive finite snapshot height estimate',\n run: ({ node }, harness) => {\n if (\n harness.sizesFromNodeHeights === false ||\n !harness.estimateSnapshotHeight\n ) {\n return;\n }\n const height = harness.estimateSnapshotHeight(node);\n assert.equal(Number.isFinite(height), true);\n assert.ok(height > 0);\n },\n },\n {\n name: 'renders through renderHTML wrapped in a minimal composition',\n run: ({ node }, harness) => {\n if (!harness.renderHTML) {\n return;\n }\n const result = harness.renderHTML(harness.wrapComposition(node));\n assert.deepEqual(result.validationErrors, []);\n assert.ok(result.html.includes('<section'));\n assert.equal(result.measurement.js, 0);\n assert.ok(result.measurement.total > 0);\n },\n },\n {\n name: 'renders no node anchors unless asked',\n run: ({ node }, harness) => {\n if (!harness.renderHTML) {\n return;\n }\n const { body } = harness.renderHTML(harness.wrapComposition(node));\n assert.deepEqual(renderedAnchors(body), []);\n },\n },\n {\n name: 'renders a node anchor on every node when asked',\n run: (example, harness) => {\n if (!harness.renderHTML || !harness.anchorWalk) {\n return;\n }\n const composition = harness.wrapComposition(example.node);\n const { body } = harness.renderHTML(composition, { anchors: true });\n const expected = anchoredNodes(\n composition.body,\n harness.anchorWalk\n ).flatMap((anchored) => {\n const anchoredType = nodeType(anchored);\n return anchoredType === undefined ? [] : [anchorValue(anchoredType)];\n });\n assert.deepEqual(\n renderedAnchors(body),\n expected,\n `Expected one anchor per node, in walker order. ${previewHint(example)}`\n );\n },\n },\n {\n name: 'emits CSS where every var(...) reference has a matching declaration',\n run: ({ node }, harness) => {\n if (!harness.renderHTML || !harness.assertVarRefsHaveDeclarations) {\n return;\n }\n const result = harness.renderHTML(harness.wrapComposition(node), {\n css: 'separate',\n });\n harness.assertVarRefsHaveDeclarations(result.css);\n },\n },\n {\n name: 'reaches every rendered readable class in compact CSS collection',\n run: (example, harness) => {\n if (!harness.renderHTML) {\n return;\n }\n const { type, exampleIndex, node } = example;\n const result = harness.renderHTML(harness.wrapComposition(node), {\n css: 'separate',\n names: 'readable',\n });\n const missing = renderedClassNames(result.body).filter(\n (className) => !cssHasClassSelector(result.css, className)\n );\n const hint =\n `Missing CSS for ${type} example #${exampleIndex}: ` +\n `${missing.join(', ') || '(none)'}. ` +\n previewHint(example);\n assert.deepEqual(missing, [], hint);\n },\n },\n {\n name: 'renders through renderText wrapped in a minimal composition',\n run: ({ node }, harness) => {\n const text = harness.renderTextComposition(harness.wrapComposition(node));\n assert.ok(text.length > 0);\n assert.ok(text.includes('CONFORMANCE FIXTURE'));\n },\n },\n {\n name: 'renders through renderMarkdown wrapped in a minimal composition',\n run: ({ node }, harness) => {\n const markdown = harness.renderMarkdownComposition(\n harness.wrapComposition(node)\n );\n assert.ok(markdown.length > 0);\n assert.ok(markdown.includes('# Conformance fixture'));\n },\n },\n {\n name: 'renders through renderSlack wrapped in a minimal composition',\n run: ({ node }, harness) => {\n const result = harness.renderSlackComposition(\n harness.wrapComposition(node)\n );\n assert.ok(result.blocks.length > 0);\n assert.ok(result.text.length > 0);\n const first = result.blocks[0];\n assert.ok(first);\n if (first.type !== 'header') {\n assert.fail(`expected a header block, got ${first.type}`);\n }\n assert.equal(first.text.type, 'plain_text');\n },\n },\n {\n name: 'renders a snapshot wrapped in a minimal composition',\n run: async ({ node }, harness) => {\n if (!harness.renderSnapshotComposition) {\n return;\n }\n const result = await harness.renderSnapshotComposition(\n harness.wrapComposition(node)\n );\n assert.deepEqual(result.validationErrors, []);\n assert.ok(result.html.trim().length > 0);\n assert.ok(result.measurement.total > 0);\n },\n },\n];\n"]}
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
* 2.0.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.assertPackRegistrationComplete = exports.assertPackIconsValid = exports.runPrimitiveInventoryConformance = exports.primitiveConformanceRows = exports.CONFORMANCE_FOREIGN_MARKER = void 0;
|
|
9
|
+
exports.assertPackRegistrationComplete = exports.assertPackIconsValid = exports.runPrimitiveInventoryConformance = exports.primitiveConformanceRows = exports.CONFORMANCE_FOREIGN_MARKER = exports.CONFORMANCE_FIXTURE_TITLE = void 0;
|
|
10
10
|
var conformance_1 = require("./conformance");
|
|
11
|
+
Object.defineProperty(exports, "CONFORMANCE_FIXTURE_TITLE", { enumerable: true, get: function () { return conformance_1.CONFORMANCE_FIXTURE_TITLE; } });
|
|
11
12
|
Object.defineProperty(exports, "CONFORMANCE_FOREIGN_MARKER", { enumerable: true, get: function () { return conformance_1.CONFORMANCE_FOREIGN_MARKER; } });
|
|
12
13
|
Object.defineProperty(exports, "primitiveConformanceRows", { enumerable: true, get: function () { return conformance_1.primitiveConformanceRows; } });
|
|
13
14
|
Object.defineProperty(exports, "runPrimitiveInventoryConformance", { enumerable: true, get: function () { return conformance_1.runPrimitiveInventoryConformance; } });
|