UNPKG

monaco-auto-typings

Version:

provides automatic dependency type completion for Monaco Editor

160 lines (159 loc) 5.6 kB
import { inflate } from "pako"; import { untar } from "@andrewbranch/untar.js"; import { fetchWithTimeout } from '../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 = inflate(buffer); const files = await 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注册表管理器 */ export 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 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 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; } } } /** * JSR注册表管理器 */ export 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 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 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; } } } export 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); } } }