monaco-auto-typings
Version:
provides automatic dependency type completion for Monaco Editor
166 lines (165 loc) • 5.92 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.RegistryFactory = exports.JSRRegistry = exports.NPMRegistry = void 0;
const pako_1 = require("pako");
const untar_js_1 = require("@andrewbranch/untar.js");
const index_1 = require("../utils/index");
/**
* 注册表管理器基类
*/
class BaseRegistry {
constructor(registryUrl) {
this.registryUrl = registryUrl;
}
/**
* 解压依赖包的tar.gz文件并返回文件列表
*/
async untarDependencyPkg(res) {
if (!res.ok) {
throw new Error(`HTTP request failed: ${res.status} ${res.statusText}`);
}
try {
const buffer = await res.arrayBuffer();
if (buffer.byteLength === 0) {
throw new Error('Response content is empty');
}
const arr = (0, pako_1.inflate)(buffer);
const files = await (0, untar_js_1.untar)(arr.buffer);
return files;
}
catch (error) {
console.error("Failed to extract dependency package:", error);
throw new Error(`Extraction failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
}
/**
* NPM注册表管理器
*/
class NPMRegistry extends BaseRegistry {
constructor(registryUrl = "https://registry.npmjs.org") {
super(registryUrl);
}
/**
* 从NPM获取依赖的类型定义文件
*/
async getDependencyTypes(dependency) {
var _a;
const result = { types: "", files: [] };
try {
const { name, version } = dependency;
if (!name) {
throw new Error('Package name cannot be empty');
}
const packageVersion = version || "latest";
const packageInfoUrl = `${this.registryUrl}/${encodeURIComponent(name)}/${encodeURIComponent(packageVersion)}`;
// Get package information
const packageInfoRes = await (0, index_1.fetchWithTimeout)(packageInfoUrl);
if (!packageInfoRes.ok) {
throw new Error(`Failed to get package information: ${packageInfoRes.status} ${packageInfoRes.statusText}`);
}
const packageInfo = await packageInfoRes.json();
if (packageInfo.error) {
throw new Error(`Package information error: ${packageInfo.error}`);
}
if (!((_a = packageInfo.dist) === null || _a === void 0 ? void 0 : _a.tarball)) {
throw new Error('Missing tarball download URL in package information');
}
// Download and extract npm package
const tarballRes = await (0, index_1.fetchWithTimeout)(packageInfo.dist.tarball);
const files = await this.untarDependencyPkg(tarballRes);
result.types = packageInfo.types || packageInfo.typings || "";
result.files = files.filter((item) => item.name.endsWith(".d.ts"));
return result;
}
catch (error) {
console.error(`Failed to get type definitions from NPM (${dependency.name}):`, error);
throw error;
}
}
}
exports.NPMRegistry = NPMRegistry;
/**
* JSR注册表管理器
*/
class JSRRegistry extends BaseRegistry {
constructor() {
super("https://jsr.io");
}
/**
* 从JSR获取依赖的类型定义文件
*/
async getDependencyTypes(dependency) {
try {
let { name, version } = dependency;
if (!name) {
throw new Error('Package name cannot be empty');
}
if (!version) {
// 如果没有指定版本,获取最新版本
const metaUrl = `${this.registryUrl}/${name}/meta.json`;
const res = await (0, index_1.fetchWithTimeout)(metaUrl);
if (!res.ok) {
throw new Error(`Failed to get package metadata: ${res.status} ${res.statusText}`);
}
const result = (await res.json());
version = result.latest;
if (!version) {
throw new Error('Unable to get the latest version information for the package');
}
}
if (!version) {
throw new Error('Invalid package version information');
}
// 构建JSR包的下载URL
const packageUrl = `https://npm.jsr.io/~/11/@jsr/${name
.replace("@", "")
.replace("/", "__")}/${version}.tgz`;
const res = await (0, index_1.fetchWithTimeout)(packageUrl);
const files = await this.untarDependencyPkg(res);
// 只返回.d.ts类型定义文件
return {
types: "",
files: files.filter((item) => item.name.endsWith(".d.ts"))
};
}
catch (error) {
console.error(`Failed to get type definitions from JSR (${dependency.name}):`, error);
throw error;
}
}
}
exports.JSRRegistry = JSRRegistry;
class RegistryFactory {
/**
* NPM镜像
*/
static getNPMRegistry(registryUrl) {
if (!this.npmRegistry || registryUrl) {
this.npmRegistry = new NPMRegistry(registryUrl);
}
return this.npmRegistry;
}
/**
* JSR仓库
*/
static getJSRRegistry() {
if (!this.jsrRegistry) {
this.jsrRegistry = new JSRRegistry();
}
return this.jsrRegistry;
}
/**
* 根据注册表类型获取实例
*/
static getRegistry(type, registryUrl) {
switch (type.toLowerCase()) {
case 'jsr':
return this.getJSRRegistry();
case 'npm':
default:
return this.getNPMRegistry(registryUrl);
}
}
}
exports.RegistryFactory = RegistryFactory;