UNPKG

nrm-lite

Version:

Fast and lightweight NpmRegistryManager, for the minimalists.

91 lines (85 loc) 2.67 kB
import { parse } from 'node:url' import { createInterface } from 'node:readline' import { request } from './utils.mjs' /** * @type {Record<string, string>} */ export const REGISTRIES = { npm: 'https://registry.npmjs.org/', yarn: 'https://registry.yarnpkg.com/', github: 'https://npm.pkg.github.com/', taobao: 'https://registry.npmmirror.com/', cnpm: 'https://r.cnpmjs.org/', npmMirror: 'https://skimdb.npmjs.com/registry/', tencent: 'https://mirrors.cloud.tencent.com/npm/', huawei: 'https://mirrors.huaweicloud.com/repository/npm/', ustc: 'https://npmreg.proxy.ustclug.org/', } /** * Returns undefined when line does not contain registry, or registry as string * @param {string} line */ function checkLine(line) { let currLine = line.trim() const keyName = 'registry' if (!currLine.startsWith(keyName)) return currLine = currLine.slice(keyName.length).trimStart() if (!currLine.startsWith('=')) return return currLine.slice(1).trimStart() } /** * @param {NodeJS.ReadableStream} stream * @returns {Promise<string | undefined>} * @see https://docs.npmjs.com/cli/configuring-npm/npmrc */ export async function getRegistryFromStream(stream) { const rl = createInterface(stream) for await (const line of rl) { const r = checkLine(line) if (r) return r } } /** * Returns the proceed rc content * @param {NodeJS.ReadableStream} stream * @param {string} registryUrl * @returns {Promise<string>} */ export async function setRegistryFromStream(stream, registryUrl) { const rl = createInterface(stream) const lines = [] for await (const line of rl) { const r = checkLine(line) if (r) { lines.push(`registry=${registryUrl}`) } else { lines.push(line) } } return lines.join('\n') } /** * Returns `Infinity` when exceed timeout, and `null` when network error * @param {string} url * @param {number} timeoutLimit - in milliseconds */ export async function speedTest(url, timeoutLimit) { return new Promise((resolve) => { const beginTime = Date.now() request( { method: 'HEAD', ...parse(url), timeout: timeoutLimit }, (res) => { res.destroy() const timeSpent = Date.now() - beginTime resolve(timeSpent > timeoutLimit ? Infinity : timeSpent) // Normal response }, ) .on('timeout', () => { resolve(Infinity) // Timeout }) .on('error', () => { resolve(null) // Network Error }) .end() }) }