@knapsack/rendering-utils 4.92.12--canary.5d3ca10.0 → 4.92.12
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/.turbo/turbo-build.log
CHANGED
package/.turbo/turbo-lint.log
CHANGED
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,19 +1,32 @@
|
|
|
1
1
|
|
|
2
|
-
> @knapsack/rendering-utils@4.92.
|
|
2
|
+
> @knapsack/rendering-utils@4.92.11 test /home/runner/work/app-monorepo/app-monorepo/libs/rendering-utils
|
|
3
3
|
> ava
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
6
|
+
[blocks-to-html] TipTap render failed for block "test-1" (text-editor): RangeError: Unknown node type: this-node-type-does-not-exist
|
|
7
|
+
at Schema.nodeType (file:///home/runner/work/app-monorepo/app-monorepo/node_modules/.pnpm/prosemirror-model@1.25.4/node_modules/prosemirror-model/dist/index.js:2500:19)
|
|
8
|
+
at Node.fromJSON (file:///home/runner/work/app-monorepo/app-monorepo/node_modules/.pnpm/prosemirror-model@1.25.4/node_modules/prosemirror-model/dist/index.js:1540:27)
|
|
9
|
+
at Schema.nodeFromJSON (file:///home/runner/work/app-monorepo/app-monorepo/node_modules/.pnpm/prosemirror-model@1.25.4/node_modules/prosemirror-model/dist/index.js:2458:42)
|
|
10
|
+
at Array.map (<anonymous>)
|
|
11
|
+
at Fragment.fromJSON (file:///home/runner/work/app-monorepo/app-monorepo/node_modules/.pnpm/prosemirror-model@1.25.4/node_modules/prosemirror-model/dist/index.js:314:35)
|
|
12
|
+
at Node.fromJSON (file:///home/runner/work/app-monorepo/app-monorepo/node_modules/.pnpm/prosemirror-model@1.25.4/node_modules/prosemirror-model/dist/index.js:1539:32)
|
|
13
|
+
at generateHTML (/home/runner/work/app-monorepo/app-monorepo/node_modules/.pnpm/@tiptap+html@3.20.0_@tiptap+core@3.20.0_@tiptap+pm@3.20.0__@tiptap+pm@3.20.0_happy-dom@_fb9f5841e8c1bd3ab1a0faf6f7899695/node_modules/@tiptap/html/src/server/generateHTML.ts:30:28)
|
|
14
|
+
at convertTipTapJsonToHtml (/home/runner/work/app-monorepo/app-monorepo/libs/tiptap-utils/src/tiptap-utils.ts:27:10)
|
|
15
|
+
at tiptapToHtmlSafe (/home/runner/work/app-monorepo/app-monorepo/libs/rendering-utils/src/blocks-to-html.ts:43:12)
|
|
16
|
+
at blockToHtml (/home/runner/work/app-monorepo/app-monorepo/libs/rendering-utils/src/blocks-to-html.ts:59:14)
|
|
17
|
+
✔ blocksToHtml - empty array (157ms)
|
|
18
|
+
✔ blocksToHtml - single divider-block (149ms)
|
|
19
|
+
✔ blocksToHtml - single text-editor block (148ms)
|
|
20
|
+
✔ blocksToHtml - single code-snippet block (124ms)
|
|
21
|
+
✔ blocksToHtml - single callout block (113ms)
|
|
22
|
+
✔ blocksToHtml - single callout block with error type (106ms)
|
|
23
|
+
✔ blocksToHtml - single image-block with single image (101ms)
|
|
24
|
+
✔ blocksToHtml - single image-block with multiple images (101ms)
|
|
25
|
+
✔ blocksToHtml - single image-block with no images (101ms)
|
|
26
|
+
✔ blocksToHtml - single image-block with empty images array (101ms)
|
|
27
|
+
✔ blocksToHtml - single video block (101ms)
|
|
28
|
+
✔ blocksToHtml - video block with no selected video
|
|
29
|
+
✔ blocksToHtml - text-editor with unknown TipTap node type does not throw
|
|
17
30
|
✔ blocksToHtml - single files-list block with image files
|
|
18
31
|
✔ blocksToHtml - single files-list block with non-image files
|
|
19
32
|
✔ blocksToHtml - single files-list block with mixed files
|
|
@@ -37,11 +50,11 @@ marked(): mangle parameter is enabled by default, but is deprecated since versio
|
|
|
37
50
|
marked(): headerIds and headerPrefix parameters enabled by default, but are deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install https://www.npmjs.com/package/marked-gfm-heading-id, or disable by setting `{headerIds: false}`.
|
|
38
51
|
marked(): mangle parameter is enabled by default, but is deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install https://www.npmjs.com/package/marked-mangle, or disable by setting `{mangle: false}`.
|
|
39
52
|
marked(): headerIds and headerPrefix parameters enabled by default, but are deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install https://www.npmjs.com/package/marked-gfm-heading-id, or disable by setting `{headerIds: false}`.
|
|
40
|
-
✔ blocksToHtml - single markdown-block with string (
|
|
41
|
-
✔ blocksToHtml - single markdown-block with array (
|
|
42
|
-
✔ blocksToHtml - single markdown-block with empty string (
|
|
43
|
-
✔ blocksToHtml - single markdown-block with undefined md (
|
|
44
|
-
✔ blocksToHtml - multiple different block types (
|
|
53
|
+
✔ blocksToHtml - single markdown-block with string (167ms)
|
|
54
|
+
✔ blocksToHtml - single markdown-block with array (166ms)
|
|
55
|
+
✔ blocksToHtml - single markdown-block with empty string (166ms)
|
|
56
|
+
✔ blocksToHtml - single markdown-block with undefined md (166ms)
|
|
57
|
+
✔ blocksToHtml - multiple different block types (139ms)
|
|
45
58
|
─
|
|
46
59
|
|
|
47
|
-
|
|
60
|
+
31 tests passed
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blocks-to-html.d.ts","sourceRoot":"","sources":["../src/blocks-to-html.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"blocks-to-html.d.ts","sourceRoot":"","sources":["../src/blocks-to-html.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAwInD,wBAAsB,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAMzE"}
|
package/dist/blocks-to-html.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @module @knapsack/rendering-utils/blocks-to-html
|
|
4
4
|
* @description Convert Knapsack Blocks to html
|
|
5
5
|
*/
|
|
6
|
-
import { convertTipTapJsonToHtml } from '@knapsack/tiptap-utils';
|
|
6
|
+
import { convertTipTapJsonToHtml, } from '@knapsack/tiptap-utils';
|
|
7
7
|
import os from 'node:os';
|
|
8
8
|
import domPurify from 'isomorphic-dompurify';
|
|
9
9
|
const EOL = os.EOL || '\n';
|
|
@@ -20,6 +20,20 @@ function escapeAttr(val = '') {
|
|
|
20
20
|
.replace(/</g, '<')
|
|
21
21
|
.replace(/>/g, '>');
|
|
22
22
|
}
|
|
23
|
+
// TipTap's generateHTML throws (e.g. RangeError: Unknown node type) when
|
|
24
|
+
// stored prose JSON references a node type not registered in the schema.
|
|
25
|
+
// That's schema drift, not a programming bug — treat it like the video
|
|
26
|
+
// guard below and degrade to empty content so the rest of the document
|
|
27
|
+
// still renders.
|
|
28
|
+
function tiptapToHtmlSafe(content, blockId, blockType) {
|
|
29
|
+
try {
|
|
30
|
+
return convertTipTapJsonToHtml(content);
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
console.error(`[blocks-to-html] TipTap render failed for block "${blockId}" (${blockType}):`, err);
|
|
34
|
+
return '';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
23
37
|
async function blockToHtml(b) {
|
|
24
38
|
if (!b.data)
|
|
25
39
|
return '';
|
|
@@ -27,22 +41,24 @@ async function blockToHtml(b) {
|
|
|
27
41
|
case 'code-snippet':
|
|
28
42
|
case 'table':
|
|
29
43
|
case 'text-editor':
|
|
30
|
-
return
|
|
44
|
+
return tiptapToHtmlSafe(b.data.content, b.id, b.blockType);
|
|
31
45
|
case 'markdown-block':
|
|
32
46
|
return mdToHtml(Array.isArray(b.data.md) ? b.data.md.join(EOL) : (b.data.md ?? ''));
|
|
33
47
|
case 'divider-block':
|
|
34
48
|
return '<hr />';
|
|
35
49
|
case 'callout': {
|
|
36
50
|
const type = `<span>${escapeAttr(b.data.type)}</span>`;
|
|
37
|
-
const content =
|
|
51
|
+
const content = tiptapToHtmlSafe(b.data.content, b.id, b.blockType);
|
|
38
52
|
return `<blockquote>${type}: ${content}</blockquote>`;
|
|
39
53
|
}
|
|
40
54
|
case 'image-block':
|
|
41
55
|
return (b.data.images
|
|
42
56
|
?.map((i) => `<img src="${escapeAttr(i.src)}" alt="${escapeAttr(i.caption ?? '')}" />`)
|
|
43
57
|
.join(EOL + EOL) ?? '');
|
|
44
|
-
case 'video':
|
|
45
|
-
|
|
58
|
+
case 'video': {
|
|
59
|
+
const url = b.data.video?.url;
|
|
60
|
+
return url ? `<video src="${escapeAttr(url)}" />` : '';
|
|
61
|
+
}
|
|
46
62
|
case 'files-list':
|
|
47
63
|
return b.data.files
|
|
48
64
|
.map((f) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blocks-to-html.js","sourceRoot":"","sources":["../src/blocks-to-html.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,
|
|
1
|
+
{"version":3,"file":"blocks-to-html.js","sourceRoot":"","sources":["../src/blocks-to-html.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knapsack/rendering-utils",
|
|
3
3
|
"description": "",
|
|
4
|
-
"version": "4.92.12
|
|
4
|
+
"version": "4.92.12",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
@@ -25,17 +25,17 @@
|
|
|
25
25
|
"test": "ava"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@knapsack/tiptap-utils": "4.92.12
|
|
29
|
-
"@knapsack/utils": "4.92.12
|
|
28
|
+
"@knapsack/tiptap-utils": "4.92.12",
|
|
29
|
+
"@knapsack/utils": "4.92.12",
|
|
30
30
|
"isomorphic-dompurify": "^1.13.0",
|
|
31
31
|
"marked": "^6.0.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@knapsack/eslint-config-starter": "4.92.12
|
|
35
|
-
"@knapsack/prettier-config": "4.92.12
|
|
36
|
-
"@knapsack/test-ava": "4.92.12
|
|
37
|
-
"@knapsack/types": "4.92.12
|
|
38
|
-
"@knapsack/typescript-config-starter": "4.92.12
|
|
34
|
+
"@knapsack/eslint-config-starter": "4.92.12",
|
|
35
|
+
"@knapsack/prettier-config": "4.92.12",
|
|
36
|
+
"@knapsack/test-ava": "4.92.12",
|
|
37
|
+
"@knapsack/types": "4.92.12",
|
|
38
|
+
"@knapsack/typescript-config-starter": "4.92.12",
|
|
39
39
|
"@types/node": "^22.19.11",
|
|
40
40
|
"ava": "^6.4.1",
|
|
41
41
|
"eslint": "^9.20.0",
|
|
@@ -50,5 +50,5 @@
|
|
|
50
50
|
"directory": "libs/rendering-utils",
|
|
51
51
|
"type": "git"
|
|
52
52
|
},
|
|
53
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "c21da4fbe3ecb3c7038c7aa56e0b4c4f5cb4a959"
|
|
54
54
|
}
|
package/src/blocks-to-html.ts
CHANGED
|
@@ -5,7 +5,10 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { type BlockConfig } from '@knapsack/types';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
convertTipTapJsonToHtml,
|
|
10
|
+
type JSONContent,
|
|
11
|
+
} from '@knapsack/tiptap-utils';
|
|
9
12
|
import os from 'node:os';
|
|
10
13
|
import domPurify from 'isomorphic-dompurify';
|
|
11
14
|
|
|
@@ -26,13 +29,34 @@ function escapeAttr(val = '') {
|
|
|
26
29
|
.replace(/>/g, '>');
|
|
27
30
|
}
|
|
28
31
|
|
|
32
|
+
// TipTap's generateHTML throws (e.g. RangeError: Unknown node type) when
|
|
33
|
+
// stored prose JSON references a node type not registered in the schema.
|
|
34
|
+
// That's schema drift, not a programming bug — treat it like the video
|
|
35
|
+
// guard below and degrade to empty content so the rest of the document
|
|
36
|
+
// still renders.
|
|
37
|
+
function tiptapToHtmlSafe(
|
|
38
|
+
content: JSONContent,
|
|
39
|
+
blockId: string,
|
|
40
|
+
blockType: string,
|
|
41
|
+
): string {
|
|
42
|
+
try {
|
|
43
|
+
return convertTipTapJsonToHtml(content);
|
|
44
|
+
} catch (err) {
|
|
45
|
+
console.error(
|
|
46
|
+
`[blocks-to-html] TipTap render failed for block "${blockId}" (${blockType}):`,
|
|
47
|
+
err,
|
|
48
|
+
);
|
|
49
|
+
return '';
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
29
53
|
async function blockToHtml(b: BlockConfig): Promise<string> {
|
|
30
54
|
if (!b.data) return '';
|
|
31
55
|
switch (b.blockType) {
|
|
32
56
|
case 'code-snippet':
|
|
33
57
|
case 'table':
|
|
34
58
|
case 'text-editor':
|
|
35
|
-
return
|
|
59
|
+
return tiptapToHtmlSafe(b.data.content, b.id, b.blockType);
|
|
36
60
|
case 'markdown-block':
|
|
37
61
|
return mdToHtml(
|
|
38
62
|
Array.isArray(b.data.md) ? b.data.md.join(EOL) : (b.data.md ?? ''),
|
|
@@ -41,7 +65,7 @@ async function blockToHtml(b: BlockConfig): Promise<string> {
|
|
|
41
65
|
return '<hr />';
|
|
42
66
|
case 'callout': {
|
|
43
67
|
const type = `<span>${escapeAttr(b.data.type)}</span>`;
|
|
44
|
-
const content =
|
|
68
|
+
const content = tiptapToHtmlSafe(b.data.content, b.id, b.blockType);
|
|
45
69
|
return `<blockquote>${type}: ${content}</blockquote>`;
|
|
46
70
|
}
|
|
47
71
|
case 'image-block':
|
|
@@ -55,8 +79,10 @@ async function blockToHtml(b: BlockConfig): Promise<string> {
|
|
|
55
79
|
)
|
|
56
80
|
.join(EOL + EOL) ?? ''
|
|
57
81
|
);
|
|
58
|
-
case 'video':
|
|
59
|
-
|
|
82
|
+
case 'video': {
|
|
83
|
+
const url = b.data.video?.url;
|
|
84
|
+
return url ? `<video src="${escapeAttr(url)}" />` : '';
|
|
85
|
+
}
|
|
60
86
|
case 'files-list':
|
|
61
87
|
return b.data.files
|
|
62
88
|
.map((f) => {
|