@verdaccio/loaders 8.0.0-next-8.6 → 8.0.0-next-8.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -10,7 +10,7 @@ import { PluginType } from './utils';
|
|
|
10
10
|
* hosted at /root/plugins
|
|
11
11
|
* - The next step is find at the node_modules or global based on the `require` native algorithm.
|
|
12
12
|
* - If the package is scoped eg: @scope/foo, try to load the package `@scope/foo`
|
|
13
|
-
* - If the package is not scoped, will use the default prefix: verdaccio-foo.
|
|
13
|
+
* - If the package is not scoped, will use the default prefix: verdaccio-foo ("verdaccio-theme-" prefix for theme ui plugins).
|
|
14
14
|
* - If a custom prefix is provided, the verdaccio- is replaced by the config.server.pluginPrefix.
|
|
15
15
|
*
|
|
16
16
|
* The `sanityCheck` is the validation for the required methods to load the plugin, if the validation fails the plugin won't be loaded.
|
|
@@ -9,6 +9,7 @@ var _debug = _interopRequireDefault(require("debug"));
|
|
|
9
9
|
var _fs = _interopRequireDefault(require("fs"));
|
|
10
10
|
var _lodash = _interopRequireDefault(require("lodash"));
|
|
11
11
|
var _path = require("path");
|
|
12
|
+
var _core = require("@verdaccio/core");
|
|
12
13
|
var _utils = require("./utils");
|
|
13
14
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
15
|
const debug = (0, _debug.default)('verdaccio:plugin:loader:async');
|
|
@@ -38,7 +39,7 @@ function mergeConfig(appConfig, pluginConfig) {
|
|
|
38
39
|
* hosted at /root/plugins
|
|
39
40
|
* - The next step is find at the node_modules or global based on the `require` native algorithm.
|
|
40
41
|
* - If the package is scoped eg: @scope/foo, try to load the package `@scope/foo`
|
|
41
|
-
* - If the package is not scoped, will use the default prefix: verdaccio-foo.
|
|
42
|
+
* - If the package is not scoped, will use the default prefix: verdaccio-foo ("verdaccio-theme-" prefix for theme ui plugins).
|
|
42
43
|
* - If a custom prefix is provided, the verdaccio- is replaced by the config.server.pluginPrefix.
|
|
43
44
|
*
|
|
44
45
|
* The `sanityCheck` is the validation for the required methods to load the plugin, if the validation fails the plugin won't be loaded.
|
|
@@ -51,7 +52,7 @@ function mergeConfig(appConfig, pluginConfig) {
|
|
|
51
52
|
* @param {*} pluginCategory the category of the plugin, eg: auth, storage, middleware
|
|
52
53
|
* @return {Array} list of plugins
|
|
53
54
|
*/
|
|
54
|
-
async function asyncLoadPlugin(pluginConfigs = {}, pluginOptions, sanityCheck, legacyMergeConfigs = false, prefix =
|
|
55
|
+
async function asyncLoadPlugin(pluginConfigs = {}, pluginOptions, sanityCheck, legacyMergeConfigs = false, prefix = _core.PLUGIN_PREFIX, pluginCategory = 'unknown') {
|
|
55
56
|
const logger = pluginOptions?.logger;
|
|
56
57
|
const pluginsIds = Object.keys(pluginConfigs);
|
|
57
58
|
const {
|
|
@@ -60,6 +61,12 @@ async function asyncLoadPlugin(pluginConfigs = {}, pluginOptions, sanityCheck, l
|
|
|
60
61
|
let plugins = [];
|
|
61
62
|
for (let pluginId of pluginsIds) {
|
|
62
63
|
debug('>>> looking for plugin %o', pluginId);
|
|
64
|
+
const isScoped = pluginId.startsWith('@') && pluginId.includes('/');
|
|
65
|
+
debug('is scoped plugin: %s', isScoped);
|
|
66
|
+
const pluginName = isScoped ? pluginId : `${prefix}-${pluginId}`;
|
|
67
|
+
debug('plugin package name %s', pluginName);
|
|
68
|
+
|
|
69
|
+
// Try to load the plugin from the config.plugins path
|
|
63
70
|
if (typeof config.plugins === 'string') {
|
|
64
71
|
let pluginsPath = config.plugins;
|
|
65
72
|
debug('plugin path %s', pluginsPath);
|
|
@@ -80,10 +87,11 @@ async function asyncLoadPlugin(pluginConfigs = {}, pluginOptions, sanityCheck, l
|
|
|
80
87
|
try {
|
|
81
88
|
await isDirectory(pluginsPath);
|
|
82
89
|
const pluginDir = pluginsPath;
|
|
83
|
-
const externalFilePlugin = (0, _path.resolve)(pluginDir,
|
|
90
|
+
const externalFilePlugin = (0, _path.resolve)(pluginDir, pluginName);
|
|
84
91
|
let plugin = (0, _utils.tryLoad)(externalFilePlugin, (a, b) => {
|
|
85
92
|
logger.error(a, b);
|
|
86
93
|
});
|
|
94
|
+
debug('external plugin %o', plugin);
|
|
87
95
|
if (plugin && (0, _utils.isValid)(plugin)) {
|
|
88
96
|
plugin = executePlugin(plugin, pluginConfigs[pluginId], pluginOptions, legacyMergeConfigs);
|
|
89
97
|
if (!sanityCheck(plugin)) {
|
|
@@ -95,25 +103,22 @@ async function asyncLoadPlugin(pluginConfigs = {}, pluginOptions, sanityCheck, l
|
|
|
95
103
|
debug('>>> plugin is running and passed sanity check');
|
|
96
104
|
plugins.push(plugin);
|
|
97
105
|
logger.info({
|
|
98
|
-
|
|
99
|
-
pluginId,
|
|
106
|
+
pluginName,
|
|
100
107
|
pluginCategory
|
|
101
|
-
}, 'plugin @{
|
|
108
|
+
}, 'plugin @{pluginName} successfully loaded (@{pluginCategory})');
|
|
102
109
|
continue;
|
|
103
110
|
}
|
|
104
111
|
} catch (err) {
|
|
105
112
|
logger.warn({
|
|
106
113
|
err: err.message,
|
|
107
114
|
pluginsPath,
|
|
108
|
-
|
|
109
|
-
}, '@{err} on loading plugins at @{pluginsPath} for @{
|
|
115
|
+
pluginName
|
|
116
|
+
}, '@{err} on loading plugins at @{pluginsPath} for @{pluginName}');
|
|
110
117
|
}
|
|
111
118
|
}
|
|
119
|
+
|
|
120
|
+
// Try to load the plugin from the node_modules or global based on the `require` native algorithm
|
|
112
121
|
if (typeof pluginId === 'string') {
|
|
113
|
-
const isScoped = pluginId.startsWith('@') && pluginId.includes('/');
|
|
114
|
-
debug('is scoped plugin: %s', isScoped);
|
|
115
|
-
const pluginName = isScoped ? pluginId : `${prefix}-${pluginId}`;
|
|
116
|
-
debug('plugin package name %s', pluginName);
|
|
117
122
|
let plugin = (0, _utils.tryLoad)(pluginName, (a, b) => {
|
|
118
123
|
logger.error(a, b);
|
|
119
124
|
});
|
|
@@ -121,17 +126,16 @@ async function asyncLoadPlugin(pluginConfigs = {}, pluginOptions, sanityCheck, l
|
|
|
121
126
|
plugin = executePlugin(plugin, pluginConfigs[pluginId], pluginOptions, legacyMergeConfigs);
|
|
122
127
|
if (!sanityCheck(plugin)) {
|
|
123
128
|
logger.error({
|
|
124
|
-
|
|
125
|
-
}, "@{
|
|
129
|
+
pluginName
|
|
130
|
+
}, "@{pluginName} doesn't look like a valid plugin");
|
|
126
131
|
continue;
|
|
127
132
|
}
|
|
128
133
|
debug('>>> plugin is running and passed sanity check');
|
|
129
134
|
plugins.push(plugin);
|
|
130
135
|
logger.info({
|
|
131
|
-
|
|
132
|
-
pluginId,
|
|
136
|
+
pluginName,
|
|
133
137
|
pluginCategory
|
|
134
|
-
}, 'plugin @{
|
|
138
|
+
}, 'plugin @{pluginName} successfully loaded (@{pluginCategory})');
|
|
135
139
|
continue;
|
|
136
140
|
} else {
|
|
137
141
|
logger.error({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-async-loader.js","names":["_debug","_interopRequireDefault","require","_fs","_lodash","_path","_utils","e","__esModule","default","debug","buildDebug","lstat","fs","promises","isDirectory","pathFolder","stat","mergeConfig","appConfig","pluginConfig","_","merge","asyncLoadPlugin","pluginConfigs","pluginOptions","sanityCheck","legacyMergeConfigs","prefix","pluginCategory","logger","pluginsIds","Object","keys","config","plugins","pluginId","pluginsPath","isAbsolute","config_path","configPath","error","resolve","join","dirname","path","pluginDir","externalFilePlugin","plugin","tryLoad","a","b","isValid","executePlugin","content","push","info","err","warn","message","isScoped","startsWith","includes","pluginName","length","originalConfig","isES6"],"sources":["../src/plugin-async-loader.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport fs from 'fs';\nimport _ from 'lodash';\nimport { dirname, isAbsolute, join, resolve } from 'path';\n\nimport { pluginUtils } from '@verdaccio/core';\n\nimport { PluginType, isES6, isValid, tryLoad } from './utils';\n\nconst debug = buildDebug('verdaccio:plugin:loader:async');\n\nconst { lstat } = fs.promises ? fs.promises : require('fs/promises');\n\nasync function isDirectory(pathFolder: string) {\n const stat = await lstat(pathFolder);\n return stat.isDirectory();\n}\n\nfunction mergeConfig(appConfig: unknown, pluginConfig: unknown) {\n return _.merge({}, appConfig, pluginConfig);\n}\n\n// type Plugins<T> =\n// | pluginUtils.Auth<T>\n// | pluginUtils.Storage<T>\n// | pluginUtils.ExpressMiddleware<T, unknown, unknown>;\n\n/**\n * The plugin loader find recursively plugins, if one plugin fails is ignored and report the error to the logger.\n *\n * The loader follows the order:\n * - If the at the `config.yaml` file the `plugins: ./plugins` is defined\n * - If is absolute will use the provided path\n * - If is relative, will use the base path of the config file. eg: /root/config.yaml the plugins folder should be\n * hosted at /root/plugins\n * - The next step is find at the node_modules or global based on the `require` native algorithm.\n * - If the package is scoped eg: @scope/foo, try to load the package `@scope/foo`\n * - If the package is not scoped, will use the default prefix: verdaccio-foo.\n * - If a custom prefix is provided, the verdaccio- is replaced by the config.server.pluginPrefix.\n *\n * The `sanityCheck` is the validation for the required methods to load the plugin, if the validation fails the plugin won't be loaded.\n * The `params` is an object that contains the global configuration and the logger.\n *\n * @param {*} pluginConfigs the custom plugin section\n * @param {*} pluginOptions a set of options to initialize the plugin\n * @param {*} sanityCheck callback that check the shape that should fulfill the plugin\n * @param {*} prefix by default is verdaccio but can be override with config.server.pluginPrefix\n * @param {*} pluginCategory the category of the plugin, eg: auth, storage, middleware\n * @return {Array} list of plugins\n */\nexport async function asyncLoadPlugin<T extends pluginUtils.Plugin<T>>(\n pluginConfigs: any = {},\n pluginOptions: pluginUtils.PluginOptions,\n sanityCheck: (plugin: PluginType<T>) => boolean,\n legacyMergeConfigs: boolean = false,\n prefix: string = 'verdaccio',\n pluginCategory: string = ''\n): Promise<PluginType<T>[]> {\n const logger = pluginOptions?.logger;\n const pluginsIds = Object.keys(pluginConfigs);\n const { config } = pluginOptions;\n let plugins: PluginType<T>[] = [];\n for (let pluginId of pluginsIds) {\n debug('>>> looking for plugin %o', pluginId);\n if (typeof config.plugins === 'string') {\n let pluginsPath = config.plugins;\n debug('plugin path %s', pluginsPath);\n if (!isAbsolute(pluginsPath)) {\n if (typeof config.config_path === 'string' && !config.configPath) {\n logger.error(\n 'configPath is missing and the legacy config.config_path is not available for loading plugins'\n );\n }\n\n if (!config.configPath) {\n logger.error('config path property is required for loading plugins');\n continue;\n }\n pluginsPath = resolve(join(dirname(config.configPath), pluginsPath));\n }\n logger.debug({ path: pluginsPath }, 'plugins folder defined, loading plugins from @{path} ');\n // throws if is not a directory\n try {\n await isDirectory(pluginsPath);\n const pluginDir = pluginsPath;\n const externalFilePlugin = resolve(pluginDir, `${prefix}-${pluginId}`);\n let plugin = tryLoad<T>(externalFilePlugin, (a: any, b: any) => {\n logger.error(a, b);\n });\n if (plugin && isValid(plugin)) {\n plugin = executePlugin(\n plugin,\n pluginConfigs[pluginId],\n pluginOptions,\n legacyMergeConfigs\n );\n if (!sanityCheck(plugin)) {\n logger.error(\n { content: externalFilePlugin },\n \"@{content} doesn't look like a valid plugin\"\n );\n continue;\n }\n debug('>>> plugin is running and passed sanity check');\n plugins.push(plugin);\n logger.info(\n { prefix, pluginId, pluginCategory },\n 'plugin @{prefix}-@{pluginId} successfully loaded (@{pluginCategory})'\n );\n continue;\n }\n } catch (err: any) {\n logger.warn(\n { err: err.message, pluginsPath, pluginId },\n '@{err} on loading plugins at @{pluginsPath} for @{pluginId}'\n );\n }\n }\n\n if (typeof pluginId === 'string') {\n const isScoped: boolean = pluginId.startsWith('@') && pluginId.includes('/');\n debug('is scoped plugin: %s', isScoped);\n const pluginName = isScoped ? pluginId : `${prefix}-${pluginId}`;\n debug('plugin package name %s', pluginName);\n let plugin = tryLoad<T>(pluginName, (a: any, b: any) => {\n logger.error(a, b);\n });\n if (plugin && isValid(plugin)) {\n plugin = executePlugin(plugin, pluginConfigs[pluginId], pluginOptions, legacyMergeConfigs);\n if (!sanityCheck(plugin)) {\n logger.error({ content: pluginName }, \"@{content} doesn't look like a valid plugin\");\n continue;\n }\n debug('>>> plugin is running and passed sanity check');\n plugins.push(plugin);\n logger.info(\n { prefix, pluginId, pluginCategory },\n 'plugin @{prefix}-@{pluginId} successfully loaded (@{pluginCategory})'\n );\n continue;\n } else {\n logger.error(\n { pluginName },\n 'package not found, try to install @{pluginName} with a package manager'\n );\n continue;\n }\n }\n }\n debug('%o plugins found: %o', pluginCategory, plugins.length);\n return plugins;\n}\n\nexport function executePlugin<T>(\n plugin: PluginType<T>,\n pluginConfig: unknown,\n pluginOptions: pluginUtils.PluginOptions,\n legacyMergeConfigs: boolean = false\n): PluginType<T> {\n // this is a legacy support for plugins that are not using the new API\n if (legacyMergeConfigs) {\n debug('>>> plugin merge config enabled');\n let originalConfig = pluginOptions.config;\n pluginConfig = mergeConfig(originalConfig, pluginConfig);\n }\n if (isES6(plugin)) {\n debug('plugin is ES6');\n // @ts-expect-error no relevant for the code\n // eslint-disable-next-line new-cap\n return new plugin.default(pluginConfig, pluginOptions) as Plugin;\n } else {\n debug('plugin is commonJS');\n // @ts-expect-error improve this type\n return plugin(pluginConfig, pluginOptions) as PluginType<T>;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"plugin-async-loader.js","names":["_debug","_interopRequireDefault","require","_fs","_lodash","_path","_core","_utils","e","__esModule","default","debug","buildDebug","lstat","fs","promises","isDirectory","pathFolder","stat","mergeConfig","appConfig","pluginConfig","_","merge","asyncLoadPlugin","pluginConfigs","pluginOptions","sanityCheck","legacyMergeConfigs","prefix","PLUGIN_PREFIX","pluginCategory","logger","pluginsIds","Object","keys","config","plugins","pluginId","isScoped","startsWith","includes","pluginName","pluginsPath","isAbsolute","config_path","configPath","error","resolve","join","dirname","path","pluginDir","externalFilePlugin","plugin","tryLoad","a","b","isValid","executePlugin","content","push","info","err","warn","message","length","originalConfig","isES6"],"sources":["../src/plugin-async-loader.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport fs from 'fs';\nimport _ from 'lodash';\nimport { dirname, isAbsolute, join, resolve } from 'path';\n\nimport { PLUGIN_PREFIX, pluginUtils } from '@verdaccio/core';\n\nimport { PluginType, isES6, isValid, tryLoad } from './utils';\n\nconst debug = buildDebug('verdaccio:plugin:loader:async');\n\nconst { lstat } = fs.promises ? fs.promises : require('fs/promises');\n\nasync function isDirectory(pathFolder: string) {\n const stat = await lstat(pathFolder);\n return stat.isDirectory();\n}\n\nfunction mergeConfig(appConfig: unknown, pluginConfig: unknown) {\n return _.merge({}, appConfig, pluginConfig);\n}\n\n// type Plugins<T> =\n// | pluginUtils.Auth<T>\n// | pluginUtils.Storage<T>\n// | pluginUtils.ExpressMiddleware<T, unknown, unknown>;\n\n/**\n * The plugin loader find recursively plugins, if one plugin fails is ignored and report the error to the logger.\n *\n * The loader follows the order:\n * - If the at the `config.yaml` file the `plugins: ./plugins` is defined\n * - If is absolute will use the provided path\n * - If is relative, will use the base path of the config file. eg: /root/config.yaml the plugins folder should be\n * hosted at /root/plugins\n * - The next step is find at the node_modules or global based on the `require` native algorithm.\n * - If the package is scoped eg: @scope/foo, try to load the package `@scope/foo`\n * - If the package is not scoped, will use the default prefix: verdaccio-foo (\"verdaccio-theme-\" prefix for theme ui plugins).\n * - If a custom prefix is provided, the verdaccio- is replaced by the config.server.pluginPrefix.\n *\n * The `sanityCheck` is the validation for the required methods to load the plugin, if the validation fails the plugin won't be loaded.\n * The `params` is an object that contains the global configuration and the logger.\n *\n * @param {*} pluginConfigs the custom plugin section\n * @param {*} pluginOptions a set of options to initialize the plugin\n * @param {*} sanityCheck callback that check the shape that should fulfill the plugin\n * @param {*} prefix by default is verdaccio but can be override with config.server.pluginPrefix\n * @param {*} pluginCategory the category of the plugin, eg: auth, storage, middleware\n * @return {Array} list of plugins\n */\nexport async function asyncLoadPlugin<T extends pluginUtils.Plugin<T>>(\n pluginConfigs: any = {},\n pluginOptions: pluginUtils.PluginOptions,\n sanityCheck: (plugin: PluginType<T>) => boolean,\n legacyMergeConfigs: boolean = false,\n prefix: string = PLUGIN_PREFIX,\n pluginCategory: string = 'unknown'\n): Promise<PluginType<T>[]> {\n const logger = pluginOptions?.logger;\n const pluginsIds = Object.keys(pluginConfigs);\n const { config } = pluginOptions;\n let plugins: PluginType<T>[] = [];\n for (let pluginId of pluginsIds) {\n debug('>>> looking for plugin %o', pluginId);\n\n const isScoped: boolean = pluginId.startsWith('@') && pluginId.includes('/');\n debug('is scoped plugin: %s', isScoped);\n const pluginName = isScoped ? pluginId : `${prefix}-${pluginId}`;\n debug('plugin package name %s', pluginName);\n\n // Try to load the plugin from the config.plugins path\n if (typeof config.plugins === 'string') {\n let pluginsPath = config.plugins;\n debug('plugin path %s', pluginsPath);\n if (!isAbsolute(pluginsPath)) {\n if (typeof config.config_path === 'string' && !config.configPath) {\n logger.error(\n 'configPath is missing and the legacy config.config_path is not available for loading plugins'\n );\n }\n\n if (!config.configPath) {\n logger.error('config path property is required for loading plugins');\n continue;\n }\n pluginsPath = resolve(join(dirname(config.configPath), pluginsPath));\n }\n logger.debug({ path: pluginsPath }, 'plugins folder defined, loading plugins from @{path} ');\n // throws if is not a directory\n try {\n await isDirectory(pluginsPath);\n const pluginDir = pluginsPath;\n const externalFilePlugin = resolve(pluginDir, pluginName);\n let plugin = tryLoad<T>(externalFilePlugin, (a: any, b: any) => {\n logger.error(a, b);\n });\n debug('external plugin %o', plugin);\n if (plugin && isValid(plugin)) {\n plugin = executePlugin(\n plugin,\n pluginConfigs[pluginId],\n pluginOptions,\n legacyMergeConfigs\n );\n if (!sanityCheck(plugin)) {\n logger.error(\n { content: externalFilePlugin },\n \"@{content} doesn't look like a valid plugin\"\n );\n continue;\n }\n debug('>>> plugin is running and passed sanity check');\n plugins.push(plugin);\n logger.info(\n { pluginName, pluginCategory },\n 'plugin @{pluginName} successfully loaded (@{pluginCategory})'\n );\n continue;\n }\n } catch (err: any) {\n logger.warn(\n { err: err.message, pluginsPath, pluginName },\n '@{err} on loading plugins at @{pluginsPath} for @{pluginName}'\n );\n }\n }\n\n // Try to load the plugin from the node_modules or global based on the `require` native algorithm\n if (typeof pluginId === 'string') {\n let plugin = tryLoad<T>(pluginName, (a: any, b: any) => {\n logger.error(a, b);\n });\n if (plugin && isValid(plugin)) {\n plugin = executePlugin(plugin, pluginConfigs[pluginId], pluginOptions, legacyMergeConfigs);\n if (!sanityCheck(plugin)) {\n logger.error({ pluginName }, \"@{pluginName} doesn't look like a valid plugin\");\n continue;\n }\n debug('>>> plugin is running and passed sanity check');\n plugins.push(plugin);\n logger.info(\n { pluginName, pluginCategory },\n 'plugin @{pluginName} successfully loaded (@{pluginCategory})'\n );\n continue;\n } else {\n logger.error(\n { pluginName },\n 'package not found, try to install @{pluginName} with a package manager'\n );\n continue;\n }\n }\n }\n debug('%o plugins found: %o', pluginCategory, plugins.length);\n return plugins;\n}\n\nexport function executePlugin<T>(\n plugin: PluginType<T>,\n pluginConfig: unknown,\n pluginOptions: pluginUtils.PluginOptions,\n legacyMergeConfigs: boolean = false\n): PluginType<T> {\n // this is a legacy support for plugins that are not using the new API\n if (legacyMergeConfigs) {\n debug('>>> plugin merge config enabled');\n let originalConfig = pluginOptions.config;\n pluginConfig = mergeConfig(originalConfig, pluginConfig);\n }\n if (isES6(plugin)) {\n debug('plugin is ES6');\n // @ts-expect-error no relevant for the code\n // eslint-disable-next-line new-cap\n return new plugin.default(pluginConfig, pluginOptions) as Plugin;\n } else {\n debug('plugin is commonJS');\n // @ts-expect-error improve this type\n return plugin(pluginConfig, pluginOptions) as PluginType<T>;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verdaccio/loaders",
|
|
3
|
-
"version": "8.0.0-next-8.
|
|
3
|
+
"version": "8.0.0-next-8.7",
|
|
4
4
|
"description": "Verdaccio Loader Logic",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -21,13 +21,13 @@
|
|
|
21
21
|
"lodash": "4.17.21"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@verdaccio/logger": "8.0.0-next-8.
|
|
25
|
-
"@verdaccio/core": "8.0.0-next-8.
|
|
26
|
-
"@verdaccio/config": "8.0.0-next-8.
|
|
27
|
-
"@verdaccio/types": "13.0.0-next-8.
|
|
24
|
+
"@verdaccio/logger": "8.0.0-next-8.16",
|
|
25
|
+
"@verdaccio/core": "8.0.0-next-8.16",
|
|
26
|
+
"@verdaccio/config": "8.0.0-next-8.16",
|
|
27
|
+
"@verdaccio/types": "13.0.0-next-8.6",
|
|
28
28
|
"@verdaccio-scope/verdaccio-auth-foo": "0.0.2",
|
|
29
29
|
"customprefix-auth": "2.0.0",
|
|
30
|
-
"verdaccio-auth-memory": "13.0.0-next-8.
|
|
30
|
+
"verdaccio-auth-memory": "13.0.0-next-8.16"
|
|
31
31
|
},
|
|
32
32
|
"homepage": "https://verdaccio.org",
|
|
33
33
|
"keywords": [
|