diff --git a/changelog.d/fixes/7661-fumadocs-devdep.md b/changelog.d/fixes/7661-fumadocs-devdep.md new file mode 100644 index 0000000000..7340d36184 --- /dev/null +++ b/changelog.d/fixes/7661-fumadocs-devdep.md @@ -0,0 +1 @@ +- fix(packaging): move fumadocs-mdx from dependencies to devDependencies to avoid pulling its build-only yuku-analyzer/yuku-ast toolchain into `npm install -g omniroute` (#7661) diff --git a/package-lock.json b/package-lock.json index d5eb7bd8fd..c5b8978f8a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,7 +36,6 @@ "fetch-socks": "^1.3.3", "fflate": "^0.8.3", "fumadocs-core": "^16.10.5", - "fumadocs-mdx": "^15.0.7", "fumadocs-ui": "^16.10.5", "http-proxy-middleware": "^4.0.0", "https-proxy-agent": "^9.0.0", @@ -104,7 +103,7 @@ "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", "@types/better-sqlite3": "^7.6.13", - "@types/bun": "*", + "@types/bun": "latest", "@types/node": "^26.1.0", "@types/react": "^19.2.15", "@types/react-dom": "^19.2.3", @@ -121,6 +120,7 @@ "eslint-config-next": "16.2.10", "eslint-plugin-sonarjs": "^4.1.0", "fast-check": "^4.8.0", + "fumadocs-mdx": "^15.0.7", "glob": "^13.0.6", "httpyac": "^6.16.7", "husky": "^9.1.7", @@ -4976,6 +4976,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.1.tgz", "integrity": "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -12844,6 +12845,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -12856,6 +12858,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -12868,6 +12871,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "freebsd" @@ -12880,6 +12884,7 @@ "cpu": [ "arm" ], + "dev": true, "libc": [ "glibc" ], @@ -12895,6 +12900,7 @@ "cpu": [ "arm" ], + "dev": true, "libc": [ "musl" ], @@ -12910,6 +12916,7 @@ "cpu": [ "arm64" ], + "dev": true, "libc": [ "glibc" ], @@ -12925,6 +12932,7 @@ "cpu": [ "arm64" ], + "dev": true, "libc": [ "musl" ], @@ -12940,6 +12948,7 @@ "cpu": [ "x64" ], + "dev": true, "libc": [ "glibc" ], @@ -12955,6 +12964,7 @@ "cpu": [ "x64" ], + "dev": true, "libc": [ "musl" ], @@ -12970,6 +12980,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -12982,6 +12993,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -12991,6 +13003,7 @@ "version": "0.5.43", "resolved": "https://registry.npmjs.org/@yuku-toolchain/types/-/types-0.5.43.tgz", "integrity": "sha512-kSpvPntnXw5+lYjO71ffBEnQ5ycQ74KGIYknh0TS4xeyCuBkOqxyJumxZkMhLBBUCLjDAbx2+Icnr3Zh4ftjpQ==", + "dev": true, "license": "MIT" }, "node_modules/a-sync-waterfall": { @@ -13052,6 +13065,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" @@ -13593,6 +13607,7 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "dev": true, "license": "MIT", "bin": { "astring": "bin/astring" @@ -14679,6 +14694,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "dev": true, "license": "MIT", "dependencies": { "readdirp": "^5.0.0" @@ -15327,6 +15343,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -17860,6 +17877,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", "integrity": "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -17876,6 +17894,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz", "integrity": "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==", + "dev": true, "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -18616,6 +18635,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -18642,6 +18662,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/estree-util-scope/-/estree-util-scope-1.0.0.tgz", "integrity": "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -18656,6 +18677,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "dev": true, "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -18683,6 +18705,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "dev": true, "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -18697,6 +18720,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" @@ -19699,6 +19723,7 @@ "version": "15.2.0", "resolved": "https://registry.npmjs.org/fumadocs-mdx/-/fumadocs-mdx-15.2.0.tgz", "integrity": "sha512-+yBP8QYw5wA9LF5eVdMhwbP7KT1OF4B/YfC6PZoD2jz0amZi1B+6QHTI6XoRRSTmhWrI4cL5LU1DspW0itk+NA==", + "dev": true, "license": "MIT", "dependencies": { "@mdx-js/mdx": "^3.1.1", @@ -25691,6 +25716,7 @@ "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" @@ -25753,6 +25779,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=16" @@ -26491,6 +26518,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz", "integrity": "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -26517,6 +26545,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz", "integrity": "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -26539,6 +26568,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "dev": true, "license": "MIT", "dependencies": { "micromark-util-types": "^2.0.0" @@ -26552,6 +26582,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "dev": true, "license": "MIT", "dependencies": { "acorn": "^8.0.0", @@ -26572,6 +26603,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "dev": true, "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -26636,6 +26668,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz", "integrity": "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -26864,6 +26897,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz", "integrity": "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -32158,6 +32192,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "dev": true, "license": "MIT", "engines": { "node": ">= 20.19.0" @@ -32210,6 +32245,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", "integrity": "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==", + "dev": true, "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -32225,6 +32261,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.1.tgz", "integrity": "sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==", + "dev": true, "license": "MIT", "dependencies": { "acorn-jsx": "^5.0.0", @@ -32245,6 +32282,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/recma-parse/-/recma-parse-1.0.0.tgz", "integrity": "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -32261,6 +32299,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/recma-stringify/-/recma-stringify-1.0.0.tgz", "integrity": "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==", + "dev": true, "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -32504,6 +32543,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz", "integrity": "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==", + "dev": true, "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -32553,6 +32593,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.1.tgz", "integrity": "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==", + "dev": true, "license": "MIT", "dependencies": { "mdast-util-mdx": "^3.0.0", @@ -33961,6 +34002,7 @@ "version": "0.7.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">= 12" @@ -35941,6 +35983,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" @@ -35954,6 +35997,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -37527,6 +37571,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/yuku-analyzer/-/yuku-analyzer-0.6.3.tgz", "integrity": "sha512-RQ02dPtOa5d2AA3Np45EWD3EJUwZDruCrMMulPwUT/9GK1P7aKAhjaxG4Jv/1qqzMUIt0RUe3Dn2RR6d7+qTrA==", + "dev": true, "license": "MIT", "dependencies": { "@yuku-toolchain/types": "0.5.43" diff --git a/package.json b/package.json index 0fbeaf37a6..28e75a4077 100644 --- a/package.json +++ b/package.json @@ -254,7 +254,6 @@ "fetch-socks": "^1.3.3", "fflate": "^0.8.3", "fumadocs-core": "^16.10.5", - "fumadocs-mdx": "^15.0.7", "fumadocs-ui": "^16.10.5", "http-proxy-middleware": "^4.0.0", "https-proxy-agent": "^9.0.0", @@ -345,6 +344,7 @@ "eslint-config-next": "16.2.10", "eslint-plugin-sonarjs": "^4.1.0", "fast-check": "^4.8.0", + "fumadocs-mdx": "^15.0.7", "glob": "^13.0.6", "httpyac": "^6.16.7", "husky": "^9.1.7", diff --git a/tests/unit/npm-runtime-deps-fumadocs-mdx-7661.test.ts b/tests/unit/npm-runtime-deps-fumadocs-mdx-7661.test.ts new file mode 100644 index 0000000000..ae74b161ac --- /dev/null +++ b/tests/unit/npm-runtime-deps-fumadocs-mdx-7661.test.ts @@ -0,0 +1,59 @@ +import { test } from "node:test"; +import assert from "node:assert/strict"; +import { readFileSync, readdirSync, statSync } from "node:fs"; +import { join, resolve, extname } from "node:path"; +import { fileURLToPath } from "node:url"; + +const REPO_ROOT = resolve(fileURLToPath(import.meta.url), "../../../"); + +function listSourceFiles(dir: string, exts: string[]): string[] { + const out: string[] = []; + let entries: string[]; + try { + entries = readdirSync(dir); + } catch { + return out; + } + for (const entry of entries) { + if (entry === "node_modules" || entry === ".git" || entry === ".source") continue; + const full = join(dir, entry); + const st = statSync(full); + if (st.isDirectory()) out.push(...listSourceFiles(full, exts)); + else if (exts.includes(extname(entry))) out.push(full); + } + return out; +} + +test("#7661 — fumadocs-mdx must not be a runtime dependency (npm install -g ETARGET exposure)", () => { + const pkg = JSON.parse(readFileSync(join(REPO_ROOT, "package.json"), "utf8")); + const deps: Record = pkg.dependencies || {}; + const devDeps: Record = pkg.devDependencies || {}; + + assert.ok( + !("fumadocs-mdx" in deps), + 'fumadocs-mdx is declared under "dependencies" — npm install -g omniroute fetches it ' + + "and its transitive yuku-analyzer/yuku-ast native-binding tree even though nothing at " + + 'runtime imports it. Move it to "devDependencies".' + ); + + assert.ok( + "fumadocs-mdx" in devDeps || "fumadocs-mdx" in deps, + "fumadocs-mdx must remain declared somewhere" + ); + + const runtimeDirs = ["src", "open-sse", "bin"].map((d) => join(REPO_ROOT, d)); + const runtimeFiles = runtimeDirs.flatMap((d) => + listSourceFiles(d, [".ts", ".tsx", ".js", ".mjs", ".cjs"]) + ); + assert.ok(runtimeFiles.length > 100, "sanity: scanner should find the runtime source tree"); + + const offenders = runtimeFiles.filter((f) => { + const src = readFileSync(f, "utf8"); + return /from\s+["']fumadocs-mdx(\/|["'])|require\(\s*["']fumadocs-mdx(\/|["'])/.test(src); + }); + assert.deepEqual( + offenders, + [], + `fumadocs-mdx is imported at runtime by: ${offenders.join(", ")}` + ); +});