UNPKG

cnpmcore

Version:

Private NPM Registry for Enterprise

122 lines 9.86 kB
import { randomBytes } from 'node:crypto'; import { createWriteStream } from 'node:fs'; // oxlint-disable import/exports-last import { mkdir, rm } from 'node:fs/promises'; import path from 'node:path'; import { setTimeout } from 'node:timers/promises'; import url from 'node:url'; import mime from 'mime-types'; import dayjs from "./dayjs.js"; async function _downloadToTempfile(httpclient, dataDir, url, optionalConfig) { const tmpfile = await createTempfile(dataDir, url); const writeStream = createWriteStream(tmpfile); try { // max 10 mins to download // FIXME: should show download progress const requestHeaders = {}; if (optionalConfig?.remoteAuthToken) { requestHeaders.authorization = `Bearer ${optionalConfig.remoteAuthToken}`; } const { status, headers, res } = (await httpclient.request(url, { timeout: 60_000 * 10, headers: requestHeaders, writeStream, timing: true, followRedirect: true, })); if (status === 404 || (optionalConfig?.ignoreDownloadStatuses && optionalConfig.ignoreDownloadStatuses.includes(status))) { const err = new Error(`Not found, status(${status})`); err.name = 'DownloadNotFoundError'; throw err; } if (status !== 200) { const err = new Error(`Download ${url} status(${status}) invalid`); err.name = 'DownloadStatusInvalidError'; throw err; } return { tmpfile, headers, timing: res.timing, }; } catch (err) { await rm(tmpfile, { force: true }); throw err; } } export async function createTempDir(dataDir, dirname) { // will auto clean on CleanTempDir Schedule let tmpdir = path.join(dataDir, 'downloads', dayjs().format('YYYY/MM/DD')); if (dirname) { tmpdir = path.join(tmpdir, dirname); } await mkdir(tmpdir, { recursive: true }); return tmpdir; } export async function createTempfile(dataDir, filename) { const tmpdir = await createTempDir(dataDir); // The filename is a URL (from dist.tarball), which needs to be truncated, (`getconf NAME_MAX /` # max filename length: 255 bytes) // https://github.com/cnpm/cnpmjs.org/pull/1345 const tmpfile = path.join(tmpdir, // oxlint-disable-next-line typescript-eslint/no-non-null-assertion `${randomBytes(10).toString('hex')}-${path.basename(url.parse(filename).pathname)}`); return tmpfile; } export async function downloadToTempfile(httpclient, dataDir, url, optionalConfig) { let retries = optionalConfig?.retries || 3; let lastError; while (retries > 0) { try { return await _downloadToTempfile(httpclient, dataDir, url, optionalConfig); } catch (err) { if (err.name === 'DownloadNotFoundError') throw err; lastError = err; } retries--; if (retries > 0) { // sleep 1s ~ 4s in random const delay = process.env.NODE_ENV === 'test' ? 1 : 1000 + Math.random() * 4000; await setTimeout(delay); } } // oxlint-disable-next-line no-throw-literal throw lastError; } const DEFAULT_CONTENT_TYPE = 'application/octet-stream'; const PLAIN_TEXT = 'text/plain'; const WHITE_FILENAME_CONTENT_TYPES = { license: PLAIN_TEXT, readme: PLAIN_TEXT, history: PLAIN_TEXT, changelog: PLAIN_TEXT, '.npmignore': PLAIN_TEXT, '.jshintignore': PLAIN_TEXT, '.eslintignore': PLAIN_TEXT, '.jshintrc': 'application/json', '.eslintrc': 'application/json', }; const CONTENT_TYPE_BLACKLIST = new Set(['application/xml', 'text/html']); export function ensureContentType(contentType) { if (CONTENT_TYPE_BLACKLIST.has(contentType)) { return 'text/plain'; } return contentType; } export function mimeLookup(filepath) { const filename = path.basename(filepath).toLowerCase(); if (filename.endsWith('.ts')) return PLAIN_TEXT; if (filename.endsWith('.lock')) return PLAIN_TEXT; const defaultContentType = mime.lookup(filename); // https://github.com/cnpm/cnpmcore/issues/693#issuecomment-2955268229 const contentType = defaultContentType || WHITE_FILENAME_CONTENT_TYPES[filename] || DEFAULT_CONTENT_TYPE; return ensureContentType(contentType); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRmlsZVV0aWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9hcHAvY29tbW9uL0ZpbGVVdGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDMUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzVDLHFDQUFxQztBQUNyQyxPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzdDLE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUM3QixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxHQUFHLE1BQU0sVUFBVSxDQUFDO0FBRzNCLE9BQU8sSUFBSSxNQUFNLFlBQVksQ0FBQztBQUU5QixPQUFPLEtBQUssTUFBTSxZQUFZLENBQUM7QUFFL0IsS0FBSyxVQUFVLG1CQUFtQixDQUNoQyxVQUFnQyxFQUNoQyxPQUFlLEVBQ2YsR0FBVyxFQUNYLGNBQWlEO0lBRWpELE1BQU0sT0FBTyxHQUFHLE1BQU0sY0FBYyxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQztJQUNuRCxNQUFNLFdBQVcsR0FBRyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMvQyxJQUFJLENBQUM7UUFDSCwwQkFBMEI7UUFDMUIsdUNBQXVDO1FBQ3ZDLE1BQU0sY0FBYyxHQUEyQixFQUFFLENBQUM7UUFDbEQsSUFBSSxjQUFjLEVBQUUsZUFBZSxFQUFFLENBQUM7WUFDcEMsY0FBYyxDQUFDLGFBQWEsR0FBRyxVQUFVLGNBQWMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUM1RSxDQUFDO1FBQ0QsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxNQUFNLFVBQVUsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFO1lBQzlELE9BQU8sRUFBRSxNQUFNLEdB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