From 7c4c785fe3ee6f48f354f895a31b32f6c25c650e Mon Sep 17 00:00:00 2001 From: Claas Augner Date: Tue, 30 Jun 2026 17:28:22 +0200 Subject: [PATCH 1/2] refactor(filecheck): remove `index.html` support We migrated all documents to `index.md` long ago, so only the adjacent `index.md` is considered when checking whether an attachment is referenced. Consolidate the test fixtures into a single `md` directory accordingly. --- scripts/filecheck/checker.js | 16 ++++------------ scripts/filecheck/checker.test.js | 15 ++++----------- scripts/filecheck/fixtures/html/index.html | 4 ---- scripts/filecheck/fixtures/html/orphan.png | Bin 592 -> 0 bytes .../fixtures/{html => md}/onhandler.svg | 0 .../filecheck/fixtures/{html => md}/png.jpeg | Bin .../filecheck/fixtures/{html => md}/script.svg | 0 .../filecheck/fixtures/{html => md}/zero.gif | 0 8 files changed, 8 insertions(+), 27 deletions(-) delete mode 100644 scripts/filecheck/fixtures/html/index.html delete mode 100644 scripts/filecheck/fixtures/html/orphan.png rename scripts/filecheck/fixtures/{html => md}/onhandler.svg (100%) rename scripts/filecheck/fixtures/{html => md}/png.jpeg (100%) rename scripts/filecheck/fixtures/{html => md}/script.svg (100%) rename scripts/filecheck/fixtures/{html => md}/zero.gif (100%) diff --git a/scripts/filecheck/checker.js b/scripts/filecheck/checker.js index c9b930bf854dc41..2df8703ea80a401 100644 --- a/scripts/filecheck/checker.js +++ b/scripts/filecheck/checker.js @@ -185,16 +185,10 @@ export async function checkFile(filePath, options = {}) { } } - // The image has to be mentioned in the adjacent index.html document + // The image has to be mentioned in the adjacent index.md document const parentPath = path.dirname(filePath); - const htmlFilePath = path.join(parentPath, "index.html"); - const mdFilePath = path.join(parentPath, "index.md"); - const docFilePath = (await fse.exists(htmlFilePath)) - ? htmlFilePath - : (await fse.exists(mdFilePath)) - ? mdFilePath - : null; - if (!docFilePath) { + const docFilePath = path.join(parentPath, "index.md"); + if (!(await fse.exists(docFilePath))) { throw new FixableError( `${getRelativePath( filePath, @@ -204,9 +198,7 @@ export async function checkFile(filePath, options = {}) { } // The image must be mentioned (as a string) in the content - const rawContent = docFilePath - ? await fs.readFile(docFilePath, "utf-8") - : null; + const rawContent = await fs.readFile(docFilePath, "utf-8"); if (!rawContent.includes(path.basename(filePath))) { throw new FixableError( `${getRelativePath( diff --git a/scripts/filecheck/checker.test.js b/scripts/filecheck/checker.test.js index a609a56e20a49c9..11657c285b1fd31 100644 --- a/scripts/filecheck/checker.test.js +++ b/scripts/filecheck/checker.test.js @@ -5,12 +5,11 @@ import { describe, it } from "node:test"; import { checkFile } from "./checker.js"; -const HTML_FIXTURES = new URL("fixtures/html/", import.meta.url); const MD_FIXTURES = new URL("fixtures/md/", import.meta.url); describe("checking files", () => { it("should spot SVGs with scripts inside them", async () => { - const filePath = fileURLToPath(new URL("./script.svg", HTML_FIXTURES)); + const filePath = fileURLToPath(new URL("./script.svg", MD_FIXTURES)); console.assert(fs.existsSync(filePath), `${filePath} does not exist`); await assert.rejects( () => checkFile(filePath), @@ -19,7 +18,7 @@ describe("checking files", () => { }); it("should spot SVGs with onLoad inside an element", async () => { - const filePath = fileURLToPath(new URL("./onhandler.svg", HTML_FIXTURES)); + const filePath = fileURLToPath(new URL("./onhandler.svg", MD_FIXTURES)); console.assert(fs.existsSync(filePath), `${filePath} does not exist`); await assert.rejects( () => checkFile(filePath), @@ -28,25 +27,19 @@ describe("checking files", () => { }); it("should spot files that are not mentioned in source", async () => { - const filePath = fileURLToPath(new URL("./orphan.png", HTML_FIXTURES)); - console.assert(fs.existsSync(filePath), `${filePath} does not exist`); - await assert.rejects(() => checkFile(filePath), /is not mentioned in/); - }); - - it("should spot files that are not mentioned in md source", async () => { const filePath = fileURLToPath(new URL("./orphan.png", MD_FIXTURES)); console.assert(fs.existsSync(filePath), `${filePath} does not exist`); await assert.rejects(() => checkFile(filePath), /is not mentioned in/); }); it("should spot files that are completely empty", async () => { - const filePath = fileURLToPath(new URL("./zero.gif", HTML_FIXTURES)); + const filePath = fileURLToPath(new URL("./zero.gif", MD_FIXTURES)); console.assert(fs.existsSync(filePath), `${filePath} does not exist`); await assert.rejects(() => checkFile(filePath), /is 0 bytes/); }); it("should spot mismatch between file-type and file extension", async () => { - const filePath = fileURLToPath(new URL("./png.jpeg", HTML_FIXTURES)); + const filePath = fileURLToPath(new URL("./png.jpeg", MD_FIXTURES)); console.assert(fs.existsSync(filePath), `${filePath} does not exist`); await assert.rejects( () => checkFile(filePath), diff --git a/scripts/filecheck/fixtures/html/index.html b/scripts/filecheck/fixtures/html/index.html deleted file mode 100644 index f6a05c2a18dca51..000000000000000 --- a/scripts/filecheck/fixtures/html/index.html +++ /dev/null @@ -1,4 +0,0 @@ -

Filecheck fixture

- - - diff --git a/scripts/filecheck/fixtures/html/orphan.png b/scripts/filecheck/fixtures/html/orphan.png deleted file mode 100644 index 791501245adad69de482b0346060771ccd008719..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 592 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L9kgfz_MvJW-LO=$4iKnkC`(rj~em?#{n~4*ELc2X(978nDC#U>4-ym*aXb`ZX zf%RaI&FufZ{kh-YYp+p1qNlBNu5bI_^IuQF z`#%tT{yJ~X=b*W`YD|7g$lqlWinOK`h^=$~r#@B_cR-(Fms{Nj^4{{c~hKjPK5 z%Q(``uKJslzgI8no|0(7F`~Uv`|6H=mWD`@{|1|S_ z`QJ6N{Xizq|JM5pKS^r#`7%7b{CKnD_AFtbH&jbpBT7;dOH!?pi&B9UgOP!urLKXQ zu910&p{bRjiIt(Lwtt)x7$D3zhS zyj(9cFS|H7u^?41zbJk7I~ysWqVTGah?1bha)pAT{ItxRRE3htf>edff|6tghKf0l zKk;xBhG}S=@;`mX^Jx$Rvog0{GPkg@u=ivUW?==F29v`n%*vZX6i(l`a^lFDBQi(W fPd9ih@X}*=B`#R<$;oso& Date: Tue, 30 Jun 2026 17:32:26 +0200 Subject: [PATCH 2/2] refactor(filecheck): replace `fs-extra` with `node:fs/promises` `node:fs/promises` covers everything we used `fs-extra` for: a small `pathExists` helper wraps `fs.access`, `fse.copyFileSync` becomes `fs.copyFile`, and `fse.removeSync` becomes `fs.rm` with `recursive` and `force`. Drop the `fs-extra` dependency. --- package-lock.json | 39 ------------------------------------ package.json | 1 - scripts/filecheck/checker.js | 20 ++++++++++++++---- 3 files changed, 16 insertions(+), 44 deletions(-) diff --git a/package-lock.json b/package-lock.json index ed7f361fda0b2a6..bb00d32d82905f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,6 @@ "env-cmd": "11.0.0", "fdir": "^6.5.0", "file-type": "^22.0.1", - "fs-extra": "^11.3.6", "gray-matter": "^4.0.3", "imagemin": "^9.0.1", "imagemin-gifsicle": "^7.0.0", @@ -4394,21 +4393,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fs-extra": { - "version": "11.3.6", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.6.tgz", - "integrity": "sha512-w8ZNZr2mKIc7qeNaQ9AVPT1+iFaI+Avd4xudVOvdDJ8VytREi1Ft5Ih7hd9jjehod8vAM5GMsfQ/TpPf4EyoEA==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -6013,19 +5997,6 @@ "dev": true, "license": "MIT" }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, "node_modules/jsonpointer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", @@ -9528,16 +9499,6 @@ "dev": true, "license": "ISC" }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/package.json b/package.json index 9a9c4bf09edce86..03b84765f98353a 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,6 @@ "env-cmd": "11.0.0", "fdir": "^6.5.0", "file-type": "^22.0.1", - "fs-extra": "^11.3.6", "gray-matter": "^4.0.3", "imagemin": "^9.0.1", "imagemin-gifsicle": "^7.0.0", diff --git a/scripts/filecheck/checker.js b/scripts/filecheck/checker.js index 2df8703ea80a401..3d22bcf52444621 100644 --- a/scripts/filecheck/checker.js +++ b/scripts/filecheck/checker.js @@ -5,7 +5,6 @@ import os from "node:os"; import { eachLimit } from "async"; import cliProgress from "cli-progress"; import { fdir } from "fdir"; -import fse from "fs-extra"; import { temporaryDirectory } from "tempy"; import * as cheerio from "cheerio"; import { fileTypeFromFile } from "file-type"; @@ -83,6 +82,19 @@ function getRelativePath(filePath) { return path.relative(process.cwd(), filePath); } +/** + * @param {string} filePath + * @returns {Promise} + */ +async function pathExists(filePath) { + try { + await fs.access(filePath); + return true; + } catch { + return false; + } +} + /** * Check a single file for naming, type, reference, and compression rules. * @param {string} filePath @@ -188,7 +200,7 @@ export async function checkFile(filePath, options = {}) { // The image has to be mentioned in the adjacent index.md document const parentPath = path.dirname(filePath); const docFilePath = path.join(parentPath, "index.md"); - if (!(await fse.exists(docFilePath))) { + if (!(await pathExists(docFilePath))) { throw new FixableError( `${getRelativePath( filePath, @@ -289,7 +301,7 @@ async function checkCompression(filePath, options) { 0, )}% smaller.`, ); - fse.copyFileSync(compressed.destinationPath, filePath); + await fs.copyFile(compressed.destinationPath, filePath); } else { throw new FixableError( `${filePath} is ${formatSize( @@ -302,7 +314,7 @@ async function checkCompression(filePath, options) { } } } finally { - fse.removeSync(tempdir); + await fs.rm(tempdir, { recursive: true, force: true }); } }