UNPKG

verdaccio

Version:

A lightweight private npm proxy registry

94 lines (93 loc) • 3.86 kB
import { isLegacyStoragePlugin, wrapLegacyStoragePlugin } from "./legacy-storage-adapter.mjs"; import { head, isNil } from "lodash-es"; import { PLUGIN_CATEGORY, PLUGIN_PREFIX, errorUtils } from "@verdaccio/core"; import createDebug from "debug"; import assert from "node:assert"; import { asyncLoadPlugin } from "@verdaccio/loaders"; import LocalDatabaseModule from "@verdaccio/local-storage"; import { Storage as Storage$1 } from "@verdaccio/store"; //#region src/lib/storage.ts var debug = createDebug("verdaccio:storage"); var LocalDatabase = LocalDatabaseModule.default || LocalDatabaseModule; var storageSanityCheck = (plugin) => typeof plugin?.getPackageStorage !== "undefined"; /** * Drop-in replacement for `@verdaccio/store`'s internal `LocalStorage` that * loads the configured storage plugin exactly like upstream, but wraps a * legacy callback-based plugin in a promisifying adapter so it satisfies the * promise contract the rest of `@verdaccio/store` relies on. * * `@verdaccio/store` only ever calls `init()`, `getSecret()` and * `getStoragePlugin()` on this object, so that is the entire surface we mirror. */ var CompatLocalStorage = class { storagePlugin = null; config; logger; constructor(config, logger) { this.config = config; this.logger = logger.child({ sub: "fs" }); } async init() { if (this.storagePlugin === null) { const loaded = await this.loadStorage(); this.storagePlugin = isLegacyStoragePlugin(loaded) ? wrapLegacyStoragePlugin(loaded, this.logger) : loaded; debug("storage plugin init"); await this.storagePlugin.init(); debug("storage plugin initialized"); } else this.logger.warn("storage plugin has been already initialized"); } getStoragePlugin() { if (this.storagePlugin === null) throw errorUtils.getInternalError("storage plugin is not initialized"); return this.storagePlugin; } async getSecret(config) { const secretKey = await this.storagePlugin.getSecret(); return this.storagePlugin.setSecret(config.checkSecretKey(secretKey)); } async loadStorage() { const Storage = await this.loadStorePlugin(); if (isNil(Storage)) { assert(this.config.storage, "CONFIG: storage path not defined"); debug("no custom storage found, loading default storage @verdaccio/local-storage"); const localStorage = new LocalDatabase(this.config, this.logger); this.logger.info({ name: "@verdaccio/local-storage", pluginCategory: PLUGIN_CATEGORY.STORAGE }, "plugin @{name} successfully loaded (@{pluginCategory})"); return localStorage; } return Storage; } async loadStorePlugin() { const plugins = await asyncLoadPlugin(this.config.store, { config: this.config, logger: this.logger }, storageSanityCheck, true, this.config.server?.pluginPrefix ?? PLUGIN_PREFIX, PLUGIN_CATEGORY.STORAGE); if (plugins.length > 1) this.logger.warn("more than one storage plugins has been detected, multiple storage are not supported, one will be selected automatically"); return head(plugins); } }; /** * `@verdaccio/store` Storage, with one change: it loads the storage plugin * through {@link CompatLocalStorage} so legacy callback plugins keep working. * * The base `init()` only creates its internal `LocalStorage` when * `this.localStorage` is still null; by pre-populating it we reuse the entire * rest of the upstream Storage implementation (including filter loading via * `super.init`) unchanged. */ var Storage = class extends Storage$1 { async init(config) { if (this.localStorage === null) { const localStorage = new CompatLocalStorage(this.config, this.logger); await localStorage.init(); await localStorage.getSecret(config); this.localStorage = localStorage; debug("compat local storage initialized"); } await super.init(config); } }; //#endregion export { Storage, Storage as default }; //# sourceMappingURL=storage.mjs.map