verdaccio
Version:
A lightweight private npm proxy registry
1 lines • 41.5 kB
Source Map (JSON)
{"version":3,"file":"local-storage.mjs","names":[],"sources":["../../src/lib/local-storage.ts"],"sourcesContent":["import assert from 'assert';\nimport builDebug from 'debug';\nimport _ from 'lodash';\n\nimport { ReadTarball, UploadTarball } from '@verdaccio/streams';\nimport {\n Author,\n Callback,\n Config,\n DistFile,\n Logger,\n Manifest,\n MergeTags,\n StorageUpdateCallback,\n Token,\n TokenFilter,\n Version,\n onEndSearchPackage,\n onSearchPackage,\n} from '@verdaccio/types';\nimport {\n createTarballHash,\n getLatestVersion,\n normalizeContributors,\n validateName,\n} from '@verdaccio/utils';\n\nimport { StoragePluginLegacy } from '../../types/custom';\nimport { StringValue } from '../types';\nimport { API_ERROR, DIST_TAGS, HTTP_STATUS, STORAGE, SUPPORT_ERRORS, USERS } from './constants';\nimport {\n cleanUpReadme,\n generatePackageTemplate,\n generateRevision,\n getLatestReadme,\n normalizePackage,\n} from './storage-utils';\nimport { prepareSearchPackage } from './storage-utils';\nimport { ErrorCode, isObject, tagVersion } from './utils';\n\nconst debug = builDebug('verdaccio:local-storage');\nexport type StoragePlugin = StoragePluginLegacy<Config> | any;\n/**\n * Implements Storage interface (same for storage.js, local-storage.js, up-storage.js).\n */\nclass LocalStorage {\n public config: Config;\n public storagePlugin: StoragePlugin;\n public logger: Logger;\n\n public constructor(config: Config, logger: Logger, localStorage: StoragePlugin) {\n this.logger = logger;\n this.config = config;\n this.storagePlugin = localStorage;\n }\n\n public addPackage(name: string, pkg: Manifest, callback: Callback): void {\n const storage: any = this._getLocalStorage(name);\n\n if (_.isNil(storage)) {\n return callback(ErrorCode.getNotFound('this package cannot be added'));\n }\n\n storage.createPackage(name, generatePackageTemplate(name), (err) => {\n // FIXME: it will be fixed here https://github.com/verdaccio/verdaccio/pull/1360\n // @ts-ignore\n if (\n _.isNull(err) === false &&\n (err.code === STORAGE.FILE_EXIST_ERROR || err.code === HTTP_STATUS.CONFLICT)\n ) {\n return callback(ErrorCode.getConflict());\n }\n\n const latest = getLatestVersion(pkg);\n if (_.isNil(latest) === false && pkg.versions[latest]) {\n return callback(null, pkg.versions[latest]);\n }\n\n return callback();\n });\n }\n\n /**\n * Remove package.\n * @param {*} name\n * @param {*} callback\n * @return {Function}\n */\n public removePackage(name: string, callback: Callback): void {\n const storage: any = this._getLocalStorage(name);\n debug('[storage] removing package %o', name);\n if (_.isNil(storage)) {\n return callback(ErrorCode.getNotFound());\n }\n\n storage.readPackage(name, (err, data: Manifest): void => {\n if (_.isNil(err) === false) {\n if (err.code === STORAGE.NO_SUCH_FILE_ERROR || err.code === HTTP_STATUS.NOT_FOUND) {\n return callback(ErrorCode.getNotFound());\n }\n return callback(err);\n }\n\n data = normalizePackage(data);\n this.storagePlugin.remove(name, (removeFailed: Error): void => {\n if (removeFailed) {\n // This will happen when database is locked\n this.logger.error(\n { name },\n `[storage/removePackage] the database is locked, removed has failed for @{name}`\n );\n return callback(ErrorCode.getBadData(removeFailed.message));\n }\n\n storage.deletePackage(STORAGE.PACKAGE_FILE_NAME, (err): void => {\n if (err) {\n return callback(err);\n }\n const attachments = Object.keys(data._attachments);\n\n this._deleteAttachments(storage, attachments, callback);\n });\n });\n });\n }\n\n /**\n * Synchronize remote package info with the local one\n * @param {*} name\n * @param {*} packageInfo\n * @param {*} callback\n */\n public updateVersions(name: string, packageInfo: Manifest, callback: Callback): void {\n this._readCreatePackage(name, (err, packageLocalJson): void => {\n if (err) {\n return callback(err);\n }\n\n let change = false;\n // updating readme\n packageLocalJson.readme = getLatestReadme(packageInfo);\n if (packageInfo.readme !== packageLocalJson.readme) {\n change = true;\n }\n for (const versionId in packageInfo.versions) {\n if (_.isNil(packageLocalJson.versions[versionId])) {\n let version = packageInfo.versions[versionId];\n\n // we don't keep readme for package versions,\n // only one readme per package\n version = cleanUpReadme(version);\n version.contributors = normalizeContributors(version.contributors as Author[]);\n\n change = true;\n packageLocalJson.versions[versionId] = version;\n\n if (version.dist && version.dist.tarball) {\n let urlObject: URL;\n try {\n // The single-arg WHATWG `URL` constructor throws on a relative url,\n // whereas the legacy `url.parse()` this replaced accepted one. The\n // `http://localhost` base is an arbitrary placeholder that lets a\n // relative `dist.tarball` resolve instead of throwing; only\n // `.pathname` is read from the result, so the host is never used and\n // is ignored entirely for the absolute urls registries return.\n urlObject = new URL(version.dist.tarball, 'http://localhost');\n } catch (err: any) {\n // an upstream registry may return a malformed tarball url; skip\n // recording this distfile rather than aborting the whole update\n this.logger.warn(\n { name, version: versionId, tarball: version.dist.tarball, err: err.message },\n 'skipping distfile for @{name}@@{version}: invalid tarball url @{tarball} (@{err})'\n );\n continue;\n }\n const filename = urlObject.pathname.replace(/^.*\\//, '');\n\n // we do NOT overwrite any existing records\n if (_.isNil(packageLocalJson._distfiles[filename])) {\n const hash: DistFile = (packageLocalJson._distfiles[filename] = {\n url: version.dist.tarball,\n sha: version.dist.shasum,\n });\n const upLink: string = version[Symbol.for('__verdaccio_uplink')];\n\n if (_.isNil(upLink) === false) {\n this._updateUplinkToRemoteProtocol(hash, upLink);\n }\n }\n }\n }\n }\n\n for (const tag in packageInfo[DIST_TAGS]) {\n if (\n !packageLocalJson[DIST_TAGS][tag] ||\n packageLocalJson[DIST_TAGS][tag] !== packageInfo[DIST_TAGS][tag]\n ) {\n change = true;\n packageLocalJson[DIST_TAGS][tag] = packageInfo[DIST_TAGS][tag];\n }\n }\n\n for (const up in packageInfo._uplinks) {\n if (Object.prototype.hasOwnProperty.call(packageInfo._uplinks, up)) {\n const need_change =\n !isObject(packageLocalJson._uplinks[up]) ||\n packageInfo._uplinks[up].etag !== packageLocalJson._uplinks[up].etag ||\n packageInfo._uplinks[up].fetched !== packageLocalJson._uplinks[up].fetched;\n\n if (need_change) {\n change = true;\n packageLocalJson._uplinks[up] = packageInfo._uplinks[up];\n }\n }\n }\n\n if ('time' in packageInfo && !_.isEqual(packageLocalJson.time, packageInfo.time)) {\n packageLocalJson.time = packageInfo.time;\n change = true;\n }\n\n if (change) {\n debug('updating package %o info', name);\n this._writePackage(name, packageLocalJson, function (err): void {\n callback(err, packageLocalJson);\n });\n } else {\n callback(null, packageLocalJson);\n }\n });\n }\n\n /**\n * Add a new version to a previous local package.\n * @param {*} name\n * @param {*} version\n * @param {*} metadata\n * @param {*} tag\n * @param {*} callback\n */\n public addVersion(\n name: string,\n version: string,\n metadata: Version,\n tag: StringValue,\n callback: Callback\n ): void {\n this._updatePackage(\n name,\n (data, cb: Callback): void => {\n // keep only one readme per package\n data.readme = metadata.readme;\n\n // TODO: lodash remove\n metadata = cleanUpReadme(metadata);\n metadata.contributors = normalizeContributors(metadata.contributors as Author[]);\n\n const hasVersion = data.versions[version] != null;\n if (hasVersion) {\n return cb(ErrorCode.getConflict());\n }\n\n // if uploaded tarball has a different shasum, it's very likely that we have some kind of error\n if (isObject(metadata.dist) && _.isString(metadata.dist.tarball)) {\n const tarball = metadata.dist.tarball.replace(/.*\\//, '');\n\n if (isObject(data._attachments[tarball])) {\n if (\n _.isNil(data._attachments[tarball].shasum) === false &&\n _.isNil(metadata.dist.shasum) === false\n ) {\n if (data._attachments[tarball].shasum != metadata.dist.shasum) {\n const errorMessage = `shasum error, ${data._attachments[tarball].shasum} != ${metadata.dist.shasum}`;\n return cb(ErrorCode.getBadRequest(errorMessage));\n }\n }\n\n const currentDate = new Date().toISOString();\n\n // some old storage do not have this field #740\n if (_.isNil(data.time)) {\n data.time = {};\n }\n\n data.time['modified'] = currentDate;\n\n if ('created' in data.time === false) {\n data.time.created = currentDate;\n }\n\n data.time[version] = currentDate;\n data._attachments[tarball].version = version;\n }\n }\n\n data.versions[version] = metadata;\n tagVersion(data, version, tag);\n\n this.storagePlugin.add(name, (addFailed): void => {\n if (addFailed) {\n return cb(ErrorCode.getBadData(addFailed.message));\n }\n\n cb();\n });\n },\n callback\n );\n }\n\n /**\n * Merge a new list of tags for a local packages with the existing one.\n * @param {*} pkgName\n * @param {*} tags\n * @param {*} callback\n */\n public mergeTags(pkgName: string, tags: MergeTags, callback: Callback): void {\n this._updatePackage(\n pkgName,\n (data, cb): void => {\n for (const tag in tags) {\n // this handle dist-tag rm command\n if (_.isNull(tags[tag])) {\n delete data[DIST_TAGS][tag];\n continue;\n }\n\n if (_.isNil(data.versions[tags[tag]])) {\n return cb(this._getVersionNotFound());\n }\n const version: string = tags[tag];\n tagVersion(data, version, tag);\n }\n cb(null);\n },\n callback\n );\n }\n\n /**\n * Return version not found\n * @return {String}\n * @private\n */\n private _getVersionNotFound(): any {\n return ErrorCode.getNotFound(API_ERROR.VERSION_NOT_EXIST);\n }\n\n /**\n * Return file no available\n * @return {String}\n * @private\n */\n private _getFileNotAvailable(): any {\n return ErrorCode.getNotFound('no such file available');\n }\n\n /**\n * Update the package metadata, tags and attachments (tarballs).\n * Note: Currently supports unpublishing and deprecation.\n * @param {*} name\n * @param {*} incomingPkg\n * @param {*} revision\n * @param {*} callback\n * @return {Function}\n */\n public changePackage(\n name: string,\n incomingPkg: Manifest,\n revision: string | void,\n callback: Callback\n ): void {\n if (!isObject(incomingPkg.versions) || !isObject(incomingPkg[DIST_TAGS])) {\n this.logger.error({ name }, `changePackage bad data for @{name}`);\n return callback(ErrorCode.getBadData());\n }\n debug('changePackage udapting package for %o', name);\n this._updatePackage(\n name,\n (localData: Manifest, cb: Callback): void => {\n for (const version in localData.versions) {\n const incomingVersion = incomingPkg.versions[version];\n if (_.isNil(incomingVersion)) {\n this.logger.info({ name: name, version: version }, 'unpublishing @{name}@@{version}');\n\n // FIXME: I prefer return a new object rather mutate the metadata\n delete localData.versions[version];\n delete localData.time![version];\n\n for (const file in localData._attachments) {\n if (localData._attachments[file].version === version) {\n delete localData._attachments[file].version;\n }\n }\n } else if (Object.prototype.hasOwnProperty.call(incomingVersion, 'deprecated')) {\n const incomingDeprecated = incomingVersion.deprecated;\n if (incomingDeprecated != localData.versions[version].deprecated) {\n if (!incomingDeprecated) {\n this.logger.info(\n { name: name, version: version },\n 'undeprecating @{name}@@{version}'\n );\n delete localData.versions[version].deprecated;\n } else {\n this.logger.info(\n { name: name, version: version },\n 'deprecating @{name}@@{version}'\n );\n localData.versions[version].deprecated = incomingDeprecated;\n }\n localData.time!.modified = new Date().toISOString();\n }\n }\n }\n\n localData[USERS] = incomingPkg[USERS];\n localData[DIST_TAGS] = incomingPkg[DIST_TAGS];\n cb(null);\n },\n function (err): void {\n if (err) {\n return callback(err);\n }\n callback();\n }\n );\n }\n /**\n * Remove a tarball.\n * @param {*} name\n * @param {*} filename\n * @param {*} revision\n * @param {*} callback\n */\n public removeTarball(name: string, filename: string, revision: string, callback: Callback): void {\n assert(validateName(filename));\n\n this._updatePackage(\n name,\n (data, cb): void => {\n if (data._attachments[filename]) {\n delete data._attachments[filename];\n cb(null);\n } else {\n cb(this._getFileNotAvailable());\n }\n },\n (err: any): void => {\n if (err) {\n return callback(err);\n }\n const storage = this._getLocalStorage(name);\n\n if (storage) {\n storage.deletePackage(filename, callback);\n }\n }\n );\n }\n\n /**\n * Add a tarball.\n * @param {String} name\n * @param {String} filename\n * @param {DistFile} distFile distfile record to restore when the manifest\n * lost it (storages written by other verdaccio versions); persisted\n * together with the attachment registration once the upload succeeds\n * @return {Stream}\n */\n public addTarball(name: string, filename: string, distFile?: DistFile) {\n assert(validateName(filename));\n\n let length = 0;\n const shaOneHash = createTarballHash();\n const uploadStream = new UploadTarball({});\n const _transform = uploadStream._transform;\n const storage = this._getLocalStorage(name);\n\n uploadStream.abort = function (): void {};\n uploadStream.done = function (): void {};\n\n uploadStream._transform = function (data, ...args): void {\n shaOneHash.update(data);\n // measure the length for validation reasons\n length += data.length;\n const appliedData = [data, ...args];\n // FIXME: not sure about this approach, tsc complains\n // @ts-ignore\n _transform.apply(uploadStream, appliedData);\n };\n\n if (name === '__proto__') {\n process.nextTick((): void => {\n uploadStream.emit('error', ErrorCode.getForbidden());\n });\n return uploadStream;\n }\n\n if (!storage) {\n process.nextTick((): void => {\n uploadStream.emit('error', \"can't upload this package\");\n });\n return uploadStream;\n }\n\n const writeStream = storage.writeTarball(filename);\n\n writeStream.on('error', (err) => {\n if (err.code === STORAGE.FILE_EXIST_ERROR || err.code === HTTP_STATUS.CONFLICT) {\n uploadStream.emit('error', ErrorCode.getConflict());\n uploadStream.abort();\n } else if (err.code === STORAGE.NO_SUCH_FILE_ERROR || err.code === HTTP_STATUS.NOT_FOUND) {\n // check if package exists to throw an appropriate message\n this.getPackageMetadata(name, function (_err: any): void {\n if (_err) {\n uploadStream.emit('error', _err);\n } else {\n uploadStream.emit('error', err);\n }\n });\n } else {\n uploadStream.emit('error', err);\n }\n });\n\n writeStream.on('open', function (): void {\n // re-emitting open because it's handled in storage.js\n uploadStream.emit('open');\n });\n\n writeStream.on('success', (): void => {\n this._updatePackage(\n name,\n function updater(data, cb): void {\n data._attachments[filename] = {\n shasum: shaOneHash.digest('hex'),\n };\n // restore a distfile record lost by other verdaccio versions,\n // piggybacking on the write that registers the attachment\n if (_.isNil(distFile) === false && _.isNil(data._distfiles[filename])) {\n debug(\n 'restoring missing distfile record for %o served by %o',\n filename,\n distFile.registry\n );\n data._distfiles[filename] = distFile;\n }\n cb(null);\n },\n function (err): void {\n if (err) {\n uploadStream.emit('error', err);\n } else {\n uploadStream.emit('success');\n }\n }\n );\n });\n\n uploadStream.abort = function (): void {\n writeStream.abort();\n };\n\n uploadStream.done = function (): void {\n if (!length) {\n uploadStream.emit('error', ErrorCode.getBadData('refusing to accept zero-length file'));\n writeStream.abort();\n } else {\n writeStream.done();\n }\n };\n\n uploadStream.pipe(writeStream);\n\n return uploadStream;\n }\n\n /**\n * Get a tarball.\n * @param {*} name\n * @param {*} filename\n * @return {ReadTarball}\n */\n public getTarball(name: string, filename: string) {\n assert(validateName(filename));\n\n const storage = this._getLocalStorage(name);\n\n if (_.isNil(storage)) {\n return this._createFailureStreamResponse();\n }\n\n return this._streamSuccessReadTarBall(storage, filename);\n }\n\n /**\n * Return a stream that emits a read failure.\n * @private\n * @return {ReadTarball}\n */\n private _createFailureStreamResponse() {\n const stream = new ReadTarball({});\n\n process.nextTick((): void => {\n stream.emit('error', this._getFileNotAvailable());\n });\n return stream;\n }\n\n /**\n * Return a stream that emits the tarball data\n * @param {Object} storage\n * @param {String} filename\n * @private\n * @return {ReadTarball}\n */\n private _streamSuccessReadTarBall(storage: any, filename: string) {\n const stream = new ReadTarball({});\n const readTarballStream = storage.readTarball(filename);\n const e404 = ErrorCode.getNotFound;\n\n stream.abort = function (): void {\n if (_.isNil(readTarballStream) === false) {\n readTarballStream.abort();\n }\n };\n\n readTarballStream.on('error', function (err) {\n if (err.code === STORAGE.NO_SUCH_FILE_ERROR || err.code === HTTP_STATUS.NOT_FOUND) {\n stream.emit('error', e404('no such file available'));\n } else {\n stream.emit('error', err);\n }\n });\n\n readTarballStream.on('content-length', function (content): void {\n stream.emit('content-length', content);\n });\n\n readTarballStream.on('open', function (): void {\n // re-emitting open because it's handled in storage.js\n stream.emit('open');\n readTarballStream.pipe(stream);\n });\n\n return stream;\n }\n\n /**\n * Retrieve a package by name.\n * @param {*} name\n * @param {*} callback\n * @return {Function}\n */\n public getPackageMetadata(name: string, callback: Callback = (): void => {}): void {\n const storage = this._getLocalStorage(name);\n if (_.isNil(storage)) {\n return callback(ErrorCode.getNotFound());\n }\n\n this._readPackage(name, storage, callback);\n }\n\n public getPackageMetadataAsync(name: string): Promise<Manifest> {\n return new Promise<Manifest>((resolve, reject) => {\n this.getPackageMetadata(name, (err: any, metadata: Manifest) => {\n if (err) {\n return reject(err);\n }\n resolve(metadata);\n });\n });\n }\n\n public updateVersionsAsync(name: string, packageInfo: Manifest): Promise<Manifest> {\n return new Promise<Manifest>((resolve, reject) => {\n this.updateVersions(name, packageInfo, (err: any, result: Manifest) => {\n if (err) {\n return reject(err);\n }\n resolve(result);\n });\n });\n }\n\n /**\n * Search a local package.\n * @param {*} startKey\n * @param {*} options\n * @return {Function}\n */\n public search(startKey: string, options: any) {\n debug('options for search %o', options);\n const stream = new ReadTarball({ objectMode: true });\n\n this._searchEachPackage(\n (item: Manifest, cb: Callback): void => {\n // @ts-ignore\n if (item.time > parseInt(startKey, 10)) {\n this.getPackageMetadata(item.name, (err: any, data: Manifest): void => {\n if (err) {\n return cb(err);\n }\n\n // @ts-ignore\n const time = new Date(item.time).toISOString();\n const result = prepareSearchPackage(data, time);\n if (_.isNil(result) === false) {\n stream.push(result);\n }\n cb(null);\n });\n } else {\n cb(null);\n }\n },\n function onEnd(err): void {\n if (err) {\n stream.emit('error', err);\n return;\n }\n stream.end();\n }\n );\n\n return stream;\n }\n\n /**\n * Retrieve a wrapper that provide access to the package location.\n * @param {Object} pkgName package name.\n * @return {Object}\n */\n private _getLocalStorage(pkgName: string) {\n return this.storagePlugin.getPackageStorage(pkgName);\n }\n\n /**\n * Read a json file from storage.\n * @param {Object} storage\n * @param {Function} callback\n */\n private _readPackage(name: string, storage: any, callback: Callback): void {\n storage.readPackage(name, (err, result): void => {\n if (err) {\n if (err.code === STORAGE.NO_SUCH_FILE_ERROR || err.code === HTTP_STATUS.NOT_FOUND) {\n return callback(ErrorCode.getNotFound());\n }\n return callback(this._internalError(err, STORAGE.PACKAGE_FILE_NAME, 'error reading'));\n }\n\n callback(err, normalizePackage(result));\n });\n }\n\n /**\n * Walks through each package and calls `on_package` on them.\n * @param {*} onPackage\n * @param {*} onEnd\n */\n private _searchEachPackage(onPackage: onSearchPackage, onEnd: onEndSearchPackage): void {\n // save wait whether plugin still do not support search functionality\n if (_.isNil(this.storagePlugin.search)) {\n this.logger.warn('plugin search not implemented yet');\n onEnd();\n } else {\n this.storagePlugin.search(onPackage, onEnd, validateName);\n }\n }\n\n /**\n * Retrieve either a previous created local package or a boilerplate.\n * @param {*} pkgName\n * @param {*} callback\n * @return {Function}\n */\n private _readCreatePackage(pkgName: string, callback: Callback): void {\n const storage: any = this._getLocalStorage(pkgName);\n if (_.isNil(storage)) {\n this._createNewPackage(pkgName, callback);\n return;\n }\n\n storage.readPackage(pkgName, (err, data): void => {\n // TODO: race condition\n if (_.isNil(err) === false) {\n if (err.code === STORAGE.NO_SUCH_FILE_ERROR || err.code === HTTP_STATUS.NOT_FOUND) {\n data = generatePackageTemplate(pkgName);\n } else {\n return callback(this._internalError(err, STORAGE.PACKAGE_FILE_NAME, 'error reading'));\n }\n }\n\n callback(null, normalizePackage(data));\n });\n }\n\n private _createNewPackage(name: string, callback: Callback): Callback {\n return callback(null, normalizePackage(generatePackageTemplate(name)));\n }\n\n /**\n * Handle internal error\n * @param {*} err\n * @param {*} file\n * @param {*} message\n * @return {Object} Error instance\n */\n private _internalError(err: string, file: string, message: string): any {\n this.logger.error({ err: err, file: file }, `${message} @{file}: @{!err.message}`);\n\n return ErrorCode.getInternalError();\n }\n\n /**\n * @param {*} name package name\n * @param {*} updateHandler function(package, cb) - update function\n * @param {*} callback callback that gets invoked after it's all updated\n * @return {Function}\n */\n private _updatePackage(\n name: string,\n updateHandler: StorageUpdateCallback,\n callback: Callback\n ): void {\n const storage = this._getLocalStorage(name);\n\n if (!storage) {\n return callback(ErrorCode.getNotFound());\n }\n\n storage.updatePackage(\n name,\n updateHandler,\n this._writePackage.bind(this),\n normalizePackage,\n callback\n );\n }\n\n /**\n * Update the revision (_rev) string for a package.\n * @param {*} name\n * @param {*} json\n * @param {*} callback\n * @return {Function}\n */\n private _writePackage(name: string, json: Manifest, callback: Callback): void {\n const storage: any = this._getLocalStorage(name);\n if (_.isNil(storage)) {\n return callback();\n }\n storage.savePackage(name, this._setDefaultRevision(json), callback);\n }\n\n private _setDefaultRevision(json: Manifest): Manifest {\n // calculate revision from couch db\n if (_.isString(json._rev) === false) {\n json._rev = STORAGE.DEFAULT_REVISION;\n }\n\n // this is intended in debug mode we do not want modify the store revision\n if (_.isNil(this.config._debug)) {\n json._rev = generateRevision(json._rev);\n }\n\n return json;\n }\n\n private _deleteAttachments(storage: any, attachments: string[], callback: Callback): void {\n debug('[storage/_deleteAttachments] delete attachments total: %o', attachments?.length);\n const unlinkNext = function (cb): void {\n if (_.isEmpty(attachments)) {\n return cb();\n }\n\n const attachment = attachments.shift();\n storage.deletePackage(attachment, function (): void {\n unlinkNext(cb);\n });\n };\n\n unlinkNext(function (): void {\n // try to unlink the directory, but ignore errors because it can fail\n storage.removePackage(function (err): void {\n callback(err);\n });\n });\n }\n\n /**\n * Ensure the dist file remains as the same protocol\n * @param {Object} hash metadata\n * @param {String} upLinkKey registry key\n * @private\n */\n private _updateUplinkToRemoteProtocol(hash: DistFile, upLinkKey: string): void {\n // if we got this information from a known registry,\n // use the same protocol for the tarball\n //\n // see https://github.com/rlidwka/sinopia/issues/166\n const tarballUrl = URL.parse(hash.url);\n const uplinkUrl = URL.parse(this.config.uplinks[upLinkKey].url);\n\n if (tarballUrl !== null && uplinkUrl !== null && uplinkUrl.host === tarballUrl.host) {\n tarballUrl.protocol = uplinkUrl.protocol;\n hash.registry = upLinkKey;\n hash.url = tarballUrl.href;\n }\n }\n\n public async getSecret(config: Config): Promise<string> {\n const secretKey = await this.storagePlugin.getSecret();\n\n return this.storagePlugin.setSecret(config.checkSecretKey(secretKey));\n }\n\n public saveToken(token: Token): Promise<any> {\n if (_.isFunction(this.storagePlugin.saveToken) === false) {\n return Promise.reject(\n ErrorCode.getCode(HTTP_STATUS.SERVICE_UNAVAILABLE, SUPPORT_ERRORS.PLUGIN_MISSING_INTERFACE)\n );\n }\n\n return this.storagePlugin.saveToken(token);\n }\n\n public deleteToken(user: string, tokenKey: string): Promise<any> {\n if (_.isFunction(this.storagePlugin.deleteToken) === false) {\n return Promise.reject(\n ErrorCode.getCode(HTTP_STATUS.SERVICE_UNAVAILABLE, SUPPORT_ERRORS.PLUGIN_MISSING_INTERFACE)\n );\n }\n\n return this.storagePlugin.deleteToken(user, tokenKey);\n }\n\n public readTokens(filter: TokenFilter): Promise<Token[]> {\n if (_.isFunction(this.storagePlugin.readTokens) === false) {\n return Promise.reject(\n ErrorCode.getCode(HTTP_STATUS.SERVICE_UNAVAILABLE, SUPPORT_ERRORS.PLUGIN_MISSING_INTERFACE)\n );\n }\n\n return this.storagePlugin.readTokens(filter);\n }\n}\n\nexport default LocalStorage;\n"],"mappings":"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"}