diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 109c1b1eca6c690..244a0db9777e3d5 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -37,6 +37,8 @@ jobs:
NODE_OPTIONS: "--max-old-space-size=4192"
RUN_LINK_CHECK: true
+ - run: npm run check:worker
+
- uses: actions/cache/save@v4
with:
path: |
diff --git a/.prettierrc.mjs b/.prettierrc.mjs
index b30a95271408434..5f7898a6fb3152f 100644
--- a/.prettierrc.mjs
+++ b/.prettierrc.mjs
@@ -1,3 +1,4 @@
+// @ts-check
/** @type {import("prettier").Config} */
export default {
plugins: ["prettier-plugin-astro"],
diff --git a/ec.config.mjs b/ec.config.mjs
index 9d44068ce570ba3..aa3e98230c885ce 100644
--- a/ec.config.mjs
+++ b/ec.config.mjs
@@ -1,3 +1,4 @@
+// @ts-check
import darkTheme from "solarflare-theme/themes/cloudflare-dark-color-theme.json" with { type: "json" };
import lightTheme from "solarflare-theme/themes/cloudflare-light-color-theme.json" with { type: "json" };
@@ -6,6 +7,9 @@ import { h } from "@expressive-code/core/hast";
import lzstring from "lz-string";
+/**
+ * @param {string} code
+ */
export function serialiseWorker(code) {
const formData = new FormData();
@@ -29,6 +33,9 @@ export function serialiseWorker(code) {
return formData;
}
+/**
+ * @param {FormData} worker
+ */
export async function compressWorker(worker) {
const serialisedWorker = new Response(worker);
return lzstring.compressToEncodedURIComponent(
@@ -92,7 +99,10 @@ function outputCodeblocks() {
},
postprocessRenderedBlock: async (context) => {
if (!context.codeBlock.meta.includes("output")) return;
- context.renderData.blockAst.properties.className.push("code-output");
+ context.renderData.blockAst.properties.className ??= [];
+ if (Array.isArray(context.renderData.blockAst.properties.className)) {
+ context.renderData.blockAst.properties.className.push("code-output");
+ }
context.addStyles(`
div.expressive-code:has(figure.code-output) {
margin-top: 0 !important;
diff --git a/package-lock.json b/package-lock.json
index 46a1051405ec231..52cbda622a96095 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -23,6 +23,7 @@
"@codingheads/sticky-header": "^1.0.2",
"@stoplight/json-schema-tree": "^4.0.0",
"@types/dompurify": "^3.0.5",
+ "@types/hast": "^3.0.4",
"@types/he": "^1.2.3",
"@types/node": "^22.8.7",
"@types/react": "^18.3.12",
@@ -44,6 +45,7 @@
"instantsearch.js": "^4.75.4",
"lz-string": "^1.5.0",
"marked": "^14.1.3",
+ "mdast-util-mdx-expression": "^2.0.1",
"mermaid": "^11.4.0",
"node-html-parser": "^6.1.13",
"patch-package": "^8.0.0",
@@ -71,7 +73,7 @@
"typescript": "^5.6.3",
"unist-util-visit": "^5.0.0",
"vitest": "2.1.4",
- "wrangler": "^3.78.10",
+ "wrangler": "^3.84.1",
"yaml": "^2.6.0"
},
"engines": {
@@ -4407,6 +4409,7 @@
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
"integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/unist": "*"
}
@@ -10683,10 +10686,11 @@
}
},
"node_modules/mdast-util-mdx-expression": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz",
- "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz",
+ "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/estree-jsx": "^1.0.0",
"@types/hast": "^3.0.0",
diff --git a/package.json b/package.json
index a339492bb6f3790..299a12a3cdec525 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
"check": "npm run check:functions && npm run check:astro",
"check:astro": "npm run sync && astro check",
"check:functions": "npx tsc --noEmit -p ./functions/tsconfig.json",
+ "check:worker": "npx tsc --noEmit -p ./worker/tsconfig.json",
"dev": "npx astro dev",
"format": "npx prettier --write \"**/*.{js,jsx,ts,tsx,mjs,astro,css,json,yaml,yml}\"",
"postinstall": "npx patch-package && npm run sync",
@@ -35,6 +36,7 @@
"@codingheads/sticky-header": "^1.0.2",
"@stoplight/json-schema-tree": "^4.0.0",
"@types/dompurify": "^3.0.5",
+ "@types/hast": "^3.0.4",
"@types/he": "^1.2.3",
"@types/node": "^22.8.7",
"@types/react": "^18.3.12",
@@ -56,6 +58,7 @@
"instantsearch.js": "^4.75.4",
"lz-string": "^1.5.0",
"marked": "^14.1.3",
+ "mdast-util-mdx-expression": "^2.0.1",
"mermaid": "^11.4.0",
"node-html-parser": "^6.1.13",
"patch-package": "^8.0.0",
@@ -83,7 +86,7 @@
"typescript": "^5.6.3",
"unist-util-visit": "^5.0.0",
"vitest": "2.1.4",
- "wrangler": "^3.78.10",
+ "wrangler": "^3.84.1",
"yaml": "^2.6.0"
},
"engines": {
diff --git a/plugins/rehype/heading-slugs.ts b/plugins/rehype/heading-slugs.ts
index 42493dd7b643ec0..9989dd13c2689f3 100644
--- a/plugins/rehype/heading-slugs.ts
+++ b/plugins/rehype/heading-slugs.ts
@@ -1,32 +1,37 @@
import { toString } from "hast-util-to-string";
import { visit } from "unist-util-visit";
import GithubSlugger from "github-slugger";
+import type { Root } from "hast";
+import type { MdxTextExpression } from "mdast-util-mdx-expression";
const slugs = new GithubSlugger();
// # foo {/*bar*/} = foo
export default function () {
- return function (tree: any) {
+ return function (tree: Root) {
slugs.reset();
- visit(tree, "element", function (element: any) {
+ visit(tree, "element", function (element) {
if (/^h[1-6]$/.test(element.tagName)) {
const last = element.children.at(-1);
- if (
- last.type === "mdxTextExpression" &&
- last.value.startsWith("/*") &&
- last.value.endsWith("*/")
- ) {
- const id = last.value.slice(2, -2).trim();
- element.properties.id = slugs.slug(id);
+ // @ts-expect-error this is added by mdast-util-mdx-expression
+ if (last.type === "mdxTextExpression") {
+ const lastElement = last as MdxTextExpression;
+ if (
+ lastElement.value.startsWith("/*") &&
+ lastElement.value.endsWith("*/")
+ ) {
+ const id = lastElement.value.slice(2, -2).trim();
+ element.properties.id = slugs.slug(id);
- const text = element.children.at(-2);
- text.value = text.value.trimEnd();
- element.children.with(-2, text);
- } else {
- if (!element.properties.id) {
- element.properties.id = slugs.slug(toString(element));
+ const text = element.children.at(-2) as MdxTextExpression;
+ text.value = text.value.trimEnd();
+ element.children.with(-2, text);
+ } else {
+ if (!element.properties.id) {
+ element.properties.id = slugs.slug(toString(element));
+ }
}
}
}
diff --git a/tailwind.config.mjs b/tailwind.config.mjs
index a4c2d313c6eb384..2809a59c91e1c0c 100644
--- a/tailwind.config.mjs
+++ b/tailwind.config.mjs
@@ -1,3 +1,4 @@
+// @ts-check
import starlightPlugin from "@astrojs/starlight-tailwind";
const gray = {
diff --git a/worker/index.ts b/worker/index.ts
index 77ab6ebc494b913..fb56e111e8187e9 100644
--- a/worker/index.ts
+++ b/worker/index.ts
@@ -23,6 +23,7 @@ export default class extends WorkerEntrypoint {
}
try {
+ // @ts-expect-error Ignore Fetcher type mismatch
const redirect = await redirectsEvaluator(request, this.env.ASSETS);
if (redirect) {
return redirect;
@@ -38,6 +39,7 @@ export default class extends WorkerEntrypoint {
);
const redirect = await redirectsEvaluator(
new Request(forceTrailingSlashURL, request),
+ // @ts-expect-error Ignore Fetcher type mismatch
this.env.ASSETS,
);
if (redirect) {