cnpmcore
Version:
Private NPM Registry for Enterprise
122 lines • 9.86 kB
JavaScript
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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