@verdaccio/loaders 8.0.0-next-8.3 → 8.0.0-next-8.4
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.
- package/CHANGELOG.md +6 -0
- package/build/plugin-async-loader.d.ts +4 -8
- package/build/plugin-async-loader.js +15 -13
- package/build/plugin-async-loader.js.map +1 -1
- package/package.json +6 -6
- package/src/plugin-async-loader.ts +14 -16
- package/test/partials/config/valid-plugin-store.yaml +3 -0
- package/test/partials/test-plugin-storage/verdaccio-plugin-store/index.js +7 -0
- package/test/partials/test-plugin-storage/verdaccio-plugin-store/package.json +11 -0
- package/test/plugin_loader_async.spec.ts +16 -25
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import { pluginUtils } from '@verdaccio/core';
|
|
2
|
-
import { Config, Logger } from '@verdaccio/types';
|
|
3
2
|
import { PluginType } from './utils';
|
|
4
|
-
export type Params = {
|
|
5
|
-
config: Config;
|
|
6
|
-
logger: Logger;
|
|
7
|
-
};
|
|
8
3
|
/**
|
|
9
4
|
* The plugin loader find recursively plugins, if one plugin fails is ignored and report the error to the logger.
|
|
10
5
|
*
|
|
@@ -22,10 +17,11 @@ export type Params = {
|
|
|
22
17
|
* The `params` is an object that contains the global configuration and the logger.
|
|
23
18
|
*
|
|
24
19
|
* @param {*} pluginConfigs the custom plugin section
|
|
25
|
-
* @param {*}
|
|
20
|
+
* @param {*} pluginOptions a set of options to initialize the plugin
|
|
26
21
|
* @param {*} sanityCheck callback that check the shape that should fulfill the plugin
|
|
27
22
|
* @param {*} prefix by default is verdaccio but can be override with config.server.pluginPrefix
|
|
23
|
+
* @param {*} pluginCategory the category of the plugin, eg: auth, storage, middleware
|
|
28
24
|
* @return {Array} list of plugins
|
|
29
25
|
*/
|
|
30
|
-
export declare function asyncLoadPlugin<T extends pluginUtils.Plugin<T>>(pluginConfigs: any,
|
|
31
|
-
export declare function executePlugin<T>(plugin: PluginType<T>, pluginConfig: unknown,
|
|
26
|
+
export declare function asyncLoadPlugin<T extends pluginUtils.Plugin<T>>(pluginConfigs: any, pluginOptions: pluginUtils.PluginOptions, sanityCheck: (plugin: PluginType<T>) => boolean, prefix?: string, pluginCategory?: string): Promise<PluginType<T>[]>;
|
|
27
|
+
export declare function executePlugin<T>(plugin: PluginType<T>, pluginConfig: unknown, pluginOptions: pluginUtils.PluginOptions): PluginType<T>;
|
|
@@ -18,6 +18,7 @@ async function isDirectory(pathFolder) {
|
|
|
18
18
|
const stat = await lstat(pathFolder);
|
|
19
19
|
return stat.isDirectory();
|
|
20
20
|
}
|
|
21
|
+
|
|
21
22
|
// type Plugins<T> =
|
|
22
23
|
// | pluginUtils.Auth<T>
|
|
23
24
|
// | pluginUtils.Storage<T>
|
|
@@ -40,20 +41,21 @@ async function isDirectory(pathFolder) {
|
|
|
40
41
|
* The `params` is an object that contains the global configuration and the logger.
|
|
41
42
|
*
|
|
42
43
|
* @param {*} pluginConfigs the custom plugin section
|
|
43
|
-
* @param {*}
|
|
44
|
+
* @param {*} pluginOptions a set of options to initialize the plugin
|
|
44
45
|
* @param {*} sanityCheck callback that check the shape that should fulfill the plugin
|
|
45
46
|
* @param {*} prefix by default is verdaccio but can be override with config.server.pluginPrefix
|
|
47
|
+
* @param {*} pluginCategory the category of the plugin, eg: auth, storage, middleware
|
|
46
48
|
* @return {Array} list of plugins
|
|
47
49
|
*/
|
|
48
|
-
async function asyncLoadPlugin(pluginConfigs = {},
|
|
49
|
-
const logger =
|
|
50
|
+
async function asyncLoadPlugin(pluginConfigs = {}, pluginOptions, sanityCheck, prefix = 'verdaccio', pluginCategory = '') {
|
|
51
|
+
const logger = pluginOptions?.logger;
|
|
50
52
|
const pluginsIds = Object.keys(pluginConfigs);
|
|
51
53
|
const {
|
|
52
54
|
config
|
|
53
|
-
} =
|
|
55
|
+
} = pluginOptions;
|
|
54
56
|
let plugins = [];
|
|
55
57
|
for (let pluginId of pluginsIds) {
|
|
56
|
-
debug('plugin %
|
|
58
|
+
debug('looking for plugin %o', pluginId);
|
|
57
59
|
if (typeof config.plugins === 'string') {
|
|
58
60
|
let pluginsPath = config.plugins;
|
|
59
61
|
debug('plugin path %s', pluginsPath);
|
|
@@ -79,7 +81,7 @@ async function asyncLoadPlugin(pluginConfigs = {}, params, sanityCheck, prefix =
|
|
|
79
81
|
logger.error(a, b);
|
|
80
82
|
});
|
|
81
83
|
if (plugin && (0, _utils.isValid)(plugin)) {
|
|
82
|
-
plugin = executePlugin(plugin, pluginConfigs[pluginId],
|
|
84
|
+
plugin = executePlugin(plugin, pluginConfigs[pluginId], pluginOptions);
|
|
83
85
|
if (!sanityCheck(plugin)) {
|
|
84
86
|
logger.error({
|
|
85
87
|
content: externalFilePlugin
|
|
@@ -104,14 +106,14 @@ async function asyncLoadPlugin(pluginConfigs = {}, params, sanityCheck, prefix =
|
|
|
104
106
|
}
|
|
105
107
|
if (typeof pluginId === 'string') {
|
|
106
108
|
const isScoped = pluginId.startsWith('@') && pluginId.includes('/');
|
|
107
|
-
debug('is scoped plugin %s', isScoped);
|
|
109
|
+
debug('is scoped plugin: %s', isScoped);
|
|
108
110
|
const pluginName = isScoped ? pluginId : `${prefix}-${pluginId}`;
|
|
109
|
-
debug('plugin
|
|
111
|
+
debug('plugin package name %s', pluginName);
|
|
110
112
|
let plugin = (0, _utils.tryLoad)(pluginName, (a, b) => {
|
|
111
113
|
logger.error(a, b);
|
|
112
114
|
});
|
|
113
115
|
if (plugin && (0, _utils.isValid)(plugin)) {
|
|
114
|
-
plugin = executePlugin(plugin, pluginConfigs[pluginId],
|
|
116
|
+
plugin = executePlugin(plugin, pluginConfigs[pluginId], pluginOptions);
|
|
115
117
|
if (!sanityCheck(plugin)) {
|
|
116
118
|
logger.error({
|
|
117
119
|
content: pluginName
|
|
@@ -133,19 +135,19 @@ async function asyncLoadPlugin(pluginConfigs = {}, params, sanityCheck, prefix =
|
|
|
133
135
|
}
|
|
134
136
|
}
|
|
135
137
|
}
|
|
136
|
-
debug('
|
|
138
|
+
debug('%s plugins found: %s', pluginCategory, plugins.length);
|
|
137
139
|
return plugins;
|
|
138
140
|
}
|
|
139
|
-
function executePlugin(plugin, pluginConfig,
|
|
141
|
+
function executePlugin(plugin, pluginConfig, pluginOptions) {
|
|
140
142
|
if ((0, _utils.isES6)(plugin)) {
|
|
141
143
|
debug('plugin is ES6');
|
|
142
144
|
// @ts-expect-error no relevant for the code
|
|
143
145
|
// eslint-disable-next-line new-cap
|
|
144
|
-
return new plugin.default(pluginConfig,
|
|
146
|
+
return new plugin.default(pluginConfig, pluginOptions);
|
|
145
147
|
} else {
|
|
146
148
|
debug('plugin is commonJS');
|
|
147
149
|
// @ts-expect-error improve this type
|
|
148
|
-
return plugin(pluginConfig,
|
|
150
|
+
return plugin(pluginConfig, pluginOptions);
|
|
149
151
|
}
|
|
150
152
|
}
|
|
151
153
|
//# sourceMappingURL=plugin-async-loader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-async-loader.js","names":["_debug","_interopRequireDefault","require","_fs","_path","_utils","e","__esModule","default","debug","buildDebug","lstat","fs","promises","isDirectory","pathFolder","stat","asyncLoadPlugin","pluginConfigs","params","sanityCheck","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","pluginConfig","isES6"],"sources":["../src/plugin-async-loader.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport fs from 'fs';\nimport { dirname, isAbsolute, join, resolve } from 'path';\n\nimport { pluginUtils } from '@verdaccio/core';\nimport { Config, Logger } from '@verdaccio/types';\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\nexport type Params = { config: Config; logger: Logger };\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 {*} params a set of params 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 * @return {Array} list of plugins\n */\nexport async function asyncLoadPlugin<T extends pluginUtils.Plugin<T>>(\n pluginConfigs: any = {},\n params: Params,\n sanityCheck: (plugin: PluginType<T>) => boolean,\n prefix: string = 'verdaccio',\n pluginCategory: string = ''\n): Promise<PluginType<T>[]> {\n const logger = params?.logger;\n const pluginsIds = Object.keys(pluginConfigs);\n const { config } = params;\n let plugins: PluginType<T>[] = [];\n for (let pluginId of pluginsIds) {\n debug('plugin %s', 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(plugin, pluginConfigs[pluginId], params);\n if (!sanityCheck(plugin)) {\n logger.error(\n { content: externalFilePlugin },\n \"@{content} doesn't look like a valid plugin\"\n );\n continue;\n }\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 pkg 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], params);\n if (!sanityCheck(plugin)) {\n logger.error({ content: pluginName }, \"@{content} doesn't look like a valid plugin\");\n continue;\n }\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('plugin found %s', plugins.length);\n return plugins;\n}\n\nexport function executePlugin<T>(\n plugin: PluginType<T>,\n pluginConfig: unknown,\n params: Params\n): PluginType<T> {\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, params) as Plugin;\n } else {\n debug('plugin is commonJS');\n // @ts-expect-error improve this type\n return plugin(pluginConfig, params) 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","_path","_utils","e","__esModule","default","debug","buildDebug","lstat","fs","promises","isDirectory","pathFolder","stat","asyncLoadPlugin","pluginConfigs","pluginOptions","sanityCheck","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","pluginConfig","isES6"],"sources":["../src/plugin-async-loader.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport fs from 'fs';\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\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 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(plugin, pluginConfigs[pluginId], pluginOptions);\n if (!sanityCheck(plugin)) {\n logger.error(\n { content: externalFilePlugin },\n \"@{content} doesn't look like a valid plugin\"\n );\n continue;\n }\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);\n if (!sanityCheck(plugin)) {\n logger.error({ content: pluginName }, \"@{content} doesn't look like a valid plugin\");\n continue;\n }\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('%s plugins found: %s', pluginCategory, plugins.length);\n return plugins;\n}\n\nexport function executePlugin<T>(\n plugin: PluginType<T>,\n pluginConfig: unknown,\n pluginOptions: pluginUtils.PluginOptions\n): PluginType<T> {\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.4",
|
|
4
4
|
"description": "loaders logic",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -17,13 +17,13 @@
|
|
|
17
17
|
"lodash": "4.17.21"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"@verdaccio/logger": "8.0.0-next-8.
|
|
21
|
-
"@verdaccio/core": "8.0.0-next-8.
|
|
22
|
-
"@verdaccio/config": "8.0.0-next-8.
|
|
23
|
-
"@verdaccio/types": "13.0.0-next-8.
|
|
20
|
+
"@verdaccio/logger": "8.0.0-next-8.5",
|
|
21
|
+
"@verdaccio/core": "8.0.0-next-8.5",
|
|
22
|
+
"@verdaccio/config": "8.0.0-next-8.5",
|
|
23
|
+
"@verdaccio/types": "13.0.0-next-8.2",
|
|
24
24
|
"@verdaccio-scope/verdaccio-auth-foo": "0.0.2",
|
|
25
25
|
"customprefix-auth": "2.0.0",
|
|
26
|
-
"verdaccio-auth-memory": "13.0.0-next-8.
|
|
26
|
+
"verdaccio-auth-memory": "13.0.0-next-8.5"
|
|
27
27
|
},
|
|
28
28
|
"homepage": "https://verdaccio.org",
|
|
29
29
|
"keywords": [
|
|
@@ -3,7 +3,6 @@ import fs from 'fs';
|
|
|
3
3
|
import { dirname, isAbsolute, join, resolve } from 'path';
|
|
4
4
|
|
|
5
5
|
import { pluginUtils } from '@verdaccio/core';
|
|
6
|
-
import { Config, Logger } from '@verdaccio/types';
|
|
7
6
|
|
|
8
7
|
import { PluginType, isES6, isValid, tryLoad } from './utils';
|
|
9
8
|
|
|
@@ -16,8 +15,6 @@ async function isDirectory(pathFolder: string) {
|
|
|
16
15
|
return stat.isDirectory();
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
export type Params = { config: Config; logger: Logger };
|
|
20
|
-
|
|
21
18
|
// type Plugins<T> =
|
|
22
19
|
// | pluginUtils.Auth<T>
|
|
23
20
|
// | pluginUtils.Storage<T>
|
|
@@ -40,24 +37,25 @@ export type Params = { config: Config; logger: Logger };
|
|
|
40
37
|
* The `params` is an object that contains the global configuration and the logger.
|
|
41
38
|
*
|
|
42
39
|
* @param {*} pluginConfigs the custom plugin section
|
|
43
|
-
* @param {*}
|
|
40
|
+
* @param {*} pluginOptions a set of options to initialize the plugin
|
|
44
41
|
* @param {*} sanityCheck callback that check the shape that should fulfill the plugin
|
|
45
42
|
* @param {*} prefix by default is verdaccio but can be override with config.server.pluginPrefix
|
|
43
|
+
* @param {*} pluginCategory the category of the plugin, eg: auth, storage, middleware
|
|
46
44
|
* @return {Array} list of plugins
|
|
47
45
|
*/
|
|
48
46
|
export async function asyncLoadPlugin<T extends pluginUtils.Plugin<T>>(
|
|
49
47
|
pluginConfigs: any = {},
|
|
50
|
-
|
|
48
|
+
pluginOptions: pluginUtils.PluginOptions,
|
|
51
49
|
sanityCheck: (plugin: PluginType<T>) => boolean,
|
|
52
50
|
prefix: string = 'verdaccio',
|
|
53
51
|
pluginCategory: string = ''
|
|
54
52
|
): Promise<PluginType<T>[]> {
|
|
55
|
-
const logger =
|
|
53
|
+
const logger = pluginOptions?.logger;
|
|
56
54
|
const pluginsIds = Object.keys(pluginConfigs);
|
|
57
|
-
const { config } =
|
|
55
|
+
const { config } = pluginOptions;
|
|
58
56
|
let plugins: PluginType<T>[] = [];
|
|
59
57
|
for (let pluginId of pluginsIds) {
|
|
60
|
-
debug('plugin %
|
|
58
|
+
debug('looking for plugin %o', pluginId);
|
|
61
59
|
if (typeof config.plugins === 'string') {
|
|
62
60
|
let pluginsPath = config.plugins;
|
|
63
61
|
debug('plugin path %s', pluginsPath);
|
|
@@ -84,7 +82,7 @@ export async function asyncLoadPlugin<T extends pluginUtils.Plugin<T>>(
|
|
|
84
82
|
logger.error(a, b);
|
|
85
83
|
});
|
|
86
84
|
if (plugin && isValid(plugin)) {
|
|
87
|
-
plugin = executePlugin(plugin, pluginConfigs[pluginId],
|
|
85
|
+
plugin = executePlugin(plugin, pluginConfigs[pluginId], pluginOptions);
|
|
88
86
|
if (!sanityCheck(plugin)) {
|
|
89
87
|
logger.error(
|
|
90
88
|
{ content: externalFilePlugin },
|
|
@@ -109,14 +107,14 @@ export async function asyncLoadPlugin<T extends pluginUtils.Plugin<T>>(
|
|
|
109
107
|
|
|
110
108
|
if (typeof pluginId === 'string') {
|
|
111
109
|
const isScoped: boolean = pluginId.startsWith('@') && pluginId.includes('/');
|
|
112
|
-
debug('is scoped plugin %s', isScoped);
|
|
110
|
+
debug('is scoped plugin: %s', isScoped);
|
|
113
111
|
const pluginName = isScoped ? pluginId : `${prefix}-${pluginId}`;
|
|
114
|
-
debug('plugin
|
|
112
|
+
debug('plugin package name %s', pluginName);
|
|
115
113
|
let plugin = tryLoad<T>(pluginName, (a: any, b: any) => {
|
|
116
114
|
logger.error(a, b);
|
|
117
115
|
});
|
|
118
116
|
if (plugin && isValid(plugin)) {
|
|
119
|
-
plugin = executePlugin(plugin, pluginConfigs[pluginId],
|
|
117
|
+
plugin = executePlugin(plugin, pluginConfigs[pluginId], pluginOptions);
|
|
120
118
|
if (!sanityCheck(plugin)) {
|
|
121
119
|
logger.error({ content: pluginName }, "@{content} doesn't look like a valid plugin");
|
|
122
120
|
continue;
|
|
@@ -136,23 +134,23 @@ export async function asyncLoadPlugin<T extends pluginUtils.Plugin<T>>(
|
|
|
136
134
|
}
|
|
137
135
|
}
|
|
138
136
|
}
|
|
139
|
-
debug('
|
|
137
|
+
debug('%s plugins found: %s', pluginCategory, plugins.length);
|
|
140
138
|
return plugins;
|
|
141
139
|
}
|
|
142
140
|
|
|
143
141
|
export function executePlugin<T>(
|
|
144
142
|
plugin: PluginType<T>,
|
|
145
143
|
pluginConfig: unknown,
|
|
146
|
-
|
|
144
|
+
pluginOptions: pluginUtils.PluginOptions
|
|
147
145
|
): PluginType<T> {
|
|
148
146
|
if (isES6(plugin)) {
|
|
149
147
|
debug('plugin is ES6');
|
|
150
148
|
// @ts-expect-error no relevant for the code
|
|
151
149
|
// eslint-disable-next-line new-cap
|
|
152
|
-
return new plugin.default(pluginConfig,
|
|
150
|
+
return new plugin.default(pluginConfig, pluginOptions) as Plugin;
|
|
153
151
|
} else {
|
|
154
152
|
debug('plugin is commonJS');
|
|
155
153
|
// @ts-expect-error improve this type
|
|
156
|
-
return plugin(pluginConfig,
|
|
154
|
+
return plugin(pluginConfig, pluginOptions) as PluginType<T>;
|
|
157
155
|
}
|
|
158
156
|
}
|
|
@@ -15,6 +15,9 @@ function getConfig(file: string) {
|
|
|
15
15
|
const authSanitize = function (plugin) {
|
|
16
16
|
return plugin.authenticate || plugin.allow_access || plugin.allow_publish;
|
|
17
17
|
};
|
|
18
|
+
const storeSanitize = function (plugin) {
|
|
19
|
+
return typeof plugin.getPackageStorage !== 'undefined';
|
|
20
|
+
};
|
|
18
21
|
|
|
19
22
|
const pluginsPartialsFolder = path.join(__dirname, './partials/test-plugin-storage');
|
|
20
23
|
|
|
@@ -31,13 +34,17 @@ describe('plugin loader', () => {
|
|
|
31
34
|
expect(plugins).toHaveLength(1);
|
|
32
35
|
});
|
|
33
36
|
|
|
37
|
+
test('testing storage valid plugin loader', async () => {
|
|
38
|
+
const config = getConfig('valid-plugin-store.yaml');
|
|
39
|
+
config.plugins = pluginsPartialsFolder;
|
|
40
|
+
const plugins = await asyncLoadPlugin(config.store, { config, logger }, storeSanitize);
|
|
41
|
+
|
|
42
|
+
expect(plugins).toHaveLength(1);
|
|
43
|
+
});
|
|
44
|
+
|
|
34
45
|
test('should handle does not exist plugin folder', async () => {
|
|
35
46
|
const config = getConfig('plugins-folder-fake.yaml');
|
|
36
|
-
const plugins = await asyncLoadPlugin(
|
|
37
|
-
config.auth,
|
|
38
|
-
{ logger: logger, config: config },
|
|
39
|
-
authSanitize
|
|
40
|
-
);
|
|
47
|
+
const plugins = await asyncLoadPlugin(config.auth, { config, logger }, authSanitize);
|
|
41
48
|
|
|
42
49
|
expect(plugins).toHaveLength(0);
|
|
43
50
|
});
|
|
@@ -59,11 +66,7 @@ describe('plugin loader', () => {
|
|
|
59
66
|
const config = getConfig('plugins-folder-fake.yaml');
|
|
60
67
|
// force file instead a folder.
|
|
61
68
|
config.plugins = path.join(__dirname, 'just-a-file.js');
|
|
62
|
-
const plugins = await asyncLoadPlugin(
|
|
63
|
-
config.auth,
|
|
64
|
-
{ logger: logger, config: config },
|
|
65
|
-
authSanitize
|
|
66
|
-
);
|
|
69
|
+
const plugins = await asyncLoadPlugin(config.auth, { config, logger }, authSanitize);
|
|
67
70
|
|
|
68
71
|
expect(plugins).toHaveLength(0);
|
|
69
72
|
});
|
|
@@ -72,11 +75,7 @@ describe('plugin loader', () => {
|
|
|
72
75
|
test('should resolve plugin based on relative path', async () => {
|
|
73
76
|
const config = getConfig('relative-plugins.yaml');
|
|
74
77
|
// force file instead a folder.
|
|
75
|
-
const plugins = await asyncLoadPlugin(
|
|
76
|
-
config.auth,
|
|
77
|
-
{ logger: logger, config: config },
|
|
78
|
-
authSanitize
|
|
79
|
-
);
|
|
78
|
+
const plugins = await asyncLoadPlugin(config.auth, { config, logger }, authSanitize);
|
|
80
79
|
|
|
81
80
|
expect(plugins).toHaveLength(1);
|
|
82
81
|
});
|
|
@@ -88,11 +87,7 @@ describe('plugin loader', () => {
|
|
|
88
87
|
// @ts-expect-error
|
|
89
88
|
config.config_path = undefined;
|
|
90
89
|
// force file instead a folder.
|
|
91
|
-
const plugins = await asyncLoadPlugin(
|
|
92
|
-
config.auth,
|
|
93
|
-
{ logger: logger, config: config },
|
|
94
|
-
authSanitize
|
|
95
|
-
);
|
|
90
|
+
const plugins = await asyncLoadPlugin(config.auth, { config, logger }, authSanitize);
|
|
96
91
|
|
|
97
92
|
expect(plugins).toHaveLength(0);
|
|
98
93
|
});
|
|
@@ -103,11 +98,7 @@ describe('plugin loader', () => {
|
|
|
103
98
|
// @ts-expect-error
|
|
104
99
|
config.configPath = undefined;
|
|
105
100
|
// force file instead a folder.
|
|
106
|
-
const plugins = await asyncLoadPlugin(
|
|
107
|
-
config.auth,
|
|
108
|
-
{ logger: logger, config: config },
|
|
109
|
-
authSanitize
|
|
110
|
-
);
|
|
101
|
+
const plugins = await asyncLoadPlugin(config.auth, { config, logger }, authSanitize);
|
|
111
102
|
|
|
112
103
|
expect(plugins).toHaveLength(0);
|
|
113
104
|
});
|