verdaccio
Version:
A lightweight private npm proxy registry
188 lines (186 loc) • 6.67 kB
JavaScript
import { DIST_TAGS, certPem, csrPem, keyPem } from "./constants.mjs";
import { logger, setup } from "./logger/index.mjs";
import _ from "lodash";
import { errorUtils, pkgUtils, validationUtils, warningUtils } from "@verdaccio/core";
import { buildToken as buildTokenUtil } from "@verdaccio/utils";
import createDebug from "debug";
import path from "node:path";
import semver from "semver";
import { parseConfigFile } from "@verdaccio/config";
//#region src/lib/utils.ts
var debug = createDebug("verdaccio:lib:utils");
var { getBadData, getBadRequest, getCode, getConflict, getForbidden, getInternalError, getNotFound, getServiceUnavailable, getUnauthorized } = errorUtils;
function initLogger(logConfig) {
if (logConfig.logs) {
logConfig.log = logConfig.logs;
warningUtils.emit(warningUtils.Codes.VERWAR002);
}
debug("initializing logger with config: %o", logConfig.log);
setup(logConfig.log);
}
function addScope(scope, packageName) {
return `@${scope}/${packageName}`;
}
/**
* Check whether an element is an Object
* @param {*} obj the element
* @return {Boolean}
*/
var isObject = validationUtils.isObject;
/**
* @deprecated not used un v6
*/
function isObjectOrArray(obj) {
return _.isObject(obj) && _.isNull(obj) === false;
}
function tagVersion(data, version, tag) {
if (tag && data["dist-tags"][tag] !== version && semver.parse(version, true)) {
data[DIST_TAGS][tag] = version;
return true;
}
return false;
}
/**
* Gets version from a package object taking into account semver weirdness.
* @return {String} return the semantic version of a package
*/
function getVersion(pkg, version) {
if (_.isNil(pkg.versions[version]) === false) return pkg.versions[version];
try {
version = semver.parse(version, true);
for (const versionItem in pkg.versions) if (version.compare(semver.parse(versionItem, true)) === 0) return pkg.versions[versionItem];
} catch {
return;
}
}
/**
* Flatten arrays of tags.
* @param {*} data
*/
function normalizeDistTags(pkg) {
let sorted;
if (!pkg["dist-tags"].latest) {
sorted = pkgUtils.semverSort(Object.keys(pkg.versions));
if (sorted && sorted.length) pkg[DIST_TAGS].latest = sorted.pop();
}
for (const tag in pkg[DIST_TAGS]) if (_.isArray(pkg["dist-tags"][tag])) if (pkg["dist-tags"][tag].length) {
sorted = pkgUtils.semverSort(pkg[DIST_TAGS][tag]);
if (sorted.length) pkg[DIST_TAGS][tag] = sorted.pop();
} else delete pkg[DIST_TAGS][tag];
else if (_.isString(pkg["dist-tags"][tag])) {
if (!semver.parse(pkg["dist-tags"][tag], true)) delete pkg[DIST_TAGS][tag];
}
}
var parseIntervalTable = {
"": 1e3,
ms: 1,
s: 1e3,
m: 60 * 1e3,
h: 3600 * 1e3,
d: 864e5,
w: 7 * 864e5,
M: 30 * 864e5,
y: 365 * 864e5
};
/**
* Parse an internal string to number
* @param {*} interval
* @return {Number}
*/
function parseInterval(interval) {
if (typeof interval === "number") return interval * 1e3;
let result = 0;
let last_suffix = Infinity;
interval.split(/\s+/).forEach(function(x) {
if (!x) return;
const m = x.match(/^((0|[1-9][0-9]*)(\.[0-9]+)?)(ms|s|m|h|d|w|M|y|)$/);
if (!m || parseIntervalTable[m[4]] >= last_suffix || m[4] === "" && last_suffix !== Infinity) throw Error("invalid interval: " + interval);
last_suffix = parseIntervalTable[m[4]];
result += Number(m[1]) * parseIntervalTable[m[4]];
});
return result;
}
var ErrorCode = {
getConflict,
getBadData,
getBadRequest,
getInternalError,
getUnauthorized,
getForbidden,
getServiceUnavailable,
getNotFound,
getCode
};
function sortByName(packages, orderAscending = true) {
return packages.slice().sort(function(a, b) {
const comparatorNames = a.name.toLowerCase() < b.name.toLowerCase();
return orderAscending ? comparatorNames ? -1 : 1 : comparatorNames ? 1 : -1;
});
}
function deleteProperties(propertiesToDelete, objectItem) {
_.forEach(propertiesToDelete, (property) => {
delete objectItem[property];
});
return objectItem;
}
/**
* parse package readme - markdown/ascii
* @param {String} packageName name of package
* @param {String} readme package readme
* @return {String} converted html template
*/
function parseReadme(packageName, readme) {
if (_.isEmpty(readme) === false) return readme;
logger.info({ packageName }, "@{packageName}: No readme found");
return "ERROR: No README data found!";
}
function encodeScopedUri(packageName) {
return packageName.replace(/\//g, "%2f");
}
function hasDiffOneKey(versions) {
return Object.keys(versions).length !== 1;
}
function isVersionValid(packageMeta, packageVersion) {
if (!(typeof packageVersion !== "undefined")) return false;
return Object.keys(packageMeta.versions).includes(packageVersion);
}
function isRelatedToDeprecation(pkgInfo) {
const { versions } = pkgInfo;
for (const version in versions) if (Object.prototype.hasOwnProperty.call(versions[version], "deprecated")) return true;
return false;
}
var resolveConfigPath = function(storageLocation, file) {
return path.resolve(path.dirname(storageLocation), file);
};
function logHTTPSWarning(storageLocation) {
logger.fatal([
"You have enabled HTTPS and need to specify either ",
" \"https.key\" and \"https.cert\" or ",
" \"https.pfx\" and optionally \"https.passphrase\" ",
"to run https server",
"",
"To quickly create self-signed certificate, use:",
" $ openssl genrsa -out " + resolveConfigPath(storageLocation, keyPem) + " 2048",
" $ openssl req -new -sha256 -key " + resolveConfigPath(storageLocation, keyPem) + " -out " + resolveConfigPath(storageLocation, csrPem),
" $ openssl x509 -req -in " + resolveConfigPath(storageLocation, csrPem) + " -signkey " + resolveConfigPath(storageLocation, keyPem) + " -out " + resolveConfigPath(storageLocation, certPem),
"",
"And then add to config file (" + storageLocation + "):",
" https:",
` key: ${resolveConfigPath(storageLocation, keyPem)}`,
` cert: ${resolveConfigPath(storageLocation, certPem)}`
].join("\n"));
process.exit(2);
}
function hasLogin(config) {
return _.isNil(config?.web?.login) || config?.web?.login === true;
}
/**
* Check whether any version in a package manifest has a tarball URL
* that matches the given filename.
*/
function hasTarball(pkg, filename) {
return Object.values(pkg.versions || {}).some((version) => version.dist?.tarball?.endsWith("/" + filename));
}
//#endregion
export { ErrorCode, addScope, buildTokenUtil as buildToken, deleteProperties, encodeScopedUri, getVersion, hasDiffOneKey, hasLogin, hasTarball, initLogger, isObject, isObjectOrArray, isRelatedToDeprecation, isVersionValid, logHTTPSWarning, normalizeDistTags, parseConfigFile, parseInterval, parseReadme, resolveConfigPath, sortByName, tagVersion };
//# sourceMappingURL=utils.mjs.map