mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-16 21:56:25 -05:00
feat: run server init as promise (#3210)
* feat: run server init as promise * chore: format * fix: format * fix: format * fix: restore files * fix: restore files * fix: disable steps * fix: init log on cli * fix: init log on cli * fix: init log on cli * fix: init log on cli * fix: init log on cli * fix: init log on cli * fix: init log on cli * fix: init log on cli * fix: init log on cli * fix: init log on cli * fix: init log on cli
This commit is contained in:
parent
4f59bb8f20
commit
42194c7302
18 changed files with 314 additions and 39 deletions
|
@ -8,7 +8,7 @@ on:
|
||||||
name: 'E2E Gatsby.js CLI with verdaccio'
|
name: 'E2E Gatsby.js CLI with verdaccio'
|
||||||
jobs:
|
jobs:
|
||||||
npm6:
|
npm6:
|
||||||
name: 'npm:gatsby example'
|
name: 'npm6:gatsby example'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
@ -32,7 +32,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
source scripts/e2e-setup-ci.sh
|
source scripts/e2e-setup-ci.sh
|
||||||
echo "registry=http://localhost:4873
|
echo "registry=http://localhost:4873
|
||||||
loglevel="silent"
|
loglevel="warn"
|
||||||
fetch-retries=10
|
fetch-retries=10
|
||||||
fetch-retry-factor=2
|
fetch-retry-factor=2
|
||||||
fetch-retry-mintimeout=10000
|
fetch-retry-mintimeout=10000
|
||||||
|
|
16
.pnp.js
generated
16
.pnp.js
generated
|
@ -84,7 +84,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||||
["@verdaccio/local-storage", "npm:10.2.1"],
|
["@verdaccio/local-storage", "npm:10.2.1"],
|
||||||
["@verdaccio/readme", "npm:10.3.4"],
|
["@verdaccio/readme", "npm:10.3.4"],
|
||||||
["@verdaccio/streams", "npm:10.2.0"],
|
["@verdaccio/streams", "npm:10.2.0"],
|
||||||
["@verdaccio/types", "npm:10.3.0"],
|
["@verdaccio/types", "npm:10.4.2"],
|
||||||
["@verdaccio/ui-theme", "npm:6.0.0-6-next.24"],
|
["@verdaccio/ui-theme", "npm:6.0.0-6-next.24"],
|
||||||
["JSONStream", "npm:1.3.5"],
|
["JSONStream", "npm:1.3.5"],
|
||||||
["all-contributors-cli", "npm:6.20.0"],
|
["all-contributors-cli", "npm:6.20.0"],
|
||||||
|
@ -5865,10 +5865,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||||
}]
|
}]
|
||||||
]],
|
]],
|
||||||
["@verdaccio/types", [
|
["@verdaccio/types", [
|
||||||
["npm:10.3.0", {
|
["npm:10.4.2", {
|
||||||
"packageLocation": "./.yarn/cache/@verdaccio-types-npm-10.3.0-a7d2915e19-307c485a51.zip/node_modules/@verdaccio/types/",
|
"packageLocation": "./.yarn/cache/@verdaccio-types-npm-10.4.2-78b2370b99-f4f02e1496.zip/node_modules/@verdaccio/types/",
|
||||||
"packageDependencies": [
|
"packageDependencies": [
|
||||||
["@verdaccio/types", "npm:10.3.0"]
|
["@verdaccio/types", "npm:10.4.2"]
|
||||||
],
|
],
|
||||||
"linkType": "HARD",
|
"linkType": "HARD",
|
||||||
}]
|
}]
|
||||||
|
@ -8090,14 +8090,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||||
]],
|
]],
|
||||||
["core-js", [
|
["core-js", [
|
||||||
["npm:2.6.9", {
|
["npm:2.6.9", {
|
||||||
"packageLocation": "./.yarn/cache/core-js-npm-2.6.9-f821bf686c-00c30207eb.zip/node_modules/core-js/",
|
"packageLocation": "./.yarn/unplugged/core-js-npm-2.6.9-f821bf686c/node_modules/core-js/",
|
||||||
"packageDependencies": [
|
"packageDependencies": [
|
||||||
["core-js", "npm:2.6.9"]
|
["core-js", "npm:2.6.9"]
|
||||||
],
|
],
|
||||||
"linkType": "HARD",
|
"linkType": "HARD",
|
||||||
}],
|
}],
|
||||||
["npm:3.22.4", {
|
["npm:3.22.4", {
|
||||||
"packageLocation": "./.yarn/cache/core-js-npm-3.22.4-4469b89edf-1305b2b9c1.zip/node_modules/core-js/",
|
"packageLocation": "./.yarn/unplugged/core-js-npm-3.22.4-4469b89edf/node_modules/core-js/",
|
||||||
"packageDependencies": [
|
"packageDependencies": [
|
||||||
["core-js", "npm:3.22.4"]
|
["core-js", "npm:3.22.4"]
|
||||||
],
|
],
|
||||||
|
@ -15230,7 +15230,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||||
]],
|
]],
|
||||||
["puppeteer", [
|
["puppeteer", [
|
||||||
["npm:5.5.0", {
|
["npm:5.5.0", {
|
||||||
"packageLocation": "./.yarn/cache/puppeteer-npm-5.5.0-bba75ba998-08ba8a7da5.zip/node_modules/puppeteer/",
|
"packageLocation": "./.yarn/unplugged/puppeteer-npm-5.5.0-bba75ba998/node_modules/puppeteer/",
|
||||||
"packageDependencies": [
|
"packageDependencies": [
|
||||||
["puppeteer", "npm:5.5.0"],
|
["puppeteer", "npm:5.5.0"],
|
||||||
["debug", "virtual:fada3bd8ad326a7c196d0c24aae1d5410b84126805d4b297cac3abf549e077c61a437968e49905247d38e2ca430b4cee29c78b779ec928550ea7a1cdf2adc3c1#npm:4.1.1"],
|
["debug", "virtual:fada3bd8ad326a7c196d0c24aae1d5410b84126805d4b297cac3abf549e077c61a437968e49905247d38e2ca430b4cee29c78b779ec928550ea7a1cdf2adc3c1#npm:4.1.1"],
|
||||||
|
@ -18010,7 +18010,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||||
["@verdaccio/local-storage", "npm:10.2.1"],
|
["@verdaccio/local-storage", "npm:10.2.1"],
|
||||||
["@verdaccio/readme", "npm:10.3.4"],
|
["@verdaccio/readme", "npm:10.3.4"],
|
||||||
["@verdaccio/streams", "npm:10.2.0"],
|
["@verdaccio/streams", "npm:10.2.0"],
|
||||||
["@verdaccio/types", "npm:10.3.0"],
|
["@verdaccio/types", "npm:10.4.2"],
|
||||||
["@verdaccio/ui-theme", "npm:6.0.0-6-next.24"],
|
["@verdaccio/ui-theme", "npm:6.0.0-6-next.24"],
|
||||||
["JSONStream", "npm:1.3.5"],
|
["JSONStream", "npm:1.3.5"],
|
||||||
["all-contributors-cli", "npm:6.20.0"],
|
["all-contributors-cli", "npm:6.20.0"],
|
||||||
|
|
Binary file not shown.
BIN
.yarn/cache/@verdaccio-types-npm-10.4.2-78b2370b99-f4f02e1496.zip
vendored
Normal file
BIN
.yarn/cache/@verdaccio-types-npm-10.4.2-78b2370b99-f4f02e1496.zip
vendored
Normal file
Binary file not shown.
6
debug/bootstrap-runserver.js
vendored
Normal file
6
debug/bootstrap-runserver.js
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
// this file aims to help local debugging with hot transpilation
|
||||||
|
// it requires BABEL_ENV=registry set as env variable
|
||||||
|
require('@babel/register')({
|
||||||
|
extensions: ['.ts', '.js'],
|
||||||
|
});
|
||||||
|
require('./run-server');
|
9
debug/run-server.ts
Normal file
9
debug/run-server.ts
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
const { runServer } = require('../src');
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const app = await runServer(); // default configuration
|
||||||
|
app.listen(4000, () => {
|
||||||
|
console.log('listening on port 4000');
|
||||||
|
});
|
||||||
|
})();
|
|
@ -105,7 +105,7 @@
|
||||||
"@typescript-eslint/eslint-plugin": "4.33.0",
|
"@typescript-eslint/eslint-plugin": "4.33.0",
|
||||||
"@typescript-eslint/parser": "4.33.0",
|
"@typescript-eslint/parser": "4.33.0",
|
||||||
"@verdaccio/eslint-config": "^8.5.0",
|
"@verdaccio/eslint-config": "^8.5.0",
|
||||||
"@verdaccio/types": "10.3.0",
|
"@verdaccio/types": "10.4.2",
|
||||||
"all-contributors-cli": "6.20.0",
|
"all-contributors-cli": "6.20.0",
|
||||||
"babel-eslint": "10.1.0",
|
"babel-eslint": "10.1.0",
|
||||||
"babel-jest": "26.6.3",
|
"babel-jest": "26.6.3",
|
||||||
|
@ -172,7 +172,9 @@
|
||||||
"lint:ts": "eslint \"**/*.{js,jsx,ts,tsx}\" -c ./eslintrc.js",
|
"lint:ts": "eslint \"**/*.{js,jsx,ts,tsx}\" -c ./eslintrc.js",
|
||||||
"lint:lockfile": "lockfile-lint --path yarn.lock --type yarn --validate-https --allowed-hosts verdaccio npm yarn",
|
"lint:lockfile": "lockfile-lint --path yarn.lock --type yarn --validate-https --allowed-hosts verdaccio npm yarn",
|
||||||
"start": "yarn babel-node --extensions \".ts,.tsx\" src/lib/cli --inspect",
|
"start": "yarn babel-node --extensions \".ts,.tsx\" src/lib/cli --inspect",
|
||||||
|
"start:brk": "yarn babel-node --extensions \".ts,.tsx\" src/lib/cli --inspect-brk",
|
||||||
"start:debug": "yarn node debug/bootstrap.js",
|
"start:debug": "yarn node debug/bootstrap.js",
|
||||||
|
"start:run-server": "yarn node debug/bootstrap-runserver.js",
|
||||||
"code:build": "yarn babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps inline",
|
"code:build": "yarn babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps inline",
|
||||||
"code:docker-build": "yarn babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\"",
|
"code:docker-build": "yarn babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\"",
|
||||||
"docker": "docker build -t verdaccio/verdaccio:local . --no-cache",
|
"docker": "docker build -t verdaccio/verdaccio:local . --no-cache",
|
||||||
|
|
|
@ -7,31 +7,21 @@ auth:
|
||||||
htpasswd:
|
htpasswd:
|
||||||
file: ./htpasswd
|
file: ./htpasswd
|
||||||
uplinks:
|
uplinks:
|
||||||
verdaccio:
|
npmjs:
|
||||||
url: https://registry.verdaccio.org/
|
url: https://registry.npmjs.org/
|
||||||
max_fails: 30
|
|
||||||
fail_timeout: 10m
|
|
||||||
timeout: 60s
|
|
||||||
cache: false
|
|
||||||
maxage: 30m
|
|
||||||
agent_options:
|
|
||||||
keepAlive: true
|
|
||||||
maxSockets: 40
|
|
||||||
maxFreeSockets: 10
|
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
'@*/*':
|
'@*/*':
|
||||||
# scoped packages
|
|
||||||
access: $all
|
access: $all
|
||||||
publish: $authenticated
|
publish: $authenticated
|
||||||
unpublish: $authenticated
|
unpublish: $authenticated
|
||||||
proxy: verdaccio
|
proxy: npmjs
|
||||||
|
|
||||||
'**':
|
'**':
|
||||||
access: $all
|
access: $all
|
||||||
publish: $authenticated
|
publish: $authenticated
|
||||||
unpublish: $authenticated
|
unpublish: $authenticated
|
||||||
proxy: verdaccio
|
proxy: npmjs
|
||||||
|
|
||||||
server:
|
server:
|
||||||
keepAliveTimeout: 60
|
keepAliveTimeout: 60
|
||||||
|
@ -40,5 +30,4 @@ middlewares:
|
||||||
audit:
|
audit:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
logs:
|
logs: { type: stdout, format: json, level: warn }
|
||||||
- { type: stdout, format: json, level: warn }
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// @flow
|
export { parseConfigFile } from './lib/utils';
|
||||||
import { startVerdaccio } from './lib/bootstrap';
|
export { startVerdaccio as default, startVerdaccio } from './lib/bootstrap';
|
||||||
|
// Similar structure as v6 but with different functions
|
||||||
export default startVerdaccio;
|
// this is a bridge for easy migration to v6
|
||||||
|
export { runServer } from './lib/bootstrap.v2';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import constants from 'constants';
|
import constants from 'constants';
|
||||||
import express from 'express';
|
|
||||||
import { Application } from 'express';
|
import { Application } from 'express';
|
||||||
|
import express from 'express';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import http from 'http';
|
import http from 'http';
|
||||||
import https from 'https';
|
import https from 'https';
|
||||||
|
@ -32,6 +32,7 @@ function displayExperimentsInfoBox(experiments) {
|
||||||
* @param {String} configPath
|
* @param {String} configPath
|
||||||
* @param {String} pkgVersion
|
* @param {String} pkgVersion
|
||||||
* @param {String} pkgName
|
* @param {String} pkgName
|
||||||
|
* @deprecated use runServer instead
|
||||||
*/
|
*/
|
||||||
function startVerdaccio(config: any, cliListen: string, configPath: string, pkgVersion: string, pkgName: string, callback: Callback): void {
|
function startVerdaccio(config: any, cliListen: string, configPath: string, pkgVersion: string, pkgName: string, callback: Callback): void {
|
||||||
if (isObject(config) === false) {
|
if (isObject(config) === false) {
|
||||||
|
@ -45,6 +46,10 @@ function startVerdaccio(config: any, cliListen: string, configPath: string, pkgV
|
||||||
endPointAPI(config).then((app): void => {
|
endPointAPI(config).then((app): void => {
|
||||||
const addresses = getListListenAddresses(cliListen, config.listen);
|
const addresses = getListListenAddresses(cliListen, config.listen);
|
||||||
|
|
||||||
|
if (addresses.length > 1) {
|
||||||
|
process.emitWarning('multiple listen addresses are deprecated, please use only one');
|
||||||
|
}
|
||||||
|
|
||||||
addresses.forEach(function (addr): void {
|
addresses.forEach(function (addr): void {
|
||||||
let webServer;
|
let webServer;
|
||||||
if (addr.proto === 'https') {
|
if (addr.proto === 'https') {
|
||||||
|
@ -135,7 +140,14 @@ function handleHTTPS(app: express.Application, configPath: string, config: Confi
|
||||||
process.exit(2);
|
process.exit(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param webServer
|
||||||
|
* @param addr
|
||||||
|
* @param pkgName
|
||||||
|
* @param pkgVersion
|
||||||
|
* @deprecated use initServer instead
|
||||||
|
*/
|
||||||
function listenDefaultCallback(webServer: Application, addr: any, pkgName: string, pkgVersion: string): void {
|
function listenDefaultCallback(webServer: Application, addr: any, pkgName: string, pkgVersion: string): void {
|
||||||
const server = webServer
|
const server = webServer
|
||||||
.listen(addr.port || addr.path, addr.host, (): void => {
|
.listen(addr.port || addr.path, addr.host, (): void => {
|
||||||
|
|
147
src/lib/bootstrap.v2.ts
Normal file
147
src/lib/bootstrap.v2.ts
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
import constants from 'constants';
|
||||||
|
import buildDebug from 'debug';
|
||||||
|
import fs from 'fs';
|
||||||
|
import http from 'http';
|
||||||
|
import https from 'https';
|
||||||
|
import _, { assign } from 'lodash';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
import { ConfigRuntime, HttpsConfKeyCert, HttpsConfPfx } from '@verdaccio/types';
|
||||||
|
|
||||||
|
import endPointAPI from '../api/index';
|
||||||
|
import { getListListenAddresses } from './cli/utils';
|
||||||
|
import findConfigFile from './config-path';
|
||||||
|
import { API_ERROR } from './constants';
|
||||||
|
import { parseConfigFile } from './utils';
|
||||||
|
|
||||||
|
const debug = buildDebug('verdaccio');
|
||||||
|
|
||||||
|
const logger = require('./logger');
|
||||||
|
|
||||||
|
export function displayExperimentsInfoBox(flags) {
|
||||||
|
if (!flags) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const experimentList = Object.keys(flags);
|
||||||
|
if (experimentList.length >= 1) {
|
||||||
|
logger.warn(
|
||||||
|
// eslint-disable-next-line max-len
|
||||||
|
`experiments are enabled, it is recommended do not use experiments in production comment out this section to disable it`
|
||||||
|
);
|
||||||
|
experimentList.forEach((experiment) => {
|
||||||
|
// eslint-disable-next-line max-len
|
||||||
|
logger.info(`support for experiment [${experiment}] ${flags[experiment] ? 'is enabled' : ' is disabled'}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exposes a server factory to be instantiated programmatically.
|
||||||
|
*
|
||||||
|
const app = await runServer(); // default configuration
|
||||||
|
const app = await runServer('./config/config.yaml');
|
||||||
|
const app = await runServer({ configuration });
|
||||||
|
app.listen(4000, (event) => {
|
||||||
|
// do something
|
||||||
|
});
|
||||||
|
* @param config
|
||||||
|
*/
|
||||||
|
export async function runServer(config?: string): Promise<any> {
|
||||||
|
let configurationParsed: ConfigRuntime;
|
||||||
|
if (config === undefined || typeof config === 'string') {
|
||||||
|
const configPathLocation = findConfigFile(config);
|
||||||
|
configurationParsed = parseConfigFile(configPathLocation) as ConfigRuntime;
|
||||||
|
if (!configurationParsed.self_path) {
|
||||||
|
configurationParsed.self_path = path.resolve(configPathLocation);
|
||||||
|
}
|
||||||
|
} else if (_.isObject(config)) {
|
||||||
|
configurationParsed = config;
|
||||||
|
if (!configurationParsed.self_path) {
|
||||||
|
throw new Error('self_path is required, please provide a valid root path for storage');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error(API_ERROR.CONFIG_BAD_FORMAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
const addresses = getListListenAddresses(undefined, configurationParsed.listen);
|
||||||
|
if (addresses.length > 1) {
|
||||||
|
process.emitWarning('You have specified multiple listen addresses, using this method only the first will be used');
|
||||||
|
}
|
||||||
|
|
||||||
|
const app = await endPointAPI(configurationParsed);
|
||||||
|
return createServerFactory(configurationParsed, addresses[0], app);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a native HTTP/HTTPS server instance
|
||||||
|
* @param config
|
||||||
|
* @param addr
|
||||||
|
* @param app
|
||||||
|
*/
|
||||||
|
export function createServerFactory(config: ConfigRuntime, addr, app) {
|
||||||
|
let serverFactory;
|
||||||
|
if (addr.proto === 'https') {
|
||||||
|
debug('https enabled');
|
||||||
|
try {
|
||||||
|
let httpsOptions = {
|
||||||
|
// disable insecure SSLv2 and SSLv3
|
||||||
|
secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3,
|
||||||
|
};
|
||||||
|
|
||||||
|
const keyCertConfig = config.https as HttpsConfKeyCert;
|
||||||
|
const pfxConfig = config.https as HttpsConfPfx;
|
||||||
|
|
||||||
|
// https must either have key and cert or a pfx and (optionally) a passphrase
|
||||||
|
if (!((keyCertConfig.key && keyCertConfig.cert) || pfxConfig.pfx)) {
|
||||||
|
throw Error('bad format https configuration');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pfxConfig.pfx) {
|
||||||
|
const { pfx, passphrase } = pfxConfig;
|
||||||
|
httpsOptions = assign(httpsOptions, {
|
||||||
|
pfx: fs.readFileSync(pfx),
|
||||||
|
passphrase: passphrase || '',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const { key, cert, ca } = keyCertConfig;
|
||||||
|
httpsOptions = assign(httpsOptions, {
|
||||||
|
key: fs.readFileSync(key),
|
||||||
|
cert: fs.readFileSync(cert),
|
||||||
|
...(ca && {
|
||||||
|
ca: fs.readFileSync(ca),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// TODO: enable http2 as feature
|
||||||
|
// if (config.server.http2) <-- check if force http2
|
||||||
|
serverFactory = https.createServer(httpsOptions, app);
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(`cannot create https server: ${err.message}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// http
|
||||||
|
debug('http enabled');
|
||||||
|
serverFactory = http.createServer(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
config.server &&
|
||||||
|
typeof config.server.keepAliveTimeout !== 'undefined' &&
|
||||||
|
// @ts-ignore
|
||||||
|
config.server.keepAliveTimeout !== 'null'
|
||||||
|
) {
|
||||||
|
// library definition for node is not up to date (doesn't contain recent 8.0 changes)
|
||||||
|
serverFactory.keepAliveTimeout = config.server.keepAliveTimeout * 1000;
|
||||||
|
}
|
||||||
|
// FIXE: I could not find the reason of this code.
|
||||||
|
unlinkAddressPath(addr);
|
||||||
|
|
||||||
|
return serverFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
function unlinkAddressPath(addr) {
|
||||||
|
if (addr.path && fs.existsSync(addr.path)) {
|
||||||
|
fs.unlinkSync(addr.path);
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,7 +27,7 @@ export function isVersionValid(version) {
|
||||||
- localhost:5557
|
- localhost:5557
|
||||||
@return {Array}
|
@return {Array}
|
||||||
*/
|
*/
|
||||||
export function getListListenAddresses(argListen: string, configListen: any): any {
|
export function getListListenAddresses(argListen: string | void, configListen: any): any {
|
||||||
// command line || config file || default
|
// command line || config file || default
|
||||||
let addresses;
|
let addresses;
|
||||||
if (argListen) {
|
if (argListen) {
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
|
import buildDebug from 'debug';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import mkdirp from 'mkdirp';
|
import mkdirp from 'mkdirp';
|
||||||
import Path from 'path';
|
import Path from 'path';
|
||||||
|
|
||||||
import { CHARACTER_ENCODING } from './constants';
|
|
||||||
import { logger } from './logger';
|
import { logger } from './logger';
|
||||||
import { fileExists, folderExists } from './utils';
|
import { fileExists, folderExists } from './utils';
|
||||||
|
|
||||||
|
const debug = buildDebug('verdaccio:config');
|
||||||
|
|
||||||
const CONFIG_FILE = 'config.yaml';
|
const CONFIG_FILE = 'config.yaml';
|
||||||
const XDG = 'xdg';
|
const XDG = 'xdg';
|
||||||
const WIN = 'win';
|
const WIN = 'win';
|
||||||
|
@ -23,19 +25,20 @@ export type SetupDirectory = {
|
||||||
* Find and get the first config file that match.
|
* Find and get the first config file that match.
|
||||||
* @return {String} the config file path
|
* @return {String} the config file path
|
||||||
*/
|
*/
|
||||||
function findConfigFile(configPath: string): string {
|
function findConfigFile(configPath?: string): string {
|
||||||
if (_.isNil(configPath) === false) {
|
if (typeof configPath !== 'undefined') {
|
||||||
return Path.resolve(configPath);
|
return Path.resolve(configPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
const configPaths: SetupDirectory[] = getConfigPaths();
|
const configPaths: SetupDirectory[] = getConfigPaths();
|
||||||
|
debug('%o posible locations found', configPaths.length);
|
||||||
if (_.isEmpty(configPaths)) {
|
if (_.isEmpty(configPaths)) {
|
||||||
throw new Error('no configuration files can be processed');
|
throw new Error('no configuration files can be processed');
|
||||||
}
|
}
|
||||||
|
|
||||||
const primaryConf: any = _.find(configPaths, (configLocation: any) => fileExists(configLocation.path));
|
const primaryConf: any = _.find(configPaths, (configLocation: any) => fileExists(configLocation.path));
|
||||||
if (_.isNil(primaryConf) === false) {
|
if (typeof primaryConf !== 'undefined') {
|
||||||
|
debug('previous location exist already %s', primaryConf?.path);
|
||||||
return primaryConf.path;
|
return primaryConf.path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,7 @@ export function sendNotification(metadata: Package, notify: any, remoteUser: Rem
|
||||||
|
|
||||||
export function notify(metadata: Package, config: Config, remoteUser: RemoteUser, publishedPackage: string): Promise<any> | void {
|
export function notify(metadata: Package, config: Config, remoteUser: RemoteUser, publishedPackage: string): Promise<any> | void {
|
||||||
if (config.notify) {
|
if (config.notify) {
|
||||||
|
// @ts-ignore
|
||||||
if (config.notify.content) {
|
if (config.notify.content) {
|
||||||
return sendNotification(metadata, config.notify as unknown as any, remoteUser, publishedPackage);
|
return sendNotification(metadata, config.notify as unknown as any, remoteUser, publishedPackage);
|
||||||
}
|
}
|
||||||
|
|
29
test/unit/modules/bootstrap/config.yaml
Normal file
29
test/unit/modules/bootstrap/config.yaml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
web:
|
||||||
|
enable: true
|
||||||
|
title: verdaccio-bootstrap
|
||||||
|
|
||||||
|
store:
|
||||||
|
memory:
|
||||||
|
limit: 10
|
||||||
|
|
||||||
|
auth:
|
||||||
|
auth-memory:
|
||||||
|
users:
|
||||||
|
test:
|
||||||
|
name: test
|
||||||
|
password: test
|
||||||
|
|
||||||
|
logs: { type: stdout, format: pretty, level: warn }
|
||||||
|
|
||||||
|
packages:
|
||||||
|
'@*/*':
|
||||||
|
access: $all
|
||||||
|
publish: $authenticated
|
||||||
|
unpublish: $authenticated
|
||||||
|
proxy: npmjs
|
||||||
|
|
||||||
|
'**':
|
||||||
|
access: $all
|
||||||
|
publish: $authenticated
|
||||||
|
unpublish: $authenticated
|
||||||
|
proxy: npmjs
|
28
test/unit/modules/bootstrap/legacy.spec.ts
Normal file
28
test/unit/modules/bootstrap/legacy.spec.ts
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import { join } from 'path';
|
||||||
|
|
||||||
|
import startVerdaccioDeault, { startVerdaccio } from '../../../../src';
|
||||||
|
import { parseConfigFile } from '../../../../src/lib/utils';
|
||||||
|
|
||||||
|
describe('bootstrap legacy', () => {
|
||||||
|
describe('startVerdaccio', () => {
|
||||||
|
test('run server should be able to listen', (done) => {
|
||||||
|
const p = join(__dirname, './config.yaml');
|
||||||
|
const cache = join(__dirname, 'cache');
|
||||||
|
const config = parseConfigFile(p);
|
||||||
|
startVerdaccio(config, '5000', cache, '1.0.0', 'verdaccio', (server, addr) => {
|
||||||
|
server.close();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('run server should be able to listen default method', (done) => {
|
||||||
|
const p = join(__dirname, './config.yaml');
|
||||||
|
const cache = join(__dirname, 'cache');
|
||||||
|
const config = parseConfigFile(p);
|
||||||
|
startVerdaccioDeault(config, '5000', cache, '1.0.0', 'verdaccio', (server, addr) => {
|
||||||
|
server.close();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
48
test/unit/modules/bootstrap/run-server.spec.ts
Normal file
48
test/unit/modules/bootstrap/run-server.spec.ts
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import { join } from 'path';
|
||||||
|
|
||||||
|
import { runServer } from '../../../../src';
|
||||||
|
import { parseConfigFile } from '../../../../src/lib/utils';
|
||||||
|
|
||||||
|
describe('bootstrap modern', () => {
|
||||||
|
describe('runServer', () => {
|
||||||
|
test('run server should be able to listen', (done) => {
|
||||||
|
const configPath = join(__dirname, './config.yaml');
|
||||||
|
runServer(configPath).then((app) => {
|
||||||
|
app.listen(4000, () => {
|
||||||
|
app.close();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('run server should be able to listen with object', (done) => {
|
||||||
|
const configPath = join(__dirname, './config.yaml');
|
||||||
|
const c = parseConfigFile(configPath);
|
||||||
|
// workaround
|
||||||
|
// on v5 the `self_path` still exists and will be removed in v6
|
||||||
|
c.self_path = 'foo';
|
||||||
|
runServer(c).then((app) => {
|
||||||
|
app.listen(4000, () => {
|
||||||
|
app.close();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('run server should be able to listen async', async () => {
|
||||||
|
const configPath = join(__dirname, './config.yaml');
|
||||||
|
const app = await runServer(configPath);
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
app.listen(4000, () => {
|
||||||
|
app.close();
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('run server should fails with wrong path', async () => {
|
||||||
|
const configPath = join(__dirname, './this_does_not_exist.yaml');
|
||||||
|
await expect(runServer(configPath)).rejects.toThrow(/Error: CONFIG: it does not look like a valid config file/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
BIN
yarn.lock
BIN
yarn.lock
Binary file not shown.
Loading…
Reference in a new issue