UNPKG

verdaccio

Version:

A lightweight private npm proxy registry

1 lines 12 kB
{"version":3,"file":"utils.mjs","names":[],"sources":["../../src/lib/utils.ts"],"sourcesContent":["import createDebug from 'debug';\nimport _ from 'lodash';\nimport path from 'node:path';\nimport semver from 'semver';\n\nimport { parseConfigFile } from '@verdaccio/config';\nimport { errorUtils, pkgUtils, validationUtils, warningUtils } from '@verdaccio/core';\nimport { ConfigYaml, LoggerConfigItem, StringValue } from '@verdaccio/types';\nimport { Config, Manifest, Version } from '@verdaccio/types';\nimport { buildToken as buildTokenUtil } from '@verdaccio/utils';\n\nimport { DIST_TAGS, certPem, csrPem, keyPem } from './constants';\nimport { logger, setup } from './logger';\n\nconst debug = createDebug('verdaccio:lib:utils');\n\nconst {\n getBadData,\n getBadRequest,\n getCode,\n getConflict,\n getForbidden,\n getInternalError,\n getNotFound,\n getServiceUnavailable,\n getUnauthorized,\n} = errorUtils;\n\nexport function initLogger(logConfig: ConfigYaml) {\n if (logConfig.logs) {\n logConfig.log = logConfig.logs;\n warningUtils.emit(warningUtils.Codes.VERWAR002);\n }\n debug('initializing logger with config: %o', logConfig.log);\n setup(logConfig.log as LoggerConfigItem);\n}\n\nexport function addScope(scope: string, packageName: string): string {\n return `@${scope}/${packageName}`;\n}\n\n/**\n * Check whether an element is an Object\n * @param {*} obj the element\n * @return {Boolean}\n */\nexport const isObject = validationUtils.isObject;\n\n/**\n * @deprecated not used un v6\n */\nexport function isObjectOrArray(obj: any): boolean {\n return _.isObject(obj) && _.isNull(obj) === false;\n}\n\nexport function tagVersion(data: Manifest, version: string, tag: StringValue): boolean {\n if (tag && data[DIST_TAGS][tag] !== version && semver.parse(version, true)) {\n // valid version - store\n data[DIST_TAGS][tag] = version;\n return true;\n }\n return false;\n}\n\n/**\n * Gets version from a package object taking into account semver weirdness.\n * @return {String} return the semantic version of a package\n */\nexport function getVersion(pkg: Manifest, version: any): Version | void {\n // this condition must allow cast\n if (_.isNil(pkg.versions[version]) === false) {\n return pkg.versions[version];\n }\n\n try {\n version = semver.parse(version, true);\n for (const versionItem in pkg.versions) {\n if (version.compare(semver.parse(versionItem, true)) === 0) {\n return pkg.versions[versionItem];\n }\n }\n } catch {\n return undefined;\n }\n}\n\n/**\n * Flatten arrays of tags.\n * @param {*} data\n */\nexport function normalizeDistTags(pkg: Manifest): void {\n let sorted;\n if (!pkg[DIST_TAGS].latest) {\n // overwrite latest with highest known version based on semver sort\n sorted = pkgUtils.semverSort(Object.keys(pkg.versions));\n if (sorted && sorted.length) {\n pkg[DIST_TAGS].latest = sorted.pop();\n }\n }\n\n for (const tag in pkg[DIST_TAGS]) {\n if (_.isArray(pkg[DIST_TAGS][tag])) {\n if (pkg[DIST_TAGS][tag].length) {\n // sort array\n // FIXME: this is clearly wrong, we need to research why this is like this.\n sorted = pkgUtils.semverSort(pkg[DIST_TAGS][tag]);\n if (sorted.length) {\n // use highest version based on semver sort\n pkg[DIST_TAGS][tag] = sorted.pop();\n }\n } else {\n delete pkg[DIST_TAGS][tag];\n }\n } else if (_.isString(pkg[DIST_TAGS][tag])) {\n if (!semver.parse(pkg[DIST_TAGS][tag], true)) {\n // if the version is invalid, delete the dist-tag entry\n delete pkg[DIST_TAGS][tag];\n }\n }\n }\n}\n\nconst parseIntervalTable = {\n '': 1000,\n ms: 1,\n s: 1000,\n m: 60 * 1000,\n h: 60 * 60 * 1000,\n d: 86400000,\n w: 7 * 86400000,\n M: 30 * 86400000,\n y: 365 * 86400000,\n};\n\n/**\n * Parse an internal string to number\n * @param {*} interval\n * @return {Number}\n */\nexport function parseInterval(interval: any): number {\n if (typeof interval === 'number') {\n return interval * 1000;\n }\n let result = 0;\n let last_suffix = Infinity;\n interval.split(/\\s+/).forEach(function (x): void {\n if (!x) {\n return;\n }\n const m = x.match(/^((0|[1-9][0-9]*)(\\.[0-9]+)?)(ms|s|m|h|d|w|M|y|)$/);\n if (\n !m ||\n parseIntervalTable[m[4]] >= last_suffix ||\n (m[4] === '' && last_suffix !== Infinity)\n ) {\n throw Error('invalid interval: ' + interval);\n }\n last_suffix = parseIntervalTable[m[4]];\n result += Number(m[1]) * parseIntervalTable[m[4]];\n });\n return result;\n}\n\nexport const ErrorCode = {\n getConflict,\n getBadData,\n getBadRequest,\n getInternalError,\n getUnauthorized,\n getForbidden,\n getServiceUnavailable,\n getNotFound,\n getCode,\n};\n\nexport function sortByName(packages: any[], orderAscending: boolean | void = true): string[] {\n return packages.slice().sort(function (a, b): number {\n const comparatorNames = a.name.toLowerCase() < b.name.toLowerCase();\n\n return orderAscending ? (comparatorNames ? -1 : 1) : comparatorNames ? 1 : -1;\n });\n}\n\nexport function deleteProperties(propertiesToDelete: string[], objectItem: any): any {\n _.forEach(propertiesToDelete, (property): any => {\n delete objectItem[property];\n });\n\n return objectItem;\n}\n\n/**\n * parse package readme - markdown/ascii\n * @param {String} packageName name of package\n * @param {String} readme package readme\n\n * @return {String} converted html template\n */\n// TODO: rename, does not parse anymore\nexport function parseReadme(packageName: string, readme: string): string | void {\n if (_.isEmpty(readme) === false) {\n return readme;\n }\n\n // logs readme not found error\n logger.info({ packageName }, '@{packageName}: No readme found');\n\n return 'ERROR: No README data found!';\n}\n\nexport function encodeScopedUri(packageName): string {\n return packageName.replace(/\\//g, '%2f');\n}\n\nexport function hasDiffOneKey(versions): boolean {\n return Object.keys(versions).length !== 1;\n}\n\nexport function isVersionValid(packageMeta, packageVersion): boolean {\n const hasVersion = typeof packageVersion !== 'undefined';\n if (!hasVersion) {\n return false;\n }\n\n const hasMatchVersion = Object.keys(packageMeta.versions).includes(packageVersion);\n return hasMatchVersion;\n}\n\nexport function isRelatedToDeprecation(pkgInfo: Manifest): boolean {\n const { versions } = pkgInfo;\n for (const version in versions) {\n if (Object.prototype.hasOwnProperty.call(versions[version], 'deprecated')) {\n return true;\n }\n }\n return false;\n}\n\nexport const resolveConfigPath = function (storageLocation: string, file: string) {\n return path.resolve(path.dirname(storageLocation), file);\n};\n\nexport function logHTTPSWarning(storageLocation) {\n logger.fatal(\n [\n 'You have enabled HTTPS and need to specify either ',\n ' \"https.key\" and \"https.cert\" or ',\n ' \"https.pfx\" and optionally \"https.passphrase\" ',\n 'to run https server',\n '',\n // commands are borrowed from node.js docs\n 'To quickly create self-signed certificate, use:',\n ' $ openssl genrsa -out ' + resolveConfigPath(storageLocation, keyPem) + ' 2048',\n ' $ openssl req -new -sha256 -key ' +\n resolveConfigPath(storageLocation, keyPem) +\n ' -out ' +\n resolveConfigPath(storageLocation, csrPem),\n ' $ openssl x509 -req -in ' +\n resolveConfigPath(storageLocation, csrPem) +\n ' -signkey ' +\n resolveConfigPath(storageLocation, keyPem) +\n ' -out ' +\n resolveConfigPath(storageLocation, certPem),\n '',\n 'And then add to config file (' + storageLocation + '):',\n ' https:',\n ` key: ${resolveConfigPath(storageLocation, keyPem)}`,\n ` cert: ${resolveConfigPath(storageLocation, certPem)}`,\n ].join('\\n')\n );\n process.exit(2);\n}\n\nexport function hasLogin(config: Config) {\n return _.isNil(config?.web?.login) || config?.web?.login === true;\n}\n\n/**\n * Check whether any version in a package manifest has a tarball URL\n * that matches the given filename.\n */\nexport function hasTarball(pkg: Manifest, filename: string): boolean {\n return Object.values(pkg.versions || {}).some((version) =>\n (version as Version).dist?.tarball?.endsWith('/' + filename)\n );\n}\n\nexport { buildTokenUtil as buildToken, parseConfigFile };\n"],"mappings":"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"}