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) {