mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 08:10:44 +00:00
lint: ban raw HTTP2 imports
This commit is contained in:
@@ -1420,12 +1420,18 @@
|
||||
"lint:plugins:no-monolithic-plugin-sdk-entry-imports": "node --import tsx scripts/check-no-monolithic-plugin-sdk-entry-imports.ts",
|
||||
"lint:plugins:no-register-http-handler": "node scripts/check-no-register-http-handler.mjs",
|
||||
"lint:plugins:plugin-sdk-subpaths-exported": "node scripts/check-plugin-sdk-subpath-exports.mjs",
|
||||
<<<<<<< HEAD
|
||||
"lint:scripts": "pnpm lint:docker-e2e && node scripts/run-oxlint.mjs --tsconfig config/tsconfig/oxlint.scripts.json scripts",
|
||||
"lint:swift": "swiftlint lint --config config/swiftlint.yml && (cd apps/ios && swiftlint lint --config .swiftlint.yml)",
|
||||
=======
|
||||
"lint:scripts": "pnpm lint:docker-e2e && pnpm lint:tmp:no-raw-http2-imports && node scripts/run-oxlint.mjs --tsconfig tsconfig.oxlint.scripts.json scripts",
|
||||
"lint:swift": "swiftlint lint --config .swiftlint.yml && (cd apps/ios && swiftlint lint --config .swiftlint.yml)",
|
||||
>>>>>>> 59b4c14509 (lint: ban raw HTTP2 imports)
|
||||
"lint:tmp:channel-agnostic-boundaries": "node scripts/check-channel-agnostic-boundaries.mjs",
|
||||
"lint:tmp:dynamic-import-warts": "node scripts/check-dynamic-import-warts.mjs",
|
||||
"lint:tmp:no-random-messaging": "node scripts/check-no-random-messaging-tmp.mjs",
|
||||
"lint:tmp:no-raw-channel-fetch": "node scripts/check-no-raw-channel-fetch.mjs",
|
||||
"lint:tmp:no-raw-http2-imports": "node scripts/check-no-raw-http2-imports.mjs",
|
||||
"lint:tmp:tsgo-core-boundary": "node scripts/check-tsgo-core-boundary.mjs",
|
||||
"lint:ui:no-raw-window-open": "node scripts/check-no-raw-window-open.mjs",
|
||||
"lint:web-fetch-provider-boundaries": "node scripts/check-web-fetch-provider-boundaries.mjs",
|
||||
|
||||
120
scripts/check-no-raw-http2-imports.mjs
Normal file
120
scripts/check-no-raw-http2-imports.mjs
Normal file
@@ -0,0 +1,120 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
const SOURCE_ROOTS = ["src", "extensions"];
|
||||
const DEFAULT_SKIPPED_DIR_NAMES = new Set(["node_modules", "dist", "coverage", ".generated"]);
|
||||
|
||||
function isCodeFile(filePath) {
|
||||
if (filePath.endsWith(".d.ts")) {
|
||||
return false;
|
||||
}
|
||||
return /\.(?:[cm]?ts|[cm]?js|tsx|jsx)$/u.test(filePath);
|
||||
}
|
||||
|
||||
function collectFilesSync(rootDir, options) {
|
||||
const skipDirNames = options.skipDirNames ?? DEFAULT_SKIPPED_DIR_NAMES;
|
||||
const files = [];
|
||||
const stack = [rootDir];
|
||||
|
||||
while (stack.length > 0) {
|
||||
const current = stack.pop();
|
||||
if (!current) {
|
||||
continue;
|
||||
}
|
||||
let entries = [];
|
||||
try {
|
||||
entries = fs.readdirSync(current, { withFileTypes: true });
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
for (const entry of entries) {
|
||||
const fullPath = path.join(current, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
if (!skipDirNames.has(entry.name)) {
|
||||
stack.push(fullPath);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (entry.isFile() && options.includeFile(fullPath)) {
|
||||
files.push(fullPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
function toPosixPath(filePath) {
|
||||
return filePath.replaceAll("\\", "/");
|
||||
}
|
||||
|
||||
const FORBIDDEN_HTTP2_MODULES = new Set(["node:http2", "http2"]);
|
||||
const ALLOWED_PRODUCTION_FILES = new Set(["src/infra/push-apns-http2.ts"]);
|
||||
|
||||
function isTestFile(relativePath) {
|
||||
return (
|
||||
/(?:^|\/)(?:test|test-fixtures)\//u.test(relativePath) ||
|
||||
/\.test\.[cm]?[jt]sx?$/u.test(relativePath)
|
||||
);
|
||||
}
|
||||
|
||||
function lineNumberForOffset(content, offset) {
|
||||
return content.slice(0, offset).split(/\r?\n/u).length;
|
||||
}
|
||||
|
||||
function collectHttp2ImportOffenders(filePath) {
|
||||
const relativePath = toPosixPath(path.relative(process.cwd(), filePath));
|
||||
if (ALLOWED_PRODUCTION_FILES.has(relativePath) || isTestFile(relativePath)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const content = fs.readFileSync(filePath, "utf8");
|
||||
const offenders = [];
|
||||
const patterns = [
|
||||
/\bimport\s+(?:type\s+)?[\s\S]*?\bfrom\s*["']([^"']+)["']/gu,
|
||||
/\bexport\s+(?:type\s+)?[\s\S]*?\bfrom\s*["']([^"']+)["']/gu,
|
||||
/\bimport\s*\(\s*["']([^"']+)["']\s*\)/gu,
|
||||
/\brequire\s*\(\s*["']([^"']+)["']\s*\)/gu,
|
||||
];
|
||||
|
||||
for (const pattern of patterns) {
|
||||
for (const match of content.matchAll(pattern)) {
|
||||
const specifier = match[1];
|
||||
if (specifier && FORBIDDEN_HTTP2_MODULES.has(specifier)) {
|
||||
offenders.push({
|
||||
file: relativePath,
|
||||
line: lineNumberForOffset(content, match.index ?? 0),
|
||||
specifier,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return offenders;
|
||||
}
|
||||
|
||||
function collectSourceFiles() {
|
||||
return SOURCE_ROOTS.flatMap((root) =>
|
||||
collectFilesSync(path.join(process.cwd(), root), {
|
||||
includeFile: isCodeFile,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
function main() {
|
||||
const offenders = collectSourceFiles().flatMap(collectHttp2ImportOffenders);
|
||||
if (offenders.length === 0) {
|
||||
console.log("OK: raw node:http2 imports stay behind the APNs proxy wrapper.");
|
||||
return;
|
||||
}
|
||||
|
||||
console.error("Raw node:http2 imports are only allowed in src/infra/push-apns-http2.ts.");
|
||||
for (const offender of offenders.toSorted(
|
||||
(a, b) => a.file.localeCompare(b.file) || a.line - b.line,
|
||||
)) {
|
||||
console.error(`- ${offender.file}:${offender.line} imports ${offender.specifier}`);
|
||||
}
|
||||
console.error("Use connectApnsHttp2Session() so APNs HTTP/2 honors managed proxy policy.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -1,6 +1,5 @@
|
||||
import { createHash, createPrivateKey, sign as signJwt } from "node:crypto";
|
||||
import fs from "node:fs/promises";
|
||||
import http2 from "node:http2";
|
||||
import path from "node:path";
|
||||
import { resolveStateDir } from "../config/paths.js";
|
||||
import {
|
||||
|
||||
Reference in New Issue
Block a user