diff --git a/.changeset/eleven-rocks-leave.md b/.changeset/eleven-rocks-leave.md new file mode 100644 index 0000000000..a8fcbae1f0 --- /dev/null +++ b/.changeset/eleven-rocks-leave.md @@ -0,0 +1,5 @@ +--- +'mermaid': patch +--- + +fix: Kanban diagrams will not render when adding a number as ticket id or assigned for a task diff --git a/.changeset/fresh-bears-doubt.md b/.changeset/fresh-bears-doubt.md new file mode 100644 index 0000000000..911ef74c1d --- /dev/null +++ b/.changeset/fresh-bears-doubt.md @@ -0,0 +1,5 @@ +--- +'mermaid': patch +--- + +fix: Intersection calculations for tilted cylinder/DAS when using handdrawn look. Some random seeds could cause the calculations to break. diff --git a/.changeset/neat-rabbits-bake.md b/.changeset/neat-rabbits-bake.md new file mode 100644 index 0000000000..6c66cc0066 --- /dev/null +++ b/.changeset/neat-rabbits-bake.md @@ -0,0 +1,5 @@ +--- +'mermaid': patch +--- + +Bump dompurify to `^3.2.1`. This removes the need for `@types/dompurify`. diff --git a/.changeset/nervous-beans-listen.md b/.changeset/nervous-beans-listen.md new file mode 100644 index 0000000000..45d796ac06 --- /dev/null +++ b/.changeset/nervous-beans-listen.md @@ -0,0 +1,5 @@ +--- +'@mermaid-js/layout-elk': patch +--- + +fix: Elk rendering of Diamond shape intersections diff --git a/cypress/integration/rendering/flowchart-elk.spec.js b/cypress/integration/rendering/flowchart-elk.spec.js index b5caef9733..c3aba53ea4 100644 --- a/cypress/integration/rendering/flowchart-elk.spec.js +++ b/cypress/integration/rendering/flowchart-elk.spec.js @@ -1,6 +1,6 @@ import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts'; -describe.skip('Flowchart ELK', () => { +describe('Flowchart ELK', () => { it('1-elk: should render a simple flowchart', () => { imgSnapshotTest( `flowchart-elk TD @@ -857,6 +857,49 @@ flowchart LR D --> E A["A"] +`, + { flowchart: { titleTopMargin: 0 } } + ); + }); + it('6080: should handle diamond shape intersections', () => { + imgSnapshotTest( + `--- +config: + layout: elk +--- +flowchart LR + subgraph s1["Untitled subgraph"] + n1["Evaluate"] + n2["Option 1"] + n3["Option 2"] + n4["fa:fa-car Option 3"] + end + subgraph s2["Untitled subgraph"] + n5["Evaluate"] + n6["Option 1"] + n7["Option 2"] + n8["fa:fa-car Option 3"] + end + A["Start"] -- Some text --> B("Continue") + B --> C{"Evaluate"} + C -- One --> D["Option 1"] + C -- Two --> E["Option 2"] + C -- Three --> F["fa:fa-car Option 3"] + n1 -- One --> n2 + n1 -- Two --> n3 + n1 -- Three --> n4 + n5 -- One --> n6 + n5 -- Two --> n7 + n5 -- Three --> n8 + n1@{ shape: diam} + n2@{ shape: rect} + n3@{ shape: rect} + n4@{ shape: rect} + n5@{ shape: diam} + n6@{ shape: rect} + n7@{ shape: rect} + n8@{ shape: rect} + `, { flowchart: { titleTopMargin: 0 } } ); diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index 66fc0f2d31..7ec666c1a9 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -88,71 +88,200 @@ +
+---
+config:
+  layout: elk
+---
+flowchart LR
+ subgraph s1["Untitled subgraph"]
+        n1["Evaluate"]
+        n2["Option 1"]
+        n3["Option 2"]
+        n4["fa:fa-car Option 3"]
+  end
+    n1 -- One --> n2
+    n1 -- Two --> n3
+    n1 -- Three --> n4
+    n5
+    n1@{ shape: diam}
+    n2@{ shape: rect}
+    n3@{ shape: rect}
+    n4@{ shape: rect}
+    A["Start"] -- Some text --> B("Continue")
+    B --> C{"Evaluate"}
+    C -- One --> D["Option 1"]
+    C -- Two --> E["Option 2"]
+    C -- Three --> F["fa:fa-car Option 3"]
+
+
+    
+---
+config:
+  layout: elk
+---
+flowchart LR
+ subgraph s1["Untitled subgraph"]
+        n1["Evaluate"]
+        n2["Option 1"]
+        n3["Option 2"]
+        n4["fa:fa-car Option 3"]
+  end
+ subgraph s2["Untitled subgraph"]
+        n5["Evaluate"]
+        n6["Option 1"]
+        n7["Option 2"]
+        n8["fa:fa-car Option 3"]
+  end
+    A["Start"] -- Some text --> B("Continue")
+    B --> C{"Evaluate"}
+    C -- One --> D["Option 1"]
+    C -- Two --> E["Option 2"]
+    C -- Three --> F["fa:fa-car Option 3"]
+    n1 -- One --> n2
+    n1 -- Two --> n3
+    n1 -- Three --> n4
+    n5 -- One --> n6
+    n5 -- Two --> n7
+    n5 -- Three --> n8
+    n1@{ shape: diam}
+    n2@{ shape: rect}
+    n3@{ shape: rect}
+    n4@{ shape: rect}
+    n5@{ shape: diam}
+    n6@{ shape: rect}
+    n7@{ shape: rect}
+    n8@{ shape: rect}
+
+    
+
+---
+config:
+  layout: elk
+---
+flowchart LR
+ subgraph s1["Untitled subgraph"]
+        n1["Evaluate"]
+        n2["Option 1"]
+  end
+    n1 -- One --> n2
+
+
+
+
+    
+
+---
+config:
+  layout: elk
+---
+flowchart LR
+    A{A} --> B & C
+
+
+---
+config:
+  layout: elk
+---
+flowchart LR
+    n2@{ shape: rect}
+    n3@{ shape: rect}
+    n4@{ shape: rect}
+    A["Start"] -- Some text --> B("Continue")
+    B --> C{"Evaluate"}
+    C -- One --> D["Option 1"]
+    C -- Two --> E["Option 2"]
+    C -- Three --> F["fa:fa-car Option 3"]
+    %% C@{ shape: hexagon}
+
+
+    
+
+---
+config:
+  kanban:
+    ticketBaseUrl: 'https://github.com/your-repo/issues/#TICKET#'
+---
+kanban
+  Backlog
+    task1[📝 Define project requirements]@{ ticket: a101 }
+  To Do
+    task2[🔍 Research technologies]@{ ticket: a102 }
+  Review
+    task4[🔍 Code review for login feature]@{ ticket: a104 }
+  Done
+    task5[✅ Deploy initial version]@{ ticket: a105 }
+  In Progress
+    task3[💻 Develop login feature]@{ ticket: 103 }
+
+    
+
 flowchart LR
 nA[Default] --> A@{ icon: 'fa:bell', form: 'rounded' }
 
     
-
+    
 flowchart LR
 nA[Style] --> A@{ icon: 'fa:bell', form: 'rounded' }
 style A fill:#f9f,stroke:#333,stroke-width:4px
     
-
+    
 flowchart LR
 nA[Class] --> A@{ icon: 'fa:bell', form: 'rounded' }
 A:::AClass
 classDef AClass fill:#f9f,stroke:#333,stroke-width:4px
     
-
+    
 flowchart LR
   nA[Class] --> A@{ icon: 'logos:aws', form: 'rounded' }
 
     
-
+    
 flowchart LR
 nA[Default] --> A@{ icon: 'fa:bell', form: 'square' }
 
     
-
+    
 flowchart LR
 nA[Style] --> A@{ icon: 'fa:bell', form: 'square' }
 style A fill:#f9f,stroke:#333,stroke-width:4px
     
-
+    
 flowchart LR
 nA[Class] --> A@{ icon: 'fa:bell', form: 'square' }
 A:::AClass
 classDef AClass fill:#f9f,stroke:#333,stroke-width:4px
     
-
+    
 flowchart LR
   nA[Class] --> A@{ icon: 'logos:aws', form: 'square' }
 
     
-
+    
 flowchart LR
 nA[Default] --> A@{ icon: 'fa:bell', form: 'circle' }
 
     
-
+    
 flowchart LR
 nA[Style] --> A@{ icon: 'fa:bell', form: 'circle' }
 style A fill:#f9f,stroke:#333,stroke-width:4px
     
-
+    
 flowchart LR
 nA[Class] --> A@{ icon: 'fa:bell', form: 'circle' }
 A:::AClass
 classDef AClass fill:#f9f,stroke:#333,stroke-width:4px
     
-
+    
 flowchart LR
   nA[Class] --> A@{ icon: 'logos:aws', form: 'circle' }
   A:::AClass
   classDef AClass fill:#f9f,stroke:#333,stroke-width:4px
     
-
+    
 flowchart LR
   nA[Style] --> A@{ icon: 'logos:aws', form: 'circle' }
   style A fill:#f9f,stroke:#333,stroke-width:4px
diff --git a/docs/ecosystem/integrations-community.md b/docs/ecosystem/integrations-community.md
index 71b02cd931..b12e148a94 100644
--- a/docs/ecosystem/integrations-community.md
+++ b/docs/ecosystem/integrations-community.md
@@ -185,8 +185,6 @@ Communication tools and platforms
   - [=Diagram block](https://github.com/zag/podlite/tree/main/packages/podlite-diagrams)
 - [Standard Notes](https://standardnotes.com/)
   - [Mermaid Extension](https://github.com/nienow/sn-mermaid)
-- [Sublime Text 3](https://sublimetext.com)
-  - [Mermaid Package](https://packagecontrol.io/packages/Mermaid)
 - [VS Code](https://code.visualstudio.com/)
   - [Mermaid Editor](https://marketplace.visualstudio.com/items?itemName=tomoyukim.vscode-mermaid-editor)
   - [Mermaid Export](https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.mermaid-export)
diff --git a/packages/mermaid-layout-elk/src/render.ts b/packages/mermaid-layout-elk/src/render.ts
index 60cdff8d62..1216b5dc82 100644
--- a/packages/mermaid-layout-elk/src/render.ts
+++ b/packages/mermaid-layout-elk/src/render.ts
@@ -484,6 +484,8 @@ export const render = async (
     const r3 = a1 * q1.x + b1 * q1.y + c1;
     const r4 = a1 * q2.x + b1 * q2.y + c1;
 
+    const epsilon = 1e-6;
+
     // Check signs of r3 and r4. If both point 3 and point 4 lie on
     // same side of line 1, the line segments do not intersect.
     if (r3 !== 0 && r4 !== 0 && sameSign(r3, r4)) {
@@ -502,7 +504,7 @@ export const render = async (
     // Check signs of r1 and r2. If both point 1 and point 2 lie
     // on same side of second line segment, the line segments do
     // not intersect.
-    if (r1 !== 0 && r2 !== 0 && sameSign(r1, r2)) {
+    if (Math.abs(r1) < epsilon && Math.abs(r2) < epsilon && sameSign(r1, r2)) {
       return /*DON'T_INTERSECT*/;
     }
 
@@ -547,11 +549,11 @@ export const render = async (
       { x: x1 - w / 2, y: y1 },
     ];
     log.debug(
-      `UIO diamondIntersection calc abc89:
+      `APA16 diamondIntersection calc abc89:
   outsidePoint: ${JSON.stringify(outsidePoint)}
   insidePoint : ${JSON.stringify(insidePoint)}
-  node        : x:${bounds.x} y:${bounds.y} w:${bounds.width} h:${bounds.height}`,
-      polyPoints
+  node-bounds       : x:${bounds.x} y:${bounds.y} w:${bounds.width} h:${bounds.height}`,
+      JSON.stringify(polyPoints)
     );
 
     const intersections = [];
@@ -564,8 +566,8 @@ export const render = async (
       minY = Math.min(minY, entry.y);
     });
 
-    // const left = x1 - w / 2;
-    // const top = y1 + h / 2;
+    const left = x1 - w / 2 - minX;
+    const top = y1 - h / 2 - minY;
 
     for (let i = 0; i < polyPoints.length; i++) {
       const p1 = polyPoints[i];
@@ -573,8 +575,8 @@ export const render = async (
       const intersect = intersectLine(
         bounds,
         outsidePoint,
-        { x: p1.x, y: p1.y },
-        { x: p2.x, y: p2.y }
+        { x: left + p1.x, y: top + p1.y },
+        { x: left + p2.x, y: top + p2.y }
       );
 
       if (intersect) {
@@ -753,7 +755,6 @@ export const render = async (
         }
       }
     });
-    log.debug('returning points', points);
     return points;
   };
 
@@ -968,17 +969,17 @@ export const render = async (
             startNode.innerHTML
           );
         }
-        if (startNode.shape === 'diamond') {
+        if (startNode.shape === 'diamond' || startNode.shape === 'diam') {
           edge.points.unshift({
             x: startNode.x + startNode.width / 2 + offset.x,
             y: startNode.y + startNode.height / 2 + offset.y,
           });
         }
-        if (endNode.shape === 'diamond') {
+        if (endNode.shape === 'diamond' || endNode.shape === 'diam') {
           const x = endNode.x + endNode.width / 2 + offset.x;
           // Add a point at the center of the diamond
           if (
-            Math.abs(edge.points[edge.points.length - 1].y - endNode.y - offset.y) > 0.001 ||
+            Math.abs(edge.points[edge.points.length - 1].y - endNode.y - offset.y) > 0.01 ||
             Math.abs(edge.points[edge.points.length - 1].x - x) > 0.001
           ) {
             edge.points.push({
@@ -997,7 +998,7 @@ export const render = async (
             height: startNode.height,
             padding: startNode.padding,
           },
-          startNode.shape === 'diamond'
+          startNode.shape === 'diamond' || startNode.shape === 'diam'
         ).reverse();
 
         edge.points = cutPathAtIntersect(
@@ -1009,7 +1010,7 @@ export const render = async (
             height: endNode.height,
             padding: endNode.padding,
           },
-          endNode.shape === 'diamond'
+          endNode.shape === 'diamond' || endNode.shape === 'diam'
         );
 
         const paths = insertEdge(
diff --git a/packages/mermaid/package.json b/packages/mermaid/package.json
index 78bf583881..4300ca14bd 100644
--- a/packages/mermaid/package.json
+++ b/packages/mermaid/package.json
@@ -71,7 +71,6 @@
     "@iconify/utils": "^2.1.32",
     "@mermaid-js/parser": "workspace:^",
     "@types/d3": "^7.4.3",
-    "@types/dompurify": "^3.0.5",
     "cytoscape": "^3.29.2",
     "cytoscape-cose-bilkent": "^4.1.0",
     "cytoscape-fcose": "^2.2.0",
@@ -79,7 +78,7 @@
     "d3-sankey": "^0.12.3",
     "dagre-d3-es": "7.0.11",
     "dayjs": "^1.11.10",
-    "dompurify": "^3.0.11 <3.1.7",
+    "dompurify": "^3.2.1",
     "katex": "^0.16.9",
     "khroma": "^2.1.0",
     "lodash-es": "^4.17.21",
diff --git a/packages/mermaid/src/diagrams/common/common.ts b/packages/mermaid/src/diagrams/common/common.ts
index e24c8e85c8..fd76d0a45d 100644
--- a/packages/mermaid/src/diagrams/common/common.ts
+++ b/packages/mermaid/src/diagrams/common/common.ts
@@ -32,14 +32,14 @@ const setupDompurifyHooksIfNotSetup = (() => {
 function setupDompurifyHooks() {
   const TEMPORARY_ATTRIBUTE = 'data-temp-href-target';
 
-  DOMPurify.addHook('beforeSanitizeAttributes', (node: Element) => {
-    if (node.tagName === 'A' && node.hasAttribute('target')) {
+  DOMPurify.addHook('beforeSanitizeAttributes', (node) => {
+    if (node instanceof Element && node.tagName === 'A' && node.hasAttribute('target')) {
       node.setAttribute(TEMPORARY_ATTRIBUTE, node.getAttribute('target') ?? '');
     }
   });
 
-  DOMPurify.addHook('afterSanitizeAttributes', (node: Element) => {
-    if (node.tagName === 'A' && node.hasAttribute(TEMPORARY_ATTRIBUTE)) {
+  DOMPurify.addHook('afterSanitizeAttributes', (node) => {
+    if (node instanceof Element && node.tagName === 'A' && node.hasAttribute(TEMPORARY_ATTRIBUTE)) {
       node.setAttribute('target', node.getAttribute(TEMPORARY_ATTRIBUTE) ?? '');
       node.removeAttribute(TEMPORARY_ATTRIBUTE);
       if (node.getAttribute('target') === '_blank') {
@@ -83,7 +83,6 @@ export const sanitizeText = (text: string, config: MermaidConfig): string => {
     return text;
   }
   if (config.dompurifyConfig) {
-    // eslint-disable-next-line @typescript-eslint/no-base-to-string
     text = DOMPurify.sanitize(sanitizeMore(text, config), config.dompurifyConfig).toString();
   } else {
     text = DOMPurify.sanitize(sanitizeMore(text, config), {
diff --git a/packages/mermaid/src/diagrams/kanban/kanbanDb.ts b/packages/mermaid/src/diagrams/kanban/kanbanDb.ts
index 478c378038..a9bcbb7b81 100644
--- a/packages/mermaid/src/diagrams/kanban/kanbanDb.ts
+++ b/packages/mermaid/src/diagrams/kanban/kanbanDb.ts
@@ -138,13 +138,13 @@ const addNode = (level: number, id: string, descr: string, type: number, shapeDa
       node.label = doc?.label;
     }
     if (doc?.icon) {
-      node.icon = doc?.icon;
+      node.icon = doc?.icon.toString();
     }
     if (doc?.assigned) {
-      node.assigned = doc?.assigned;
+      node.assigned = doc?.assigned.toString();
     }
     if (doc?.ticket) {
-      node.ticket = doc?.ticket;
+      node.ticket = doc?.ticket.toString();
     }
 
     if (doc?.priority) {
diff --git a/packages/mermaid/src/docs/ecosystem/integrations-community.md b/packages/mermaid/src/docs/ecosystem/integrations-community.md
index 974cccc127..6cff12aac2 100644
--- a/packages/mermaid/src/docs/ecosystem/integrations-community.md
+++ b/packages/mermaid/src/docs/ecosystem/integrations-community.md
@@ -180,8 +180,6 @@ Communication tools and platforms
   - [=Diagram block](https://github.com/zag/podlite/tree/main/packages/podlite-diagrams)
 - [Standard Notes](https://standardnotes.com/)
   - [Mermaid Extension](https://github.com/nienow/sn-mermaid)
-- [Sublime Text 3](https://sublimetext.com)
-  - [Mermaid Package](https://packagecontrol.io/packages/Mermaid)
 - [VS Code](https://code.visualstudio.com/)
   - [Mermaid Editor](https://marketplace.visualstudio.com/items?itemName=tomoyukim.vscode-mermaid-editor)
   - [Mermaid Export](https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.mermaid-export)
diff --git a/packages/mermaid/src/mermaidAPI.ts b/packages/mermaid/src/mermaidAPI.ts
index c44161a520..910ecb5e88 100644
--- a/packages/mermaid/src/mermaidAPI.ts
+++ b/packages/mermaid/src/mermaidAPI.ts
@@ -455,6 +455,7 @@ const render = async function (
     svgCode = DOMPurify.sanitize(svgCode, {
       ADD_TAGS: DOMPURIFY_TAGS,
       ADD_ATTR: DOMPURIFY_ATTR,
+      HTML_INTEGRATION_POINTS: { foreignobject: true },
     });
   }
 
diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/tiltedCylinder.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/tiltedCylinder.ts
index f8a2fb52b2..29f2c267f5 100644
--- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/tiltedCylinder.ts
+++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/tiltedCylinder.ts
@@ -125,7 +125,7 @@ export async function tiltedCylinder(
     ) {
       let x = rx * rx * (1 - (y * y) / (ry * ry));
       if (x != 0) {
-        x = Math.sqrt(x);
+        x = Math.sqrt(Math.abs(x));
       }
       x = rx - x;
       if (point.x - (node.x ?? 0) > 0) {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0a9bc7d758..7f3f4fa5f9 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -226,9 +226,6 @@ importers:
       '@types/d3':
         specifier: ^7.4.3
         version: 7.4.3
-      '@types/dompurify':
-        specifier: ^3.0.5
-        version: 3.0.5
       cytoscape:
         specifier: ^3.29.2
         version: 3.30.2
@@ -251,8 +248,8 @@ importers:
         specifier: ^1.11.10
         version: 1.11.13
       dompurify:
-        specifier: ^3.0.11 <3.1.7
-        version: 3.1.6
+        specifier: ^3.2.1
+        version: 3.2.1
       katex:
         specifier: ^0.16.9
         version: 0.16.11
@@ -2768,9 +2765,6 @@ packages:
   '@types/debug@4.1.12':
     resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
 
-  '@types/dompurify@3.0.5':
-    resolution: {integrity: sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==}
-
   '@types/estree@0.0.39':
     resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==}
 
@@ -4720,8 +4714,8 @@ packages:
     resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
     engines: {node: '>= 4'}
 
-  dompurify@3.1.6:
-    resolution: {integrity: sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==}
+  dompurify@3.2.1:
+    resolution: {integrity: sha512-NBHEsc0/kzRYQd+AY6HR6B/IgsqzBABrqJbpCDQII/OK6h7B7LXzweZTDsqSW2LkTRpoxf18YUP+YjGySk6B3w==}
 
   domutils@3.1.0:
     resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==}
@@ -12125,10 +12119,6 @@ snapshots:
     dependencies:
       '@types/ms': 0.7.34
 
-  '@types/dompurify@3.0.5':
-    dependencies:
-      '@types/trusted-types': 2.0.7
-
   '@types/estree@0.0.39': {}
 
   '@types/estree@1.0.6': {}
@@ -12970,7 +12960,7 @@ snapshots:
       antlr4: 4.11.0
       color-string: 1.9.1
       dom-to-image-more: 2.16.0
-      dompurify: 3.1.6
+      dompurify: 3.2.1
       file-saver: 2.0.5
       highlight.js: 10.7.3
       html-to-image: 1.11.11
@@ -14509,7 +14499,9 @@ snapshots:
     dependencies:
       domelementtype: 2.3.0
 
-  dompurify@3.1.6: {}
+  dompurify@3.2.1:
+    optionalDependencies:
+      '@types/trusted-types': 2.0.7
 
   domutils@3.1.0:
     dependencies:
diff --git a/scripts/tsc-check.ts b/scripts/tsc-check.ts
index 7a5ff50a9b..2e5b3016d1 100644
--- a/scripts/tsc-check.ts
+++ b/scripts/tsc-check.ts
@@ -38,7 +38,6 @@ const SRC = {
           // to match the real `package.json` values
           'type-fest': '*',
           '@types/d3': '^7.4.3',
-          '@types/dompurify': '^3.0.5',
           typescript: '*',
         },
       },