Skip to content

Commit a1bf485

Browse files
authored
[Docs Site] Adopt eslint (#19263)
* [Docs Site] Adopt eslint * Demonstrate a fixable suggestion, add VSCode plugin and package.json script * Fix slice in ModelCatalog * Remove test error in AnchorHeading * recreate package-lock.json * update new .jsx components to .tsx * amend deps, fix react types, organise ec plugins * another attempt at fixing platform-specific deps * fix FieldCatalog filters, remove test block from code.mdx * use opacity instead of brightness for ruleid * fix lockfile * amend ruleid opacity styling * test onetrust * enable prefer const rule, remove onetrust test * add save-dev
1 parent 8adca6b commit a1bf485

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+15003
-11651
lines changed

.github/workflows/ci.yml

+6
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ jobs:
3030
- run: npm ci
3131
- run: npm run check
3232

33+
- uses: reviewdog/action-eslint@v1
34+
with:
35+
github_token: ${{ secrets.GITHUB_TOKEN }}
36+
reporter: github-pr-review
37+
fail_level: "error"
38+
3339
- run: npm run format:core:check
3440
## TODO: content formatting checks
3541
- run: npm run build

.npmrc

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
save-dev=true
2+
save-exact=true

.vscode/extensions.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"unifiedjs.vscode-mdx",
77
"bradlc.vscode-tailwindcss",
88
"redhat.vscode-yaml",
9-
"esbenp.prettier-vscode"
9+
"esbenp.prettier-vscode",
10+
"dbaeumer.vscode-eslint"
1011
]
1112
}

bin/validate-redirects.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ async function main() {
66
let numInfiniteRedirects = 0;
77
let numUrlsWithFragment = 0;
88
let numDuplicateRedirects = 0;
9-
let redirectSourceUrls: string[] = [];
9+
10+
const redirectSourceUrls: string[] = [];
1011

1112
for (const line of redirects.split("\n")) {
1213
if (line.startsWith("#") || line.trim() === "") continue;

ec.config.mjs

+6-151
Original file line numberDiff line numberDiff line change
@@ -2,162 +2,17 @@
22
import darkTheme from "solarflare-theme/themes/cloudflare-dark-color-theme.json" with { type: "json" };
33
import lightTheme from "solarflare-theme/themes/cloudflare-light-color-theme.json" with { type: "json" };
44

5-
import { definePlugin } from "@expressive-code/core";
6-
import { h } from "@expressive-code/core/hast";
5+
import pluginWorkersPlayground from "./plugins/expressive-code/workers-playground.js";
6+
import pluginOutputFrame from "./plugins/expressive-code/output-frame.js";
7+
import pluginDefaultTitles from "./plugins/expressive-code/default-titles.js";
78

89
import { pluginCollapsibleSections } from "@expressive-code/plugin-collapsible-sections";
910

10-
import lzstring from "lz-string";
11-
12-
/**
13-
* @param {string} code
14-
*/
15-
export function serialiseWorker(code) {
16-
const formData = new FormData();
17-
18-
const metadata = {
19-
main_module: "index.js",
20-
};
21-
22-
formData.set(
23-
"index.js",
24-
new Blob([code], {
25-
type: "application/javascript+module",
26-
}),
27-
"index.js",
28-
);
29-
30-
formData.set(
31-
"metadata",
32-
new Blob([JSON.stringify(metadata)], { type: "application/json" }),
33-
);
34-
35-
return formData;
36-
}
37-
38-
/**
39-
* @param {FormData} worker
40-
*/
41-
export async function compressWorker(worker) {
42-
const serialisedWorker = new Response(worker);
43-
return lzstring.compressToEncodedURIComponent(
44-
`${serialisedWorker.headers.get(
45-
"content-type",
46-
)}:${await serialisedWorker.text()}`,
47-
);
48-
}
49-
50-
function workersPlaygroundButton() {
51-
return definePlugin({
52-
name: "Adds 'Run Worker' button to JS codeblocks",
53-
baseStyles: `
54-
.run {
55-
display: flex;
56-
gap: 0.25rem;
57-
flex-direction: row;
58-
position: absolute;
59-
inset-block-start: calc(var(--ec-brdWd) + var(--button-spacing));
60-
inset-inline-end: calc(var(--ec-brdWd) + var(--ec-uiPadInl) * 3);
61-
direction: ltr;
62-
unicode-bidi: isolate;
63-
64-
text-decoration-color: var(--sl-color-accent);
65-
span {
66-
color: var(--sl-color-white);
67-
font-family: var(--sl-font-system);
68-
}
69-
}
70-
`,
71-
hooks: {
72-
postprocessRenderedBlock: async (context) => {
73-
if (!context.codeBlock.meta.includes("playground")) return;
74-
75-
const serialised = await compressWorker(
76-
serialiseWorker(context.codeBlock.code),
77-
);
78-
79-
const url = `https://workers.cloudflare.com/playground#${serialised}`;
80-
81-
const runButton = h("a.run", { href: url, target: "__blank" }, [
82-
h("span", "Run Worker in Playground"),
83-
]);
84-
85-
const ast = context.renderData.blockAst;
86-
ast.children.push(runButton);
87-
88-
context.renderData.blockAst = ast;
89-
},
90-
},
91-
});
92-
}
93-
94-
function outputCodeblocks() {
95-
return definePlugin({
96-
name: "Adds the '.code-output' class if 'output' is passed on the opening codefence.",
97-
hooks: {
98-
preprocessMetadata: async (context) => {
99-
if (!context.codeBlock.meta.includes("output")) return;
100-
context.codeBlock.props.frame = "none";
101-
},
102-
postprocessRenderedBlock: async (context) => {
103-
if (!context.codeBlock.meta.includes("output")) return;
104-
context.renderData.blockAst.properties.className ??= [];
105-
if (Array.isArray(context.renderData.blockAst.properties.className)) {
106-
context.renderData.blockAst.properties.className.push("code-output");
107-
}
108-
context.addStyles(`
109-
div.expressive-code:has(figure.code-output) {
110-
margin-top: 0 !important;
111-
}
112-
113-
.code-output .copy {
114-
display: none !important;
115-
}
116-
117-
.code-output > pre {
118-
border-top-width: 0 !important;
119-
background: var(--sl-color-gray-6) !important;
120-
}
121-
122-
.code-output > pre > code {
123-
user-select: none;
124-
transition: opacity 0.5s ease;
125-
}
126-
127-
.code-output > pre > code:hover {
128-
cursor: default;
129-
opacity: 0.5;
130-
}
131-
`);
132-
},
133-
},
134-
});
135-
}
136-
137-
function defaultLanguageTitles() {
138-
return definePlugin({
139-
name: "Adds language-specific default titles.",
140-
hooks: {
141-
preprocessLanguage: async (context) => {
142-
switch (context.codeBlock.language) {
143-
case "powershell": {
144-
context.codeBlock.props.title ??= "PowerShell";
145-
break;
146-
}
147-
default: {
148-
return;
149-
}
150-
}
151-
},
152-
},
153-
});
154-
}
155-
15611
export default {
15712
plugins: [
158-
workersPlaygroundButton(),
159-
outputCodeblocks(),
160-
defaultLanguageTitles(),
13+
pluginWorkersPlayground(),
14+
pluginOutputFrame(),
15+
pluginDefaultTitles(),
16116
pluginCollapsibleSections(),
16217
],
16318
themes: [darkTheme, lightTheme],

eslint.config.js

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import pluginJavaScript from "@eslint/js";
2+
import pluginTypeScript from "typescript-eslint";
3+
import pluginReact from "eslint-plugin-react";
4+
import pluginAstro from "eslint-plugin-astro";
5+
import pluginReactA11y from "eslint-plugin-jsx-a11y";
6+
7+
import globals from "globals";
8+
9+
/** @type {import('eslint').Linter.Config[]} */
10+
export default [
11+
{
12+
languageOptions: {
13+
globals: {
14+
...globals.node,
15+
},
16+
},
17+
},
18+
pluginJavaScript.configs.recommended,
19+
...pluginTypeScript.configs.recommended,
20+
...pluginAstro.configs.recommended,
21+
...pluginAstro.configs["jsx-a11y-recommended"],
22+
{
23+
files: ["**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}"],
24+
...pluginReact.configs.flat.recommended,
25+
...pluginReactA11y.flatConfigs.recommended,
26+
...pluginReact.configs.flat["jsx-runtime"],
27+
},
28+
{
29+
ignores: [".astro/", ".wrangler/", "dist/", ".github/"],
30+
},
31+
{
32+
rules: {
33+
"no-var": "error",
34+
"@typescript-eslint/no-explicit-any": "off",
35+
"@typescript-eslint/triple-slash-reference": "off",
36+
"@typescript-eslint/no-unused-vars": [
37+
"error",
38+
{ ignoreRestSiblings: true },
39+
],
40+
},
41+
},
42+
];

0 commit comments

Comments
 (0)