@knapsack/rendering-utils 4.92.9--canary.7562.fc3fcd2.0 → 4.92.9--canary.7602.1bacad7.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.
@@ -1,4 +1,4 @@
1
1
 
2
- > @knapsack/rendering-utils@4.92.4 build /home/runner/work/app-monorepo/app-monorepo/libs/rendering-utils
2
+ > @knapsack/rendering-utils@4.92.8 build /home/runner/work/app-monorepo/app-monorepo/libs/rendering-utils
3
3
  > tsc
4
4
 
@@ -1,4 +1,4 @@
1
1
 
2
- > @knapsack/rendering-utils@4.92.4 lint /home/runner/work/app-monorepo/app-monorepo/libs/rendering-utils
2
+ > @knapsack/rendering-utils@4.92.8 lint /home/runner/work/app-monorepo/app-monorepo/libs/rendering-utils
3
3
  > eslint ./
4
4
 
@@ -1,19 +1,32 @@
1
1
 
2
- > @knapsack/rendering-utils@4.92.4 test /home/runner/work/app-monorepo/app-monorepo/libs/rendering-utils
2
+ > @knapsack/rendering-utils@4.92.8 test /home/runner/work/app-monorepo/app-monorepo/libs/rendering-utils
3
3
  > ava
4
4
 
5
5
 
6
- blocksToHtml - empty array (135ms)
7
- blocksToHtml - single divider-block (132ms)
8
- blocksToHtml - single text-editor block (131ms)
9
- blocksToHtml - single code-snippet block (108ms)
10
- blocksToHtml - single callout block (101ms)
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 (129ms)
18
+ ✔ blocksToHtml - single divider-block (128ms)
19
+ ✔ blocksToHtml - single text-editor block (128ms)
20
+ ✔ blocksToHtml - single code-snippet block (101ms)
21
+ ✔ blocksToHtml - single callout block
11
22
  ✔ blocksToHtml - single callout block with error type
12
23
  ✔ blocksToHtml - single image-block with single image
13
24
  ✔ blocksToHtml - single image-block with multiple images
14
25
  ✔ blocksToHtml - single image-block with no images
15
26
  ✔ blocksToHtml - single image-block with empty images array
16
27
  ✔ blocksToHtml - single video block
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
@@ -24,24 +37,24 @@
24
37
  ✔ blocksToHtml - single shortcut-tiles block with link but no name
25
38
  ✔ blocksToHtml - block with no data
26
39
  ✔ blocksToHtml - file extensions detection for images
27
- 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}`.
28
- 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}`.
29
40
  ✔ blocksToHtml - case insensitive file extension detection
30
41
  ✔ blocksToHtml - files with no extension
31
42
  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}`.
32
43
  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}`.
33
44
  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}`.
34
- ✔ blocksToHtml - unknown block type throws error
35
45
  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}`.
36
46
  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}`.
37
47
  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
48
  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
49
  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 (144ms)
41
- blocksToHtml - single markdown-block with array (143ms)
42
- ✔ blocksToHtml - single markdown-block with empty string (143ms)
43
- ✔ blocksToHtml - single markdown-block with undefined md (143ms)
44
- ✔ blocksToHtml - multiple different block types (130ms)
50
+ 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}`.
51
+ 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}`.
52
+ ✔ blocksToHtml - unknown block type throws error
53
+ ✔ blocksToHtml - single markdown-block with string (129ms)
54
+ ✔ blocksToHtml - single markdown-block with array (129ms)
55
+ ✔ blocksToHtml - single markdown-block with empty string (129ms)
56
+ ✔ blocksToHtml - single markdown-block with undefined md (128ms)
57
+ ✔ blocksToHtml - multiple different block types (112ms)
45
58
 
46
59
 
47
- 29 tests passed
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;AA8GnD,wBAAsB,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAMzE"}
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"}
@@ -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, '&lt;')
21
21
  .replace(/>/g, '&gt;');
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 convertTipTapJsonToHtml(b.data.content);
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 = convertTipTapJsonToHtml(b.data.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
- return `<video src="${escapeAttr(b.data.video.url)}" />`;
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":"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"}
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.9--canary.7562.fc3fcd2.0",
4
+ "version": "4.92.9--canary.7602.1bacad7.0",
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.9--canary.7562.fc3fcd2.0",
29
- "@knapsack/utils": "4.92.9--canary.7562.fc3fcd2.0",
28
+ "@knapsack/tiptap-utils": "4.92.9--canary.7602.1bacad7.0",
29
+ "@knapsack/utils": "4.92.9--canary.7602.1bacad7.0",
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.9--canary.7562.fc3fcd2.0",
35
- "@knapsack/prettier-config": "4.92.9--canary.7562.fc3fcd2.0",
36
- "@knapsack/test-ava": "4.92.9--canary.7562.fc3fcd2.0",
37
- "@knapsack/types": "4.92.9--canary.7562.fc3fcd2.0",
38
- "@knapsack/typescript-config-starter": "4.92.9--canary.7562.fc3fcd2.0",
34
+ "@knapsack/eslint-config-starter": "4.92.9--canary.7602.1bacad7.0",
35
+ "@knapsack/prettier-config": "4.92.9--canary.7602.1bacad7.0",
36
+ "@knapsack/test-ava": "4.92.9--canary.7602.1bacad7.0",
37
+ "@knapsack/types": "4.92.9--canary.7602.1bacad7.0",
38
+ "@knapsack/typescript-config-starter": "4.92.9--canary.7602.1bacad7.0",
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": "fc3fcd2515cdecd396f57d0cf2fe8822e8aef3be"
53
+ "gitHead": "1bacad752c5584b66bb606a076493c8c0177eb9c"
54
54
  }
@@ -5,7 +5,10 @@
5
5
  */
6
6
 
7
7
  import { type BlockConfig } from '@knapsack/types';
8
- import { convertTipTapJsonToHtml } from '@knapsack/tiptap-utils';
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, '&gt;');
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 convertTipTapJsonToHtml(b.data.content);
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 = convertTipTapJsonToHtml(b.data.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
- return `<video src="${escapeAttr(b.data.video.url)}" />`;
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) => {