mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-24 21:15:51 +01: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
@ -8,7 +8,7 @@ on:
|
||||
name: 'E2E Gatsby.js CLI with verdaccio'
|
||||
jobs:
|
||||
npm6:
|
||||
name: 'npm:gatsby example'
|
||||
name: 'npm6:gatsby example'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@ -32,7 +32,7 @@ jobs:
|
||||
run: |
|
||||
source scripts/e2e-setup-ci.sh
|
||||
echo "registry=http://localhost:4873
|
||||
loglevel="silent"
|
||||
loglevel="warn"
|
||||
fetch-retries=10
|
||||
fetch-retry-factor=2
|
||||
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/readme", "npm:10.3.4"],
|
||||
["@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"],
|
||||
["JSONStream", "npm:1.3.5"],
|
||||
["all-contributors-cli", "npm:6.20.0"],
|
||||
@ -5865,10 +5865,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
}]
|
||||
]],
|
||||
["@verdaccio/types", [
|
||||
["npm:10.3.0", {
|
||||
"packageLocation": "./.yarn/cache/@verdaccio-types-npm-10.3.0-a7d2915e19-307c485a51.zip/node_modules/@verdaccio/types/",
|
||||
["npm:10.4.2", {
|
||||
"packageLocation": "./.yarn/cache/@verdaccio-types-npm-10.4.2-78b2370b99-f4f02e1496.zip/node_modules/@verdaccio/types/",
|
||||
"packageDependencies": [
|
||||
["@verdaccio/types", "npm:10.3.0"]
|
||||
["@verdaccio/types", "npm:10.4.2"]
|
||||
],
|
||||
"linkType": "HARD",
|
||||
}]
|
||||
@ -8090,14 +8090,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
]],
|
||||
["core-js", [
|
||||
["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": [
|
||||
["core-js", "npm:2.6.9"]
|
||||
],
|
||||
"linkType": "HARD",
|
||||
}],
|
||||
["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": [
|
||||
["core-js", "npm:3.22.4"]
|
||||
],
|
||||
@ -15230,7 +15230,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
]],
|
||||
["puppeteer", [
|
||||
["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": [
|
||||
["puppeteer", "npm:5.5.0"],
|
||||
["debug", "virtual:fada3bd8ad326a7c196d0c24aae1d5410b84126805d4b297cac3abf549e077c61a437968e49905247d38e2ca430b4cee29c78b779ec928550ea7a1cdf2adc3c1#npm:4.1.1"],
|
||||
@ -18010,7 +18010,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
["@verdaccio/local-storage", "npm:10.2.1"],
|
||||
["@verdaccio/readme", "npm:10.3.4"],
|
||||
["@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"],
|
||||
["JSONStream", "npm:1.3.5"],
|
||||
["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/parser": "4.33.0",
|
||||
"@verdaccio/eslint-config": "^8.5.0",
|
||||
"@verdaccio/types": "10.3.0",
|
||||
"@verdaccio/types": "10.4.2",
|
||||
"all-contributors-cli": "6.20.0",
|
||||
"babel-eslint": "10.1.0",
|
||||
"babel-jest": "26.6.3",
|
||||
@ -172,7 +172,9 @@
|
||||
"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",
|
||||
"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: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:docker-build": "yarn babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\"",
|
||||
"docker": "docker build -t verdaccio/verdaccio:local . --no-cache",
|
||||
|
@ -7,31 +7,21 @@ auth:
|
||||
htpasswd:
|
||||
file: ./htpasswd
|
||||
uplinks:
|
||||
verdaccio:
|
||||
url: https://registry.verdaccio.org/
|
||||
max_fails: 30
|
||||
fail_timeout: 10m
|
||||
timeout: 60s
|
||||
cache: false
|
||||
maxage: 30m
|
||||
agent_options:
|
||||
keepAlive: true
|
||||
maxSockets: 40
|
||||
maxFreeSockets: 10
|
||||
npmjs:
|
||||
url: https://registry.npmjs.org/
|
||||
|
||||
packages:
|
||||
'@*/*':
|
||||
# scoped packages
|
||||
access: $all
|
||||
publish: $authenticated
|
||||
unpublish: $authenticated
|
||||
proxy: verdaccio
|
||||
proxy: npmjs
|
||||
|
||||
'**':
|
||||
access: $all
|
||||
publish: $authenticated
|
||||
unpublish: $authenticated
|
||||
proxy: verdaccio
|
||||
proxy: npmjs
|
||||
|
||||
server:
|
||||
keepAliveTimeout: 60
|
||||
@ -40,5 +30,4 @@ middlewares:
|
||||
audit:
|
||||
enabled: true
|
||||
|
||||
logs:
|
||||
- { type: stdout, format: json, level: warn }
|
||||
logs: { type: stdout, format: json, level: warn }
|
||||
|
@ -1,4 +1,5 @@
|
||||
// @flow
|
||||
import { startVerdaccio } from './lib/bootstrap';
|
||||
|
||||
export default startVerdaccio;
|
||||
export { parseConfigFile } from './lib/utils';
|
||||
export { startVerdaccio as default, startVerdaccio } from './lib/bootstrap';
|
||||
// Similar structure as v6 but with different functions
|
||||
// this is a bridge for easy migration to v6
|
||||
export { runServer } from './lib/bootstrap.v2';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import constants from 'constants';
|
||||
import express from 'express';
|
||||
import { Application } from 'express';
|
||||
import express from 'express';
|
||||
import fs from 'fs';
|
||||
import http from 'http';
|
||||
import https from 'https';
|
||||
@ -32,6 +32,7 @@ function displayExperimentsInfoBox(experiments) {
|
||||
* @param {String} configPath
|
||||
* @param {String} pkgVersion
|
||||
* @param {String} pkgName
|
||||
* @deprecated use runServer instead
|
||||
*/
|
||||
function startVerdaccio(config: any, cliListen: string, configPath: string, pkgVersion: string, pkgName: string, callback: Callback): void {
|
||||
if (isObject(config) === false) {
|
||||
@ -45,6 +46,10 @@ function startVerdaccio(config: any, cliListen: string, configPath: string, pkgV
|
||||
endPointAPI(config).then((app): void => {
|
||||
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 {
|
||||
let webServer;
|
||||
if (addr.proto === 'https') {
|
||||
@ -135,7 +140,14 @@ function handleHTTPS(app: express.Application, configPath: string, config: Confi
|
||||
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 {
|
||||
const server = webServer
|
||||
.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
|
||||
@return {Array}
|
||||
*/
|
||||
export function getListListenAddresses(argListen: string, configListen: any): any {
|
||||
export function getListListenAddresses(argListen: string | void, configListen: any): any {
|
||||
// command line || config file || default
|
||||
let addresses;
|
||||
if (argListen) {
|
||||
|
@ -1,12 +1,14 @@
|
||||
import buildDebug from 'debug';
|
||||
import fs from 'fs';
|
||||
import _ from 'lodash';
|
||||
import mkdirp from 'mkdirp';
|
||||
import Path from 'path';
|
||||
|
||||
import { CHARACTER_ENCODING } from './constants';
|
||||
import { logger } from './logger';
|
||||
import { fileExists, folderExists } from './utils';
|
||||
|
||||
const debug = buildDebug('verdaccio:config');
|
||||
|
||||
const CONFIG_FILE = 'config.yaml';
|
||||
const XDG = 'xdg';
|
||||
const WIN = 'win';
|
||||
@ -23,19 +25,20 @@ export type SetupDirectory = {
|
||||
* Find and get the first config file that match.
|
||||
* @return {String} the config file path
|
||||
*/
|
||||
function findConfigFile(configPath: string): string {
|
||||
if (_.isNil(configPath) === false) {
|
||||
function findConfigFile(configPath?: string): string {
|
||||
if (typeof configPath !== 'undefined') {
|
||||
return Path.resolve(configPath);
|
||||
}
|
||||
|
||||
const configPaths: SetupDirectory[] = getConfigPaths();
|
||||
|
||||
debug('%o posible locations found', configPaths.length);
|
||||
if (_.isEmpty(configPaths)) {
|
||||
throw new Error('no configuration files can be processed');
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
if (config.notify) {
|
||||
// @ts-ignore
|
||||
if (config.notify.content) {
|
||||
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 New Issue
Block a user