monaco-auto-typings
Version:
provides automatic dependency type completion for Monaco Editor
84 lines (83 loc) • 3.6 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getDependenciesFromImports = getDependenciesFromImports;
exports.getImportsFromSourceCode = getImportsFromSourceCode;
const is_builtin_module_1 = __importDefault(require("is-builtin-module"));
const typescript_1 = __importDefault(require("typescript"));
// 匹配本地导入路径的正则表达式(如./或/开头的路径)
const LOCAL_IMPORT_REG = /^[\\/|\\.]/;
// 匹配依赖项名称的正则表达式,解析格式如:registry:@scope/name@version
const DEPENDENCY_REG = /^(?:(\w+):)?(?:(@\w+\/)?)([\w\-\.\/]+)(?:@([\w\-\.]+))?$/;
/**
* 从导入语句中提取依赖项信息
* @param imports 导入语句数组
* @returns 提取的依赖项数组
*/
function getDependenciesFromImports(imports) {
const dependencies = [];
for (const imp of imports) {
// 跳过内置模块和本地导入
if ((0, is_builtin_module_1.default)(imp) || LOCAL_IMPORT_REG.test(imp)) {
continue;
}
// 解析导入语句,提取registry、scope、name和version
const matches = imp.match(DEPENDENCY_REG);
if (matches) {
const [_, pkgRegistry, pkgScope, pkgFilePath, pkgVersion] = matches;
const pkgName = pkgFilePath.split("/").shift();
const name = pkgScope ? `${pkgScope}${pkgName}` : pkgName;
const version = pkgVersion || "";
const registry = (pkgRegistry === null || pkgRegistry === void 0 ? void 0 : pkgRegistry.split(":").shift()) || "";
dependencies.push({ name, version, registry });
}
}
return dependencies;
}
/**
* 从源代码中提取所有导入语句
* @param code 源代码字符串
* @returns 导入语句数组
*/
function getImportsFromSourceCode(code) {
if (!code || !code.trim()) {
return [];
}
const imports = [];
// 将visitNode函数定义移到函数根作用域
function visitNode(node, dependencies) {
// 处理 import 语句
if (typescript_1.default.isImportDeclaration(node)) {
const moduleSpecifier = node.moduleSpecifier;
if (typescript_1.default.isStringLiteral(moduleSpecifier)) {
dependencies.push(moduleSpecifier.text);
}
} // 处理动态 import()
else if (typescript_1.default.isCallExpression(node)) {
if (node.expression.kind === typescript_1.default.SyntaxKind.ImportKeyword) {
const arg = node.arguments[0];
if (typescript_1.default.isStringLiteral(arg)) {
dependencies.push(arg.text);
}
} // 处理 require()
else if (typescript_1.default.isIdentifier(node.expression) && node.expression.text === "require") {
const arg = node.arguments[0];
if (typescript_1.default.isStringLiteral(arg)) {
dependencies.push(arg.text);
}
}
}
// 递归遍历子节点
typescript_1.default.forEachChild(node, (child) => visitNode(child, dependencies));
}
try {
const sourceFile = typescript_1.default.createSourceFile("__temp__.ts", code, typescript_1.default.ScriptTarget.Latest, true);
visitNode(sourceFile, imports);
}
catch (error) {
console.error("Failed to parse source code:", error);
}
return Array.from(new Set(imports));
}