chore: use mcp sdk via playwright (#973)

This commit is contained in:
Pavel Feldman
2025-09-03 07:58:36 -07:00
committed by GitHub
parent 87741662f4
commit 8d86ce4958
34 changed files with 305 additions and 117 deletions

View File

@@ -21,8 +21,12 @@
import fs from 'fs';
import ts from 'typescript';
import path from 'path';
import Module from 'module';
const __dirname = path.dirname(new URL(import.meta.url).pathname);
const require = Module.createRequire(import.meta.url);
const builtins = new Set(Module.builtinModules);
const depsCache = {};
const packageRoot = path.resolve(__dirname, '..');
@@ -31,6 +35,13 @@ async function checkDeps() {
const deps = new Set();
const src = path.join(packageRoot, 'src');
let packageJSON;
try {
packageJSON = require(path.resolve(path.join(packageRoot, 'package.json')));
} catch {
}
const program = ts.createProgram({
options: {
allowJs: true,
@@ -53,6 +64,25 @@ async function checkDeps() {
process.exit(1);
}
if (packageJSON) {
for (const dep of deps) {
const resolved = require.resolve(dep, { paths: [packageRoot] });
if (dep === resolved || !resolved.includes('node_modules'))
deps.delete(dep);
}
for (const dep of Object.keys(packageJSON.dependencies || {}))
deps.delete(dep);
if (deps.size) {
console.log('Dependencies are not declared in package.json:');
for (const dep of deps)
console.log(` ${dep}`);
process.exit(1);
}
}
return packageJSON;
function visit(node, fileName, text) {
if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {
if (node.importClause) {
@@ -94,10 +124,21 @@ async function checkDeps() {
return;
}
let depName;
if (importName.startsWith('@'))
deps.add(importName.split('/').slice(0, 2).join('/'));
depName = importName.split('/').slice(0, 2).join('/');
else
deps.add(importName.split('/')[0]);
depName = importName.split('/')[0];
deps.add(depName);
try {
require.resolve(depName, { paths: [packageRoot] })
} catch (e) {
console.log(`Invalid dependency ${depName} in ${fileName}`);
process.exit(1);
}
if (!allowExternalImport(importName, packageJSON))
errors.push(`Disallowed external dependency ${importName} from ${path.relative(packageRoot, fileName)}`);
}
ts.forEachChild(node, x => visit(x, fileName, text));
}
@@ -154,6 +195,19 @@ async function checkDeps() {
}
return false;
}
function allowExternalImport(importName, packageJSON) {
// Only external imports are relevant. Files in src/web are bundled via webpack.
if (importName.startsWith('.') || (importName.startsWith('@') && !importName.startsWith('@playwright/')))
return true;
if (!packageJSON)
return false;
const match = importName.match(/(@[\w-]+\/)?([^/]+)/);
const dependency = match[1] ? match[1] + match[2] : match[2];
if (builtins.has(dependency))
return true;
return !!(packageJSON.dependencies || {})[dependency];
}
}
function listAllFiles(dir) {