{"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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"}