From 95ebb862ca1f9493684c924a01f3aa62dc976980 Mon Sep 17 00:00:00 2001 From: Stephen Hukish Date: Wed, 23 Sep 2026 14:10:15 -0400 Subject: [PATCH 1/2] fix(themes): declare generated runtime dependencies --- .github/workflows/pr.yml | 3 +- package.json | 1 + .../_scripts/check-runtime-dependencies.cjs | 75 +++++++++++++++++++ themes/abcdef/package.json | 2 + themes/abyss/package.json | 2 + themes/androidstudio/package.json | 2 + themes/andromeda/package.json | 2 + themes/atomone/package.json | 2 + themes/aura/package.json | 2 + themes/basic/package.json | 2 + themes/bbedit/package.json | 2 + themes/bespin/package.json | 2 + themes/console/package.json | 1 + themes/copilot/package.json | 2 + themes/darcula/package.json | 2 + themes/dracula/package.json | 2 + themes/duotone/package.json | 2 + themes/eclipse/package.json | 2 + themes/github/package.json | 2 + themes/gruvbox/package.json | 2 + themes/kimbie/package.json | 2 + themes/material/package.json | 2 + themes/monokai-dimmed/package.json | 2 + themes/monokai/package.json | 2 + themes/noctis-lilac/package.json | 2 + themes/nord/package.json | 2 + themes/okaidia/package.json | 2 + themes/quietlight/package.json | 2 + themes/red/package.json | 2 + themes/solarized/package.json | 2 + themes/sublime/package.json | 2 + themes/tokyo-night-day/package.json | 2 + themes/tokyo-night-storm/package.json | 2 + themes/tokyo-night/package.json | 2 + themes/tomorrow-night-blue/package.json | 2 + themes/vscode/package.json | 2 + themes/white/package.json | 2 + themes/xcode/package.json | 2 + 38 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 themes/_scripts/check-runtime-dependencies.cjs diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 2f9ff9418..86fa1f60b 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -13,10 +13,11 @@ jobs: - run: npm install - run: npm run build + - run: npm run check:theme-dependencies - working-directory: core run: | npm run bundle npm run bundle:min - run: npm run coverage - - run: npm run doc \ No newline at end of file + - run: npm run doc diff --git a/package.json b/package.json index 9cad7389b..d9070dffc 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "⬆️⬆️⬆️⬆️⬆️ package ⬆️⬆️⬆️⬆️⬆️": "▲▲▲▲▲ package ▲▲▲▲▲", "test": "lerna exec \"tsbb test --no-watchman\" --scope @uiw/react-codemirror", "coverage": "lerna exec \"tsbb test --coverage --bail --no-watchman\" --scope @uiw/react-codemirror --scope @uiw/codemirror-extensions-langs", + "check:theme-dependencies": "node themes/_scripts/check-runtime-dependencies.cjs", "prepare": "husky", "version": "lerna version --exact --force-publish --no-push --no-git-tag-version", "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,json}'", diff --git a/themes/_scripts/check-runtime-dependencies.cjs b/themes/_scripts/check-runtime-dependencies.cjs new file mode 100644 index 000000000..b525b5159 --- /dev/null +++ b/themes/_scripts/check-runtime-dependencies.cjs @@ -0,0 +1,75 @@ +const fs = require('node:fs'); +const path = require('node:path'); + +const themesDir = path.resolve(__dirname, '..'); + +function packageName(specifier) { + if (specifier.startsWith('@')) { + return specifier.split('/').slice(0, 2).join('/'); + } + return specifier.split('/')[0]; +} + +function runtimeImports(source) { + const imports = new Set(); + const patterns = [ + /\bimport\s+(?:[^'";]+?\s+from\s+)?['"]([^'"]+)['"]/g, + /\bexport\s+[^'";]+?\s+from\s+['"]([^'"]+)['"]/g, + /\b(?:import|require)\s*\(\s*['"]([^'"]+)['"]\s*\)/g, + /\brequire\s*\(\s*['"]([^'"]+)['"]\s*\)/g, + ]; + + for (const pattern of patterns) { + for (const match of source.matchAll(pattern)) { + if (!match[1].startsWith('.') && !path.isAbsolute(match[1])) { + imports.add(match[1]); + } + } + } + return imports; +} + +function javascriptFiles(directory) { + if (!fs.existsSync(directory)) return []; + return fs.readdirSync(directory, { withFileTypes: true }).flatMap((entry) => { + const entryPath = path.join(directory, entry.name); + if (entry.isDirectory()) return javascriptFiles(entryPath); + return entry.isFile() && entry.name.endsWith('.js') ? [entryPath] : []; + }); +} + +const failures = []; +for (const entry of fs.readdirSync(themesDir, { withFileTypes: true })) { + if (!entry.isDirectory() || entry.name.startsWith('_')) continue; + + const packageDir = path.join(themesDir, entry.name); + const manifestPath = path.join(packageDir, 'package.json'); + const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')); + const declared = new Set([ + ...Object.keys(manifest.dependencies || {}), + ...Object.keys(manifest.optionalDependencies || {}), + ...Object.keys(manifest.peerDependencies || {}), + ]); + const outputFiles = [ + ...javascriptFiles(path.join(packageDir, 'esm')), + ...javascriptFiles(path.join(packageDir, 'cjs')), + ]; + + for (const file of outputFiles) { + const source = fs.readFileSync(file, 'utf8'); + for (const specifier of runtimeImports(source)) { + const dependency = packageName(specifier); + if (!declared.has(dependency)) { + failures.push(`${entry.name}: ${path.relative(packageDir, file)} imports ${specifier}`); + } + } + } +} + +if (failures.length > 0) { + console.error('Undeclared runtime dependencies found:'); + for (const failure of failures) console.error(`- ${failure}`); + process.exitCode = 1; +} else { + console.log('All built theme runtime imports are declared.'); +} diff --git a/themes/abcdef/package.json b/themes/abcdef/package.json index 42e83068c..a27cf1220 100644 --- a/themes/abcdef/package.json +++ b/themes/abcdef/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/abyss/package.json b/themes/abyss/package.json index 969f7eb8a..0c635380e 100644 --- a/themes/abyss/package.json +++ b/themes/abyss/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/androidstudio/package.json b/themes/androidstudio/package.json index 7fba074b8..46889dbdf 100644 --- a/themes/androidstudio/package.json +++ b/themes/androidstudio/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/andromeda/package.json b/themes/andromeda/package.json index c90868f09..a18471ae3 100644 --- a/themes/andromeda/package.json +++ b/themes/andromeda/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/atomone/package.json b/themes/atomone/package.json index d8b7d7d1a..04f4dd2f1 100644 --- a/themes/atomone/package.json +++ b/themes/atomone/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/aura/package.json b/themes/aura/package.json index 1ead1eed7..d338ec900 100644 --- a/themes/aura/package.json +++ b/themes/aura/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/basic/package.json b/themes/basic/package.json index 3aea2d177..1b3114194 100644 --- a/themes/basic/package.json +++ b/themes/basic/package.json @@ -43,6 +43,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/bbedit/package.json b/themes/bbedit/package.json index a3732c22d..1c9ef00c6 100644 --- a/themes/bbedit/package.json +++ b/themes/bbedit/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/bespin/package.json b/themes/bespin/package.json index be5fdc633..abd13144e 100644 --- a/themes/bespin/package.json +++ b/themes/bespin/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/console/package.json b/themes/console/package.json index 94b0713ef..88284319e 100644 --- a/themes/console/package.json +++ b/themes/console/package.json @@ -42,6 +42,7 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/copilot/package.json b/themes/copilot/package.json index ac87e94c3..ee48f5204 100644 --- a/themes/copilot/package.json +++ b/themes/copilot/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/darcula/package.json b/themes/darcula/package.json index 691bc7235..7238d65c8 100644 --- a/themes/darcula/package.json +++ b/themes/darcula/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/dracula/package.json b/themes/dracula/package.json index f66072810..40d6069b1 100644 --- a/themes/dracula/package.json +++ b/themes/dracula/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/duotone/package.json b/themes/duotone/package.json index efe199b1c..49d892d5b 100644 --- a/themes/duotone/package.json +++ b/themes/duotone/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/eclipse/package.json b/themes/eclipse/package.json index f51aa7c50..847fc3345 100644 --- a/themes/eclipse/package.json +++ b/themes/eclipse/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/github/package.json b/themes/github/package.json index 38ea9fff8..f30a4ef0d 100644 --- a/themes/github/package.json +++ b/themes/github/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/gruvbox/package.json b/themes/gruvbox/package.json index 798cb96ca..a2411e3e5 100644 --- a/themes/gruvbox/package.json +++ b/themes/gruvbox/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/kimbie/package.json b/themes/kimbie/package.json index 961db9b90..87f61a760 100644 --- a/themes/kimbie/package.json +++ b/themes/kimbie/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/material/package.json b/themes/material/package.json index 00ead3730..38efc0f20 100644 --- a/themes/material/package.json +++ b/themes/material/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/monokai-dimmed/package.json b/themes/monokai-dimmed/package.json index fa0198cb9..020df3fb4 100644 --- a/themes/monokai-dimmed/package.json +++ b/themes/monokai-dimmed/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/monokai/package.json b/themes/monokai/package.json index cf8c3d52e..33ee6f552 100644 --- a/themes/monokai/package.json +++ b/themes/monokai/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/noctis-lilac/package.json b/themes/noctis-lilac/package.json index 726fa1738..2e37d7f32 100644 --- a/themes/noctis-lilac/package.json +++ b/themes/noctis-lilac/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/nord/package.json b/themes/nord/package.json index 0bc6253c9..d72ce7330 100644 --- a/themes/nord/package.json +++ b/themes/nord/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/okaidia/package.json b/themes/okaidia/package.json index f04e4945d..54566a015 100644 --- a/themes/okaidia/package.json +++ b/themes/okaidia/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/quietlight/package.json b/themes/quietlight/package.json index 8bdeab316..3c8a01689 100644 --- a/themes/quietlight/package.json +++ b/themes/quietlight/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/red/package.json b/themes/red/package.json index 79bcb462a..c45a07a06 100644 --- a/themes/red/package.json +++ b/themes/red/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/solarized/package.json b/themes/solarized/package.json index a3493850e..4b0ab0d12 100644 --- a/themes/solarized/package.json +++ b/themes/solarized/package.json @@ -43,6 +43,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/sublime/package.json b/themes/sublime/package.json index c1089f721..ea104833c 100644 --- a/themes/sublime/package.json +++ b/themes/sublime/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/tokyo-night-day/package.json b/themes/tokyo-night-day/package.json index 032ff0ca0..4a586a245 100644 --- a/themes/tokyo-night-day/package.json +++ b/themes/tokyo-night-day/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/tokyo-night-storm/package.json b/themes/tokyo-night-storm/package.json index 9aaa57124..db18a4ccc 100644 --- a/themes/tokyo-night-storm/package.json +++ b/themes/tokyo-night-storm/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/tokyo-night/package.json b/themes/tokyo-night/package.json index 13b8490d1..ed408d4cd 100644 --- a/themes/tokyo-night/package.json +++ b/themes/tokyo-night/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/tomorrow-night-blue/package.json b/themes/tomorrow-night-blue/package.json index 08a628c35..44834abe9 100644 --- a/themes/tomorrow-night-blue/package.json +++ b/themes/tomorrow-night-blue/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/vscode/package.json b/themes/vscode/package.json index 549a8e0e3..9db34be86 100644 --- a/themes/vscode/package.json +++ b/themes/vscode/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/white/package.json b/themes/white/package.json index d0987a9a2..d2285a46c 100644 --- a/themes/white/package.json +++ b/themes/white/package.json @@ -41,6 +41,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ diff --git a/themes/xcode/package.json b/themes/xcode/package.json index 5c3a98705..96f0b722d 100644 --- a/themes/xcode/package.json +++ b/themes/xcode/package.json @@ -30,6 +30,8 @@ "cjs" ], "dependencies": { + "@babel/runtime": "^7.18.6", + "@lezer/highlight": "^1.0.0", "@uiw/codemirror-themes": "4.25.11" }, "keywords": [ From 9ec1859dc40645ca24dc130dce550b653cfa978f Mon Sep 17 00:00:00 2001 From: Stephen Phukish Date: Thu, 24 Sep 2026 11:03:41 -0400 Subject: [PATCH 2/2] fix(check-runtime-deps): remove redundant require() regex pattern --- themes/_scripts/check-runtime-dependencies.cjs | 1 - 1 file changed, 1 deletion(-) diff --git a/themes/_scripts/check-runtime-dependencies.cjs b/themes/_scripts/check-runtime-dependencies.cjs index b525b5159..92727f58a 100644 --- a/themes/_scripts/check-runtime-dependencies.cjs +++ b/themes/_scripts/check-runtime-dependencies.cjs @@ -16,7 +16,6 @@ function runtimeImports(source) { /\bimport\s+(?:[^'";]+?\s+from\s+)?['"]([^'"]+)['"]/g, /\bexport\s+[^'";]+?\s+from\s+['"]([^'"]+)['"]/g, /\b(?:import|require)\s*\(\s*['"]([^'"]+)['"]\s*\)/g, - /\brequire\s*\(\s*['"]([^'"]+)['"]\s*\)/g, ]; for (const pattern of patterns) {