Compare commits

...

2 Commits

Author SHA1 Message Date
github-actions[bot]
88850dce24 chore: update versions (6-next) (#2166) 2021-04-04 21:29:03 +02:00
Juan Picado
5c5057fc5f feat: improve node-api (#2165)
* refactor: improve node-api

* chore: add test for run server
2021-04-04 21:13:16 +02:00
79 changed files with 1045 additions and 1508 deletions

View File

@@ -61,6 +61,7 @@
"smart-apricots-kneel",
"spicy-frogs-press",
"tender-bags-call",
"three-pots-sit"
"three-pots-sit",
"two-dolls-check"
]
}

View File

@@ -0,0 +1,28 @@
---
'@verdaccio/cli': major
'@verdaccio/config': major
'@verdaccio/types': major
'@verdaccio/logger': major
'@verdaccio/node-api': major
'verdaccio-google-cloud': major
'verdaccio': major
---
feat: node api new structure based on promise
```js
import { runServer } from '@verdaccio/node-api';
// or
import { runServer } from 'verdaccio';
const app = await runServer(); // default configuration
const app = await runServer('./config/config.yaml');
const app = await runServer({ configuration });
app.listen(4000, (event) => {
// do something
});
```
### Breaking Change
If you are using the node-api, the new structure is Promise based and less arguments.

View File

@@ -1,5 +1,18 @@
# @verdaccio/api
## 6.0.0-6-next.8
### Patch Changes
- Updated dependencies [5c5057fc]
- @verdaccio/config@6.0.0-6-next.4
- @verdaccio/logger@6.0.0-6-next.4
- @verdaccio/auth@6.0.0-6-next.6
- @verdaccio/hooks@6.0.0-6-next.4
- @verdaccio/store@6.0.0-6-next.6
- @verdaccio/tarball@11.0.0-6-next.4
- @verdaccio/middleware@6.0.0-6-next.6
## 6.0.0-6-next.7
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/api",
"version": "6.0.0-6-next.7",
"version": "6.0.0-6-next.8",
"description": "loaders logic",
"main": "./build/index.js",
"types": "build/index.d.ts",
@@ -39,13 +39,13 @@
},
"license": "MIT",
"dependencies": {
"@verdaccio/auth": "workspace:6.0.0-alpha.5",
"@verdaccio/auth": "workspace:6.0.0-6-next.6",
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-alpha.3",
"@verdaccio/hooks": "workspace:6.0.0-alpha.3",
"@verdaccio/logger": "workspace:6.0.0-alpha.3",
"@verdaccio/middleware": "workspace:6.0.0-alpha.5",
"@verdaccio/store": "workspace:6.0.0-6-next.5",
"@verdaccio/config": "workspace:6.0.0-6-next.4",
"@verdaccio/hooks": "workspace:6.0.0-6-next.4",
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
"@verdaccio/middleware": "workspace:6.0.0-6-next.6",
"@verdaccio/store": "workspace:6.0.0-6-next.6",
"@verdaccio/tarball": "workspace:11.0.0-6-next.4",
"@verdaccio/utils": "workspace:6.0.0-alpha.3",
"cookies": "0.8.0",
@@ -56,8 +56,8 @@
"semver": "7.3.2"
},
"devDependencies": {
"@verdaccio/server": "workspace:6.0.0-6-next.8",
"@verdaccio/types": "workspace:11.0.0-alpha.3",
"@verdaccio/server": "workspace:6.0.0-6-next.9",
"@verdaccio/types": "workspace:11.0.0-6-next.4",
"body-parser": "1.19.0",
"lodash": "^4.17.20",
"supertest": "next"

View File

@@ -1,5 +1,16 @@
# @verdaccio/auth
## 6.0.0-6-next.6
### Patch Changes
- Updated dependencies [5c5057fc]
- @verdaccio/config@6.0.0-6-next.4
- @verdaccio/logger@6.0.0-6-next.4
- @verdaccio/auth@6.0.0-6-next.6
- @verdaccio/loaders@6.0.0-6-next.4
- verdaccio-htpasswd@11.0.0-alpha.6
## 5.0.0-alpha.5
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/auth",
"version": "6.0.0-alpha.5",
"version": "6.0.0-6-next.6",
"description": "logger",
"main": "./build/index.js",
"types": "build/index.d.ts",
@@ -39,11 +39,11 @@
},
"license": "MIT",
"dependencies": {
"@verdaccio/auth": "workspace:6.0.0-alpha.5",
"@verdaccio/auth": "workspace:6.0.0-6-next.6",
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-alpha.3",
"@verdaccio/loaders": "workspace:6.0.0-alpha.3",
"@verdaccio/logger": "workspace:6.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-6-next.4",
"@verdaccio/loaders": "workspace:6.0.0-6-next.4",
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
"@verdaccio/utils": "workspace:6.0.0-alpha.3",
"verdaccio-htpasswd": "workspace:11.0.0-alpha.6",
"debug": "^4.1.1",
@@ -52,8 +52,8 @@
"lodash": "4.17.15"
},
"devDependencies": {
"@verdaccio/mock": "workspace:6.0.0-alpha.3",
"@verdaccio/types": "workspace:11.0.0-alpha.3"
"@verdaccio/mock": "workspace:6.0.0-6-next.4",
"@verdaccio/types": "workspace:11.0.0-6-next.4"
},
"funding": {
"type": "opencollective",

View File

@@ -1,5 +1,34 @@
# @verdaccio/cli
## 6.0.0-6-next.10
### Major Changes
- 5c5057fc: feat: node api new structure based on promise
```js
import { runServer } from '@verdaccio/node-api';
// or
import { runServer } from 'verdaccio';
const app = await runServer(); // default configuration
const app = await runServer('./config/config.yaml');
const app = await runServer({ configuration });
app.listen(4000, event => {
// do something
});
```
### Breaking Change
If you are using the node-api, the new structure is Promise based and less arguments.
### Patch Changes
- Updated dependencies [5c5057fc]
- @verdaccio/config@6.0.0-6-next.4
- @verdaccio/node-api@6.0.0-6-next.10
## 6.0.0-6-next.9
### Major Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/cli",
"version": "6.0.0-6-next.9",
"version": "6.0.0-6-next.10",
"author": {
"name": "Juan Picado",
"email": "juanpicado19@gmail.com"
@@ -43,9 +43,9 @@
"build": "pnpm run build:js && pnpm run build:types"
},
"dependencies": {
"@verdaccio/config": "workspace:6.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-6-next.4",
"@verdaccio/cli-ui": "workspace:6.0.0-alpha.3",
"@verdaccio/node-api": "workspace:6.0.0-6-next.9",
"@verdaccio/node-api": "workspace:6.0.0-6-next.10",
"commander": "6.2.0",
"clipanion": "3.0.0-rc.11",
"envinfo": "7.4.0",

View File

@@ -1,15 +1,13 @@
import { Command, Option } from 'clipanion';
import { ConfigRuntime } from '@verdaccio/types';
import { findConfigFile, parseConfigFile } from '@verdaccio/config';
import { startVerdaccio, listenDefaultCallback } from '@verdaccio/node-api';
import { initServer } from '@verdaccio/node-api';
export const DEFAULT_PROCESS_NAME: string = 'verdaccio';
export class InitCommand extends Command {
static paths = [Command.Default];
listen = Option.String('-l,--listen', {
port = Option.String('-l,-p,--listen,--port', {
description: 'host:port number to listen on (default: localhost:4873)',
});
@@ -25,8 +23,8 @@ export class InitCommand extends Command {
The optional arguments are:
- \`--listen\` to switch the default server port,
- \`--config\` to define a different configuration path location,
- \`-l | --listen | -p | --port\` to switch the default server port,
- \`-c | --config\` to define a different configuration path location,
`,
examples: [
@@ -44,65 +42,19 @@ export class InitCommand extends Command {
});
async execute() {
let configPathLocation;
let verdaccioConfiguration: ConfigRuntime;
try {
configPathLocation = findConfigFile(this.config as string);
verdaccioConfiguration = parseConfigFile(configPathLocation);
const { web, https } = verdaccioConfiguration;
const configPathLocation = findConfigFile(this.config as string);
const configParsed = parseConfigFile(configPathLocation);
const { web } = configParsed;
process.title = web?.title || DEFAULT_PROCESS_NAME;
if (!https) {
verdaccioConfiguration = Object.assign({}, verdaccioConfiguration, {
https: { enable: false },
});
}
const { version, name } = require('../../package.json');
startVerdaccio(
verdaccioConfiguration,
this.listen as string,
configPathLocation,
version,
name,
listenDefaultCallback
);
await initServer(configParsed, this.port as string, version, name);
} catch (err) {
console.error(err);
process.exit(1);
}
}
}
// export default function initProgram(commander, pkgVersion, pkgName) {
// const cliListener = commander.listen;
// let configPathLocation;
// let verdaccioConfiguration: ConfigRuntime;
// try {
// configPathLocation = findConfigFile(commander.config);
// verdaccioConfiguration = parseConfigFile(configPathLocation);
// const { web, https } = verdaccioConfiguration;
// process.title = web?.title || DEFAULT_PROCESS_NAME;
// if (!https) {
// verdaccioConfiguration = Object.assign({}, verdaccioConfiguration, {
// https: { enable: false },
// });
// }
// // initLogger.warn({file: configPathLocation}, 'config file - @{file}');
// startVerdaccio(
// verdaccioConfiguration,
// cliListener,
// configPathLocation,
// pkgVersion,
// pkgName,
// listenDefaultCallback
// );
// } catch (err) {
// process.exit(1);
// }
// }

View File

@@ -1,5 +1,28 @@
# @verdaccio/config
## 6.0.0-6-next.4
### Major Changes
- 5c5057fc: feat: node api new structure based on promise
```js
import { runServer } from '@verdaccio/node-api';
// or
import { runServer } from 'verdaccio';
const app = await runServer(); // default configuration
const app = await runServer('./config/config.yaml');
const app = await runServer({ configuration });
app.listen(4000, event => {
// do something
});
```
### Breaking Change
If you are using the node-api, the new structure is Promise based and less arguments.
## 5.0.0-alpha.3
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/config",
"version": "6.0.0-alpha.3",
"version": "6.0.0-6-next.4",
"description": "logger",
"main": "./build/index.js",
"types": "build/index.d.ts",

View File

@@ -28,8 +28,8 @@ const debug = buildDebug('verdaccio:config');
* 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 | undefined): string {
if (typeof configPath !== 'undefined') {
return Path.resolve(configPath);
}

View File

@@ -40,7 +40,7 @@
"lockfile": "1.0.4"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-alpha.3"
"@verdaccio/types": "workspace:11.0.0-6-next.4"
},
"scripts": {
"clean": "rimraf ./build",

View File

@@ -43,7 +43,7 @@
},
"devDependencies": {
"@types/bcryptjs": "^2.4.2",
"@verdaccio/types": "workspace:11.0.0-alpha.3",
"@verdaccio/types": "workspace:11.0.0-6-next.4",
"mockdate": "^3.0.2"
},
"scripts": {

View File

@@ -48,7 +48,7 @@
},
"devDependencies": {
"@types/minimatch": "^3.0.3",
"@verdaccio/types": "workspace:11.0.0-alpha.3",
"@verdaccio/types": "workspace:11.0.0-6-next.4",
"minimatch": "^3.0.4",
"rmdir-sync": "^1.0.1"
},

View File

@@ -45,7 +45,7 @@
"marked": "1.1.1"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-alpha.3"
"@verdaccio/types": "workspace:11.0.0-6-next.4"
},
"scripts": {
"clean": "rimraf ./build",

View File

@@ -34,7 +34,7 @@
"access": "public"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-alpha.3"
"@verdaccio/types": "workspace:11.0.0-6-next.4"
},
"scripts": {
"clean": "rimraf ./build",

View File

@@ -41,7 +41,7 @@
"@verdaccio/utils": "workspace:6.0.0-alpha.3"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-alpha.3",
"@verdaccio/types": "workspace:11.0.0-6-next.4",
"express": "^4.17.1",
"node-mocks-http": "^1.10.1"
},

View File

@@ -1,5 +1,28 @@
# Change Log
## 11.0.0-6-next.4
### Major Changes
- 5c5057fc: feat: node api new structure based on promise
```js
import { runServer } from '@verdaccio/node-api';
// or
import { runServer } from 'verdaccio';
const app = await runServer(); // default configuration
const app = await runServer('./config/config.yaml');
const app = await runServer({ configuration });
app.listen(4000, event => {
// do something
});
```
### Breaking Change
If you are using the node-api, the new structure is Promise based and less arguments.
## 10.0.0-alpha.3
### Patch Changes

View File

@@ -352,10 +352,9 @@ declare module '@verdaccio/types' {
export type ServerSettingsConf = {
// express-rate-limit settings
rateLimit: RateLimit;
// deprecated
keepAliveTimeout?: number;
//F
publicUrl?: string;
// force http2 if https is defined
http2?: boolean;
};
type URLPrefix = {

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/types",
"version": "11.0.0-alpha.3",
"version": "11.0.0-6-next.4",
"description": "verdaccio types definitions",
"keywords": [
"private",

View File

@@ -41,7 +41,7 @@
},
"devDependencies": {
"node-mocks-http": "^1.10.1",
"@verdaccio/types": "workspace:11.0.0-alpha.3"
"@verdaccio/types": "workspace:11.0.0-6-next.4"
},
"scripts": {
"clean": "rimraf ./build",

View File

@@ -1,5 +1,12 @@
# @verdaccio/hooks
## 6.0.0-6-next.4
### Patch Changes
- Updated dependencies [5c5057fc]
- @verdaccio/logger@6.0.0-6-next.4
## 5.0.0-alpha.3
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/hooks",
"version": "6.0.0-alpha.3",
"version": "6.0.0-6-next.4",
"description": "loaders logic",
"main": "./build/index.js",
"types": "build/index.d.ts",
@@ -31,17 +31,17 @@
},
"dependencies": {
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
"@verdaccio/logger": "workspace:6.0.0-alpha.3",
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
"debug": "^4.2.0",
"handlebars": "4.5.3",
"node-fetch": "^2.6.1",
"request": "2.87.0"
},
"devDependencies": {
"@verdaccio/auth": "workspace:6.0.0-alpha.5",
"@verdaccio/auth": "workspace:6.0.0-6-next.6",
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-alpha.3",
"@verdaccio/types": "workspace:11.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-6-next.4",
"@verdaccio/types": "workspace:11.0.0-6-next.4",
"nock": "^13.0.4"
},
"scripts": {

View File

@@ -1,5 +1,12 @@
# @verdaccio/loaders
## 6.0.0-6-next.4
### Patch Changes
- Updated dependencies [5c5057fc]
- @verdaccio/logger@6.0.0-6-next.4
## 5.0.0-alpha.3
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/loaders",
"version": "6.0.0-alpha.3",
"version": "6.0.0-6-next.4",
"description": "loaders logic",
"main": "./build/index.js",
"types": "build/index.d.ts",
@@ -13,15 +13,15 @@
"url": "https://github.com/verdaccio/verdaccio"
},
"dependencies": {
"@verdaccio/logger": "workspace:6.0.0-alpha.3",
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
"debug": "^4.1.1",
"lodash": "4.17.15"
},
"devDependencies": {
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-alpha.3",
"@verdaccio/mock": "workspace:6.0.0-alpha.3",
"@verdaccio/types": "workspace:11.0.0-alpha.3"
"@verdaccio/config": "workspace:6.0.0-6-next.4",
"@verdaccio/mock": "workspace:6.0.0-6-next.4",
"@verdaccio/types": "workspace:11.0.0-6-next.4"
},
"homepage": "https://verdaccio.org",
"keywords": [

View File

@@ -1,5 +1,28 @@
# @verdaccio/logger
## 6.0.0-6-next.4
### Major Changes
- 5c5057fc: feat: node api new structure based on promise
```js
import { runServer } from '@verdaccio/node-api';
// or
import { runServer } from 'verdaccio';
const app = await runServer(); // default configuration
const app = await runServer('./config/config.yaml');
const app = await runServer({ configuration });
app.listen(4000, event => {
// do something
});
```
### Breaking Change
If you are using the node-api, the new structure is Promise based and less arguments.
## 5.0.0-alpha.3
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/logger",
"version": "6.0.0-alpha.3",
"version": "6.0.0-6-next.4",
"description": "logger",
"main": "./build/index.js",
"types": "build/index.d.ts",
@@ -46,7 +46,7 @@
},
"devDependencies": {
"@types/pino": "^6.3.3",
"@verdaccio/types": "workspace:11.0.0-alpha.3"
"@verdaccio/types": "workspace:11.0.0-6-next.4"
},
"funding": {
"type": "opencollective",

View File

@@ -74,6 +74,7 @@ export function createLogger(
export function getLogger() {
if (_.isNil(logger)) {
// FIXME: not sure about display here a warning
process.emitWarning('logger is not defined');
return;
}
@@ -153,4 +154,6 @@ export function setup(options: LoggerConfig | LoggerConfigItem = [DEFAULT_LOGGER
process.on('SIGQUIT', () => finalHandler(null, 'SIGQUIT'));
process.on('SIGTERM', () => finalHandler(null, 'SIGTERM'));
}
return logger;
}

View File

@@ -1,5 +1,13 @@
# @verdaccio/middleware
## 6.0.0-6-next.6
### Patch Changes
- Updated dependencies [5c5057fc]
- @verdaccio/logger@6.0.0-6-next.4
- @verdaccio/auth@6.0.0-6-next.6
## 5.0.0-alpha.5
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/middleware",
"version": "6.0.0-alpha.5",
"version": "6.0.0-6-next.6",
"description": "loaders logic",
"main": "./build/index.js",
"types": "build/index.d.ts",
@@ -39,9 +39,9 @@
},
"dependencies": {
"debug": "^4.3.1",
"@verdaccio/auth": "workspace:6.0.0-alpha.5",
"@verdaccio/auth": "workspace:6.0.0-6-next.6",
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
"@verdaccio/logger": "workspace:6.0.0-alpha.3",
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
"@verdaccio/utils": "workspace:6.0.0-alpha.3",
"lodash": "4.17.15"
},

View File

@@ -1,5 +1,12 @@
# @verdaccio/mock
## 6.0.0-6-next.4
### Patch Changes
- Updated dependencies [5c5057fc]
- @verdaccio/config@6.0.0-6-next.4
## 5.0.0-alpha.3
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/mock",
"version": "6.0.0-alpha.3",
"version": "6.0.0-6-next.4",
"author": {
"name": "Juan Picado",
"email": "juanpicado19@gmail.com"
@@ -40,7 +40,7 @@
},
"dependencies": {
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-6-next.4",
"@verdaccio/utils": "workspace:6.0.0-alpha.3",
"debug": "^4.2.0",
"fs-extra": "^8.1.0",
@@ -49,7 +49,7 @@
"supertest": "^4.0.2"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-alpha.3"
"@verdaccio/types": "workspace:11.0.0-6-next.4"
},
"funding": {
"type": "opencollective",

View File

@@ -1,5 +1,35 @@
# @verdaccio/node-api
## 6.0.0-6-next.10
### Major Changes
- 5c5057fc: feat: node api new structure based on promise
```js
import { runServer } from '@verdaccio/node-api';
// or
import { runServer } from 'verdaccio';
const app = await runServer(); // default configuration
const app = await runServer('./config/config.yaml');
const app = await runServer({ configuration });
app.listen(4000, event => {
// do something
});
```
### Breaking Change
If you are using the node-api, the new structure is Promise based and less arguments.
### Patch Changes
- Updated dependencies [5c5057fc]
- @verdaccio/config@6.0.0-6-next.4
- @verdaccio/logger@6.0.0-6-next.4
- @verdaccio/server@6.0.0-6-next.9
## 6.0.0-6-next.9
### Patch Changes

View File

@@ -0,0 +1,5 @@
{
"rules": {
"no-console": "off"
}
}

View File

@@ -0,0 +1,8 @@
const { runServer } = require('../build');
(async () => {
const app = await runServer();
app.listen(4000, () => {
console.log('server started');
});
})();

View File

@@ -1,5 +1,3 @@
const config = require('../../jest/config');
module.exports = Object.assign({}, config, {
collectCoverage: false,
});
module.exports = Object.assign({}, config, {});

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/node-api",
"version": "6.0.0-6-next.9",
"version": "6.0.0-6-next.10",
"description": "node API",
"main": "build/index.js",
"types": "build/index.d.ts",
@@ -25,7 +25,7 @@
"verdaccio"
],
"engines": {
"node": ">=10",
"node": ">=12",
"npm": ">=6"
},
"scripts": {
@@ -40,18 +40,20 @@
"license": "MIT",
"dependencies": {
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-6-next.4",
"@verdaccio/cli-ui": "workspace:6.0.0-alpha.3",
"@verdaccio/server": "workspace:6.0.0-6-next.8",
"@verdaccio/server": "workspace:6.0.0-6-next.9",
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
"core-js": "^3.6.5",
"debug": "^4.2.0",
"lodash": "^4.17.20",
"selfsigned": "1.10.7"
"lodash": "^4.17.20"
},
"devDependencies": {
"@verdaccio/mock": "workspace:6.0.0-alpha.3",
"@verdaccio/types": "workspace:11.0.0-alpha.3",
"jest-mock-process": "^1.4.0"
"@verdaccio/mock": "workspace:6.0.0-6-next.4",
"@verdaccio/types": "workspace:11.0.0-6-next.4",
"jest-mock-process": "^1.4.0",
"selfsigned": "1.10.7",
"supertest": "^6.1.3"
},
"publishConfig": {
"access": "public"

View File

@@ -1,25 +0,0 @@
import { Application } from 'express';
import { Callback } from '@verdaccio/types';
/**
* Trigger the server after configuration has been loaded.
* @param {Object} config
* @param {Object} cliArguments
* @param {String} configPath
* @param {String} pkgVersion
* @param {String} pkgName
*/
declare function startVerdaccio(
config: any,
cliListen: string,
configPath: string,
pkgVersion: string,
pkgName: string,
callback: Callback
): void;
declare function listenDefaultCallback(
webServer: Application,
addr: any,
pkgName: string,
pkgVersion: string
): void;
export { startVerdaccio, listenDefaultCallback };

View File

@@ -1,196 +0,0 @@
import URL from 'url';
import fs from 'fs';
import http from 'http';
import https from 'https';
import constants from 'constants';
import { Application } from 'express';
import { assign, isObject, isFunction } from 'lodash';
import buildDebug from 'debug';
import { displayError, displayMessage, displayLink } from '@verdaccio/cli-ui';
import {
ConfigRuntime,
Callback,
ConfigWithHttps,
HttpsConfKeyCert,
HttpsConfPfx,
} from '@verdaccio/types';
import { API_ERROR } from '@verdaccio/commons-api';
import server from '@verdaccio/server';
export const keyPem = 'verdaccio-key.pem';
export const certPem = 'verdaccio-cert.pem';
export const csrPem = 'verdaccio-csr.pem';
import { getListListenAddresses, resolveConfigPath } from './cli-utils';
import { displayExperimentsInfoBox } from './experiments';
const debug = buildDebug('verdaccio:runtime');
function launchServer(
app,
addr,
config,
configPath: string,
pkgVersion: string,
pkgName: string,
callback: Callback
): void {
let webServer;
if (addr.proto === 'https') {
debug('https enabled');
webServer = handleHTTPS(app, configPath, config);
} else {
// http
debug('http enabled');
webServer = http.createServer(app);
}
if (
config.server &&
typeof config.server.keepAliveTimeout !== 'undefined' &&
config.server.keepAliveTimeout !== 'null'
) {
// library definition for node is not up to date (doesn't contain recent 8.0 changes)
webServer.keepAliveTimeout = config.server.keepAliveTimeout * 1000;
}
unlinkAddressPath(addr);
callback(webServer, addr, pkgName, pkgVersion);
}
async function startVerdaccio(
config: ConfigRuntime,
cliListen: string,
configPath: string,
pkgVersion: string,
pkgName: string,
callback: Callback
): Promise<void> {
if (isObject(config) === false) {
throw new Error(API_ERROR.CONFIG_BAD_FORMAT);
}
const app = await server(config);
const addresses = getListListenAddresses(cliListen, config.listen);
displayExperimentsInfoBox(config.flags);
addresses.forEach((addr) =>
launchServer(app, addr, config, configPath, pkgVersion, pkgName, callback)
);
}
function unlinkAddressPath(addr) {
if (addr.path && fs.existsSync(addr.path)) {
fs.unlinkSync(addr.path);
}
}
function logHTTPSError(storageLocation) {
displayError(
[
'You have enabled HTTPS and need to specify either ',
' "https.key" and "https.cert" or ',
' "https.pfx" and optionally "https.passphrase" ',
'to run https server',
'',
// commands are borrowed from node.js docs
'To quickly create self-signed certificate, use:',
' $ openssl genrsa -out ' + resolveConfigPath(storageLocation, keyPem) + ' 2048',
' $ openssl req -new -sha256 -key ' +
resolveConfigPath(storageLocation, keyPem) +
' -out ' +
resolveConfigPath(storageLocation, csrPem),
' $ openssl x509 -req -in ' +
resolveConfigPath(storageLocation, csrPem) +
' -signkey ' +
resolveConfigPath(storageLocation, keyPem) +
' -out ' +
resolveConfigPath(storageLocation, certPem),
'',
'And then add to config file (' + storageLocation + '):',
' https:',
` key: ${resolveConfigPath(storageLocation, keyPem)}`,
` cert: ${resolveConfigPath(storageLocation, certPem)}`,
].join('\n')
);
displayError(displayLink('https://verdaccio.org/docs/en/configuration#https'));
process.exit(2);
}
function handleHTTPS(app: Application, configPath: string, config: ConfigWithHttps): https.Server {
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)) {
logHTTPSError(configPath);
process.exit(1);
}
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),
}),
});
}
return https.createServer(httpsOptions, app);
} catch (err) {
displayError(`cannot create server: ${err.message}`);
process.exit(2);
}
}
function listenDefaultCallback(
webServer: Application,
addr: any,
pkgName: string,
pkgVersion: string
): void {
webServer
.listen(addr.port || addr.path, addr.host, (): void => {
// send a message for test
if (isFunction(process.send)) {
process.send({
verdaccio_started: true,
});
}
const addressServer = `${
addr.path
? URL.format({
protocol: 'unix',
pathname: addr.path,
})
: URL.format({
protocol: addr.proto,
hostname: addr.host,
port: addr.port,
pathname: '/',
})
}`;
displayMessage(`http address ${displayLink(addressServer)}`);
displayMessage(`${pkgName} / ${pkgVersion}`);
})
.on('error', function (err): void {
displayError(`cannot create server: ${err.message}`);
process.exit(2);
});
}
export { startVerdaccio, listenDefaultCallback };

View File

@@ -1,7 +1,3 @@
import path from 'path';
import { displayLink, displayWarning } from '@verdaccio/cli-ui';
export const DEFAULT_PORT = '4873';
export const DEFAULT_PROTOCOL = 'http';
export const DEFAULT_DOMAIN = 'localhost';
@@ -46,10 +42,6 @@ export function parseAddress(urlAddress: any): any {
return null;
}
export const resolveConfigPath = function (storageLocation: string, file: string) {
return path.resolve(path.dirname(storageLocation), file);
};
/**
* Retrieve all addresses defined in the config file.
* Verdaccio is able to listen multiple ports
@@ -61,7 +53,7 @@ export const resolveConfigPath = function (storageLocation: string, file: string
- 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) {
@@ -78,11 +70,11 @@ export function getListListenAddresses(argListen: string, configListen: any): an
const parsedAddr = parseAddress(addr);
if (!parsedAddr) {
displayWarning(
process.emitWarning(
// eslint-disable-next-line max-len
`invalid address - ${addr}, we expect a port (e.g. "4873"), host:port (e.g. "localhost:4873") or full url '(e.g. "http://localhost:4873/")`
);
displayWarning(displayLink('https://verdaccio.org/docs/en/configuration#listen-port'));
process.emitWarning('https://verdaccio.org/docs/en/configuration#listen-port');
}
return parsedAddr;

View File

@@ -1 +1 @@
export { listenDefaultCallback, startVerdaccio } from './bootstrap';
export { initServer, runServer } from './server';

View File

@@ -0,0 +1,186 @@
/* eslint-disable */
import _, { assign, isFunction } from 'lodash';
import http from 'http';
import https from 'https';
import constants from 'constants';
import buildDebug from 'debug';
import fs from 'fs';
import url from 'url';
import { findConfigFile, parseConfigFile } from '@verdaccio/config';
import { API_ERROR } from '@verdaccio/commons-api';
import { ConfigRuntime, HttpsConfKeyCert, HttpsConfPfx } from '@verdaccio/types';
import { setup } from '@verdaccio/logger';
import server from '@verdaccio/server';
import { getListListenAddresses } from './cli-utils';
import { displayExperimentsInfoBox } from './experiments';
const debug = buildDebug('verdaccio:node-api');
function unlinkAddressPath(addr) {
if (addr.path && fs.existsSync(addr.path)) {
fs.unlinkSync(addr.path);
}
}
/**
* 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)) {
// logHTTPSError(configPath);
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;
}
/**
* Start the server on the port defined
* @param config
* @param port
* @param version
* @param pkgName
*/
export async function initServer(
config: ConfigRuntime,
port: string | void,
version: string,
pkgName: string
): Promise<void> {
return new Promise(async (resolve, reject) => {
// FIXME: get only the first match, the multiple address will be removed
const [addr] = getListListenAddresses(port, config.listen);
const logger = setup((config as ConfigRuntime).logs);
displayExperimentsInfoBox(config.flags);
const app = await server(config);
const serverFactory = createServerFactory(config, addr, app);
serverFactory
.listen(addr.port || addr.path, addr.host, (): void => {
// send a message for test
if (isFunction(process.send)) {
process.send({
verdaccio_started: true,
});
}
const addressServer = `${
addr.path
? url.format({
protocol: 'unix',
pathname: addr.path,
})
: url.format({
protocol: addr.proto,
hostname: addr.host,
port: addr.port,
pathname: '/',
})
}`;
console.log(`http address ${addressServer}`);
console.log(`${pkgName} / ${version}`);
resolve();
})
.on('error', function (err): void {
reject(err);
process.exitCode = 1;
});
function handleShutdownGracefully() {
logger.fatal('received shutdown signal - closing server gracefully...');
serverFactory.close(() => {
logger.info('server closed.');
process.exit(0);
});
}
process.on('SIGINT', handleShutdownGracefully);
process.on('SIGTERM', handleShutdownGracefully);
process.on('SIGHUP', handleShutdownGracefully);
});
}
/**
* 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 | ConfigRuntime): Promise<any> {
let configurationParsed: ConfigRuntime;
if (config === undefined || typeof config === 'string') {
const configPathLocation = findConfigFile(config);
configurationParsed = parseConfigFile(configPathLocation);
} else if (_.isObject(config)) {
configurationParsed = config;
} else {
throw new Error(API_ERROR.CONFIG_BAD_FORMAT);
}
setup(configurationParsed.logs);
displayExperimentsInfoBox(configurationParsed.flags);
// FIXME: get only the first match, the multiple address will be removed
const [addr] = getListListenAddresses(undefined, configurationParsed.listen);
const app = await server(configurationParsed);
return createServerFactory(configurationParsed, addr, app);
}

View File

@@ -1,183 +0,0 @@
import path from 'path';
import os from 'os';
import fs from 'fs';
import selfsigned from 'selfsigned';
import { configExample } from '@verdaccio/mock';
import { parseConfigFile } from '@verdaccio/config';
import { startVerdaccio } from '../src';
import { DEFAULT_DOMAIN, DEFAULT_PROTOCOL } from '../src/cli-utils';
const mockProcess = require('jest-mock-process');
describe('startServer via API', () => {
const parseConfigurationFile = (name) => {
return parseConfigFile(path.join(__dirname, `./partials/config/yaml/${name}.yaml`));
};
describe('startServer launcher', () => {
test('should provide all HTTP server data', async (done) => {
const store = path.join(__dirname, 'partials/store');
const serverName = 'verdaccio-test';
const version = '1.0.0';
const port = '6000';
await startVerdaccio(
configExample(),
port,
store,
version,
serverName,
(webServer, addrs, pkgName, pkgVersion) => {
expect(webServer).toBeDefined();
expect(addrs).toBeDefined();
expect(addrs.proto).toBe(DEFAULT_PROTOCOL);
expect(addrs.host).toBe(DEFAULT_DOMAIN);
expect(addrs.port).toBe(port);
expect(pkgName).toBeDefined();
expect(pkgVersion).toBeDefined();
expect(pkgVersion).toBe(version);
expect(pkgName).toBe(serverName);
done();
}
);
});
test('should set keepAliveTimeout to 0 seconds', async (done) => {
const store = path.join(__dirname, 'partials/store');
const serverName = 'verdaccio-test';
const version = '1.0.0';
const port = '6100';
await startVerdaccio(
configExample(parseConfigurationFile('server/keepalivetimeout-0')),
port,
store,
version,
serverName,
(webServer, addrs, pkgName, pkgVersion) => {
expect(webServer).toBeDefined();
expect(webServer.keepAliveTimeout).toBeDefined();
expect(webServer.keepAliveTimeout).toBe(0);
expect(addrs).toBeDefined();
expect(addrs.proto).toBe(DEFAULT_PROTOCOL);
expect(addrs.host).toBe(DEFAULT_DOMAIN);
expect(addrs.port).toBe(port);
expect(pkgName).toBeDefined();
expect(pkgVersion).toBeDefined();
expect(pkgVersion).toBe(version);
expect(pkgName).toBe(serverName);
done();
}
);
});
test('should set keepAliveTimeout to 60 seconds', async (done) => {
const store = path.join(__dirname, 'partials/store');
const serverName = 'verdaccio-test';
const version = '1.0.0';
const port = '6200';
await startVerdaccio(
configExample(parseConfigurationFile('server/keepalivetimeout-60')),
port,
store,
version,
serverName,
(webServer, addrs, pkgName, pkgVersion) => {
expect(webServer).toBeDefined();
expect(webServer.keepAliveTimeout).toBeDefined();
expect(webServer.keepAliveTimeout).toBe(60000);
expect(addrs).toBeDefined();
expect(addrs.proto).toBe(DEFAULT_PROTOCOL);
expect(addrs.host).toBe(DEFAULT_DOMAIN);
expect(addrs.port).toBe(port);
expect(pkgName).toBeDefined();
expect(pkgVersion).toBeDefined();
expect(pkgVersion).toBe(version);
expect(pkgName).toBe(serverName);
done();
}
);
});
test('should set keepAliveTimeout to 5 seconds per default', async (done) => {
const store = path.join(__dirname, 'partials/store');
const serverName = 'verdaccio-test';
const version = '1.0.0';
const port = '6300';
await startVerdaccio(
configExample(parseConfigurationFile('server/keepalivetimeout-undefined')),
port,
store,
version,
serverName,
(webServer, addrs, pkgName, pkgVersion) => {
expect(webServer).toBeDefined();
expect(webServer.keepAliveTimeout).toBeDefined();
expect(webServer.keepAliveTimeout).toBe(5000);
expect(addrs).toBeDefined();
expect(addrs.proto).toBe(DEFAULT_PROTOCOL);
expect(addrs.host).toBe(DEFAULT_DOMAIN);
expect(addrs.port).toBe(port);
expect(pkgName).toBeDefined();
expect(pkgVersion).toBeDefined();
expect(pkgVersion).toBe(version);
expect(pkgName).toBe(serverName);
done();
}
);
});
test('should provide all HTTPS server fails', async (done) => {
let mockExit = mockProcess.mockProcessExit();
const store = path.join(__dirname, 'partials/store');
const serverName = 'verdaccio-test';
const version = '1.0.0';
const address = 'https://www.domain.com:443';
const conf = configExample({});
conf.https = {};
// save process to catch exist
await startVerdaccio(conf, address, store, version, serverName, () => {
expect(mockExit).toHaveBeenCalledWith(2);
done();
});
});
test('should start a https server with key and cert', async (done) => {
const store = path.join(__dirname, 'partials/store');
const serverName = 'verdaccio-test';
const version = '1.0.0';
const address = 'https://www.domain.com:443';
const { private: key, cert } = selfsigned.generate();
const keyPath = path.join(os.tmpdir(), 'key.pem');
const certPath = path.join(os.tmpdir(), 'crt.pem');
fs.writeFileSync(keyPath, key);
fs.writeFileSync(certPath, cert);
const conf = configExample();
conf.https = {
key: keyPath,
cert: certPath,
};
await startVerdaccio(conf, address, store, version, serverName, (webServer, addrs) => {
expect(webServer).toBeDefined();
expect(addrs).toBeDefined();
expect(addrs.proto).toBe('https');
done();
});
});
test('should fails if config is missing', async () => {
try {
// @ts-ignore
await startVerdaccio();
} catch (e) {
expect(e.message).toEqual('config file must be an object');
}
});
});
});

View File

@@ -0,0 +1,20 @@
import request from 'supertest';
import { runServer } from '../src';
describe('startServer via API', () => {
test('should provide all HTTP server data', async () => {
const webServer = await runServer();
expect(webServer).toBeDefined();
await request(webServer).get('/').expect(200);
});
test('should fail on start with empty configuration', async () => {
// @ts-expect-error
await expect(runServer({})).rejects.toThrow(
'AssertionError [ERR_ASSERTION]: CONFIG: storage path not defined'
);
});
test('should fail on start with null as entry', async () => {
await expect(runServer(null)).rejects.toThrow('config file must be an object');
});
});

View File

@@ -39,7 +39,7 @@
},
"devDependencies": {
"@types/activedirectory2": "^1.2.1",
"@verdaccio/types": "workspace:11.0.0-alpha.3"
"@verdaccio/types": "workspace:11.0.0-6-next.4"
},
"scripts": {
"clean": "rimraf ./build",

View File

@@ -36,7 +36,7 @@
"node-fetch": "^2.6.0"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-alpha.3",
"@verdaccio/types": "workspace:11.0.0-6-next.4",
"body-parser": "^1.19.0",
"nock": "^12.0.3",
"supertest": "^4.0.2"

View File

@@ -35,7 +35,7 @@
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-alpha.3"
"@verdaccio/types": "workspace:11.0.0-6-next.4"
},
"scripts": {
"clean": "rimraf ./build",

View File

@@ -36,7 +36,7 @@
"aws-sdk": "^2.607.0"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-alpha.3",
"@verdaccio/types": "workspace:11.0.0-6-next.4",
"recursive-readdir": "2.2.2"
},
"scripts": {

View File

@@ -1,5 +1,32 @@
# Change Log
## 11.0.0-6-next.5
### Major Changes
- 5c5057fc: feat: node api new structure based on promise
```js
import { runServer } from '@verdaccio/node-api';
// or
import { runServer } from 'verdaccio';
const app = await runServer(); // default configuration
const app = await runServer('./config/config.yaml');
const app = await runServer({ configuration });
app.listen(4000, event => {
// do something
});
```
### Breaking Change
If you are using the node-api, the new structure is Promise based and less arguments.
### Patch Changes
- @verdaccio/streams@11.0.0-alpha.3
## 11.0.0-6-next.4
### Major Changes

View File

@@ -1,6 +1,6 @@
{
"name": "verdaccio-google-cloud",
"version": "11.0.0-6-next.4",
"version": "11.0.0-6-next.5",
"description": "Google Cloud storage implementation for Verdaccio",
"keywords": [
"private",
@@ -37,7 +37,7 @@
"@verdaccio/streams": "workspace:11.0.0-alpha.3"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-alpha.3",
"@verdaccio/types": "workspace:11.0.0-6-next.4",
"memory-fs": "0.5.0"
},
"optionalDependencies": {

View File

@@ -1,7 +1,7 @@
import _ from 'lodash';
import { Logger, ILocalPackageManager } from '@verdaccio/types';
import { VerdaccioError } from '@verdaccio/commons-api';
import { HTTP_STATUS } from '@verdaccio/commons-api/lib';
import { HTTP_STATUS } from '@verdaccio/commons-api';
import { ERROR_MISSING_CONFIG } from '../src/data-storage';
import { VerdaccioConfigGoogleStorage } from '../src/types';

View File

@@ -38,7 +38,7 @@
"memfs": "3.2.0"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-alpha.3"
"@verdaccio/types": "workspace:11.0.0-6-next.4"
},
"scripts": {
"clean": "rimraf ./build",

View File

@@ -29,7 +29,7 @@
"@testing-library/dom": "^7.29.0",
"@testing-library/jest-dom": "^5.11.6",
"@testing-library/react": "10.4.9",
"@verdaccio/node-api": "workspace:6.0.0-6-next.9",
"@verdaccio/node-api": "workspace:6.0.0-6-next.10",
"autosuggest-highlight": "3.1.1",
"babel-loader": "^8.2.2",
"babel-plugin-dynamic-import-node": "^2.3.3",

View File

@@ -1,5 +1,15 @@
# @verdaccio/proxy
## 6.0.0-6-next.6
### Patch Changes
- Updated dependencies [5c5057fc]
- @verdaccio/config@6.0.0-6-next.4
- @verdaccio/logger@6.0.0-6-next.4
- @verdaccio/local-storage@11.0.0-6-next.5
- @verdaccio/streams@11.0.0-alpha.3
## 6.0.0-6-next.5
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/proxy",
"version": "6.0.0-6-next.5",
"version": "6.0.0-6-next.6",
"description": "verdaccio proxy fetcher",
"main": "./build/index.js",
"types": "build/index.d.ts",
@@ -40,9 +40,9 @@
},
"dependencies": {
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-6-next.4",
"@verdaccio/local-storage": "workspace:11.0.0-6-next.5",
"@verdaccio/logger": "workspace:6.0.0-alpha.3",
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
"@verdaccio/streams": "workspace:11.0.0-alpha.3",
"@verdaccio/utils": "workspace:6.0.0-alpha.3",
"JSONStream": "1.3.5",
@@ -50,7 +50,7 @@
"request": "2.87.0"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-alpha.3"
"@verdaccio/types": "workspace:11.0.0-6-next.4"
},
"funding": {
"type": "opencollective",

View File

@@ -1,5 +1,20 @@
# @verdaccio/server
## 6.0.0-6-next.9
### Patch Changes
- Updated dependencies [5c5057fc]
- @verdaccio/config@6.0.0-6-next.4
- @verdaccio/logger@6.0.0-6-next.4
- @verdaccio/api@6.0.0-6-next.8
- @verdaccio/auth@6.0.0-6-next.6
- @verdaccio/loaders@6.0.0-6-next.4
- @verdaccio/store@6.0.0-6-next.6
- @verdaccio/web@6.0.0-6-next.9
- verdaccio-audit@11.0.0-alpha.4
- @verdaccio/middleware@6.0.0-6-next.6
## 6.0.0-6-next.8
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/server",
"version": "6.0.0-6-next.8",
"version": "6.0.0-6-next.9",
"description": "server logic",
"main": "./build/index.js",
"types": "build/index.d.ts",
@@ -30,16 +30,16 @@
"npm": ">=6"
},
"dependencies": {
"@verdaccio/api": "workspace:6.0.0-6-next.7",
"@verdaccio/auth": "workspace:6.0.0-alpha.5",
"@verdaccio/api": "workspace:6.0.0-6-next.8",
"@verdaccio/auth": "workspace:6.0.0-6-next.6",
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-alpha.3",
"@verdaccio/loaders": "workspace:6.0.0-alpha.3",
"@verdaccio/logger": "workspace:6.0.0-alpha.3",
"@verdaccio/middleware": "workspace:6.0.0-alpha.5",
"@verdaccio/store": "workspace:6.0.0-6-next.5",
"@verdaccio/config": "workspace:6.0.0-6-next.4",
"@verdaccio/loaders": "workspace:6.0.0-6-next.4",
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
"@verdaccio/middleware": "workspace:6.0.0-6-next.6",
"@verdaccio/store": "workspace:6.0.0-6-next.6",
"@verdaccio/utils": "workspace:6.0.0-alpha.3",
"@verdaccio/web": "workspace:6.0.0-6-next.8",
"@verdaccio/web": "workspace:6.0.0-6-next.9",
"verdaccio-audit": "workspace:11.0.0-alpha.4",
"compression": "1.7.4",
"cors": "2.8.5",
@@ -48,8 +48,8 @@
"lodash": "4.17.15"
},
"devDependencies": {
"@verdaccio/mock": "workspace:6.0.0-alpha.3",
"@verdaccio/proxy": "workspace:6.0.0-6-next.5",
"@verdaccio/mock": "workspace:6.0.0-6-next.4",
"@verdaccio/proxy": "workspace:6.0.0-6-next.6",
"http-errors": "1.7.3",
"request": "2.87.0"
},

View File

@@ -32,7 +32,7 @@
"homepage": "https://verdaccio.org",
"license": "MIT",
"devDependencies": {
"@verdaccio/cli": "workspace:6.0.0-6-next.9",
"@verdaccio/cli": "workspace:6.0.0-6-next.10",
"@verdaccio/ui-theme": "workspace:6.0.0-alpha.5",
"fs-extra": "9.0.1",
"webpack": "^5.11.1",

View File

@@ -1,5 +1,17 @@
# @verdaccio/store
## 6.0.0-6-next.6
### Patch Changes
- Updated dependencies [5c5057fc]
- @verdaccio/config@6.0.0-6-next.4
- @verdaccio/logger@6.0.0-6-next.4
- @verdaccio/loaders@6.0.0-6-next.4
- @verdaccio/proxy@6.0.0-6-next.6
- @verdaccio/local-storage@11.0.0-6-next.5
- @verdaccio/streams@11.0.0-alpha.3
## 6.0.0-6-next.5
### Major Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/store",
"version": "6.0.0-6-next.5",
"version": "6.0.0-6-next.6",
"description": "loaders logic",
"main": "./build/index.js",
"types": "build/index.d.ts",
@@ -40,11 +40,11 @@
},
"dependencies": {
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-alpha.3",
"@verdaccio/loaders": "workspace:6.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-6-next.4",
"@verdaccio/loaders": "workspace:6.0.0-6-next.4",
"@verdaccio/local-storage": "workspace:11.0.0-6-next.5",
"@verdaccio/logger": "workspace:6.0.0-alpha.3",
"@verdaccio/proxy": "workspace:6.0.0-6-next.5",
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
"@verdaccio/proxy": "workspace:6.0.0-6-next.6",
"@verdaccio/streams": "workspace:11.0.0-alpha.3",
"@verdaccio/utils": "workspace:6.0.0-alpha.3",
"async": "3.1.1",
@@ -54,8 +54,8 @@
"semver": "7.1.2"
},
"devDependencies": {
"@verdaccio/mock": "workspace:6.0.0-alpha.3",
"@verdaccio/types": "workspace:11.0.0-alpha.3"
"@verdaccio/mock": "workspace:6.0.0-6-next.4",
"@verdaccio/types": "workspace:11.0.0-6-next.4"
},
"funding": {
"type": "opencollective",

View File

@@ -1,5 +1,38 @@
# verdaccio
## 6.0.0-6-next.11
### Major Changes
- 5c5057fc: feat: node api new structure based on promise
```js
import { runServer } from '@verdaccio/node-api';
// or
import { runServer } from 'verdaccio';
const app = await runServer(); // default configuration
const app = await runServer('./config/config.yaml');
const app = await runServer({ configuration });
app.listen(4000, event => {
// do something
});
```
### Breaking Change
If you are using the node-api, the new structure is Promise based and less arguments.
### Patch Changes
- Updated dependencies [5c5057fc]
- @verdaccio/cli@6.0.0-6-next.10
- @verdaccio/logger@6.0.0-6-next.4
- @verdaccio/node-api@6.0.0-6-next.10
- @verdaccio/hooks@6.0.0-6-next.4
- @verdaccio/mock@6.0.0-6-next.4
- @verdaccio/ui-theme@6.0.0-alpha.5
## 6.0.0-6-next.10
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "verdaccio",
"version": "6.0.0-6-next.10",
"version": "6.0.0-6-next.11",
"description": "A lightweight private npm proxy registry",
"main": "build/index.js",
"types": "build/index.d.ts",
@@ -36,21 +36,21 @@
},
"homepage": "https://verdaccio.org",
"dependencies": {
"@verdaccio/cli": "workspace:6.0.0-6-next.9",
"@verdaccio/hooks": "workspace:6.0.0-alpha.3",
"@verdaccio/logger": "workspace:6.0.0-alpha.3",
"@verdaccio/mock": "workspace:6.0.0-alpha.3",
"@verdaccio/node-api": "workspace:6.0.0-6-next.9",
"@verdaccio/cli": "workspace:6.0.0-6-next.10",
"@verdaccio/hooks": "workspace:6.0.0-6-next.4",
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
"@verdaccio/mock": "workspace:6.0.0-6-next.4",
"@verdaccio/node-api": "workspace:6.0.0-6-next.10",
"@verdaccio/ui-theme": "workspace:6.0.0-alpha.5",
"@verdaccio/utils": "workspace:6.0.0-alpha.3",
"verdaccio-audit": "11.0.0-alpha.4",
"verdaccio-htpasswd": "11.0.0-alpha.6"
},
"devDependencies": {
"@verdaccio/auth": "workspace:6.0.0-alpha.5",
"@verdaccio/auth": "workspace:6.0.0-6-next.6",
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-alpha.3",
"@verdaccio/store": "workspace:6.0.0-6-next.5"
"@verdaccio/config": "workspace:6.0.0-6-next.4",
"@verdaccio/store": "workspace:6.0.0-6-next.6"
},
"keywords": [
"private",

View File

@@ -1,3 +1 @@
// @verdaccio-cli is only accesible via .bin/ folder
export { listenDefaultCallback, startVerdaccio } from '@verdaccio/node-api';
export { runServer } from '@verdaccio/node-api';

View File

@@ -1,5 +1,20 @@
# @verdaccio/web
## 6.0.0-6-next.9
### Patch Changes
- Updated dependencies [5c5057fc]
- @verdaccio/config@6.0.0-6-next.4
- @verdaccio/logger@6.0.0-6-next.4
- @verdaccio/auth@6.0.0-6-next.6
- @verdaccio/loaders@6.0.0-6-next.4
- @verdaccio/store@6.0.0-6-next.6
- @verdaccio/readme@11.0.0-alpha.3
- @verdaccio/tarball@11.0.0-6-next.4
- @verdaccio/url@11.0.0-6-next.4
- @verdaccio/middleware@6.0.0-6-next.6
## 6.0.0-6-next.8
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/web",
"version": "6.0.0-6-next.8",
"version": "6.0.0-6-next.9",
"description": "web ui middleware",
"main": "./build/index.js",
"types": "build/index.d.ts",
@@ -25,14 +25,14 @@
},
"license": "MIT",
"dependencies": {
"@verdaccio/auth": "workspace:6.0.0-alpha.5",
"@verdaccio/auth": "workspace:6.0.0-6-next.6",
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-alpha.3",
"@verdaccio/loaders": "workspace:6.0.0-alpha.3",
"@verdaccio/logger": "workspace:6.0.0-alpha.3",
"@verdaccio/middleware": "workspace:6.0.0-alpha.5",
"@verdaccio/config": "workspace:6.0.0-6-next.4",
"@verdaccio/loaders": "workspace:6.0.0-6-next.4",
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
"@verdaccio/middleware": "workspace:6.0.0-6-next.6",
"@verdaccio/readme": "workspace:11.0.0-alpha.3",
"@verdaccio/store": "workspace:6.0.0-6-next.5",
"@verdaccio/store": "workspace:6.0.0-6-next.6",
"@verdaccio/utils": "workspace:6.0.0-alpha.3",
"@verdaccio/url": "workspace:11.0.0-6-next.4",
"@verdaccio/tarball": "workspace:11.0.0-6-next.4",
@@ -44,7 +44,7 @@
"lodash": "^4.17.20"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-alpha.3",
"@verdaccio/types": "workspace:11.0.0-6-next.4",
"verdaccio-auth-memory": "workspace:11.0.0-alpha.3",
"verdaccio-memory": "workspace:11.0.0-6-next.4",
"supertest": "^6.1.3",

694
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,23 +0,0 @@
import buildDebug from 'debug';
export type Manifest = {
// goes on first place at the header
ico: string;
css: string[];
js: string[];
};
const debug = buildDebug('verdaccio');
export function getManifestValue(
manifestItems: string[],
manifest,
basePath: string = ''
): string[] {
return manifestItems?.map((item) => {
debug('resolve item %o', item);
const resolvedItem = `${basePath}${manifest[item]}`;
debug('resolved item %o', resolvedItem);
return resolvedItem;
});
}

View File

@@ -1,95 +0,0 @@
import { URL } from 'url';
import buildDebug from 'debug';
import LRU from 'lru-cache';
import { HEADERS } from '@verdaccio/commons-api';
import { getPublicUrl } from '../../../lib/utils';
import { WEB_TITLE } from '../../../lib/constants';
import renderTemplate from './template';
const pkgJSON = require('../../../../package.json');
const DEFAULT_LANGUAGE = 'es-US';
const cache = new LRU({ max: 500, maxAge: 1000 * 60 * 60 });
const debug = buildDebug('verdaccio');
const defaultManifestFiles = {
js: ['runtime.js', 'vendors.js', 'main.js'],
ico: 'favicon.ico',
};
export function validatePrimaryColor(primaryColor) {
const isHex = /^#+([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/i.test(primaryColor);
if (!isHex) {
debug('invalid primary color %o', primaryColor);
return;
}
return primaryColor;
}
export default function renderHTML(config, manifest, manifestFiles, req, res) {
const { url_prefix } = config;
const base = getPublicUrl(config?.url_prefix, req);
const basename = new URL(base).pathname;
const language = config?.i18n?.web ?? DEFAULT_LANGUAGE;
const darkMode = config?.web?.darkMode ?? false;
const title = config?.web?.title ?? WEB_TITLE;
const scope = config?.web?.scope ?? '';
// FIXME: logo URI is incomplete
let logoURI = config?.web?.logo ?? '';
const version = pkgJSON.version;
const primaryColor = validatePrimaryColor(config?.web?.primary_color) ?? '#4b5e40';
const { scriptsBodyAfter, metaScripts, scriptsbodyBefore } = Object.assign(
{},
{
scriptsBodyAfter: [],
bodyBefore: [],
metaScripts: [],
},
config?.web
);
const options = {
darkMode,
url_prefix,
basename,
base,
primaryColor,
version,
logoURI,
title,
scope,
language,
};
let webPage;
try {
webPage = cache.get('template');
if (!webPage) {
debug('web options %o', options);
debug('web manifestFiles %o', manifestFiles);
webPage = renderTemplate(
{
manifest: manifestFiles ?? defaultManifestFiles,
options,
scriptsBodyAfter,
metaScripts,
scriptsbodyBefore,
},
manifest
);
debug('template :: %o', webPage);
cache.set('template', webPage);
debug('set template cache');
} else {
debug('reuse template cache');
}
} catch (error) {
throw new Error(`theme could not be load, stack ${error.stack}`);
}
res.setHeader('Content-Type', HEADERS.TEXT_HTML);
res.send(webPage);
debug('render web');
}

View File

@@ -1,62 +0,0 @@
import buildDebug from 'debug';
import { getManifestValue, Manifest } from './manifest';
const debug = buildDebug('verdaccio');
export type TemplateUIOptions = {
title?: string;
uri?: string;
darkMode?: boolean;
protocol?: string;
host?: string;
url_prefix?: string;
base: string;
primaryColor?: string;
version?: string;
logoURI?: string;
scope?: string;
language?: string;
};
export type Template = {
manifest: Manifest;
options: TemplateUIOptions;
metaScripts?: string[];
scriptsBodyAfter?: string[];
scriptsbodyBefore?: string[];
};
// the outcome of the Webpack Manifest Plugin
export interface WebpackManifest {
[key: string]: string;
}
export default function renderTemplate(template: Template, manifest: WebpackManifest) {
debug('template %o', template);
debug('manifest %o', manifest);
return `
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<base href="${template?.options.base}">
<title>${template?.options?.title ?? ''}</title>
<link rel="icon" href="${template?.options.base}-/static/favicon.ico"/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script>
window.__VERDACCIO_BASENAME_UI_OPTIONS=${JSON.stringify(template.options)}
</script>
${template?.metaScripts ? template.metaScripts.join('') : ''}
</head>
<body class="body">
${template?.scriptsbodyBefore ? template.scriptsbodyBefore.join('') : ''}
<div id="root"></div>
${getManifestValue(template.manifest.js, manifest, template?.options.base)
.map((item) => `<script defer="defer" src="${item}"></script>`)
.join('')}
${template?.scriptsBodyAfter ? template.scriptsBodyAfter.join('') : ''}
</body>
</html>
`;
}

View File

@@ -1,33 +0,0 @@
import { Cli } from 'clipanion';
import { InfoCommand } from './commands/info';
import { InitCommand } from './commands/init';
import { isVersionValid, MIN_NODE_VERSION } from './utils';
import { VersionCommand } from './commands/version';
require('pkginfo')(module);
const pkgVersion = module.exports.version;
if (process.getuid && process.getuid() === 0) {
process.emitWarning(`Verdaccio doesn't need superuser privileges. don't run it under root`);
}
if (!isVersionValid(process.version)) {
throw new Error(
// eslint-disable-next-line max-len
`Verdaccio requires at least Node.js v${MIN_NODE_VERSION} or higher and you have installed ${process.version},
please upgrade your Node.js distribution`
);
}
const [node, app, ...args] = process.argv;
const cli = new Cli({
binaryLabel: `verdaccio`,
binaryName: `${node} ${app}`,
binaryVersion: pkgVersion,
});
cli.register(InfoCommand);
cli.register(InitCommand);
cli.register(VersionCommand);
cli.runExit(args, Cli.defaultContext);

View File

@@ -1,20 +0,0 @@
import envinfo from 'envinfo';
import { Command } from 'clipanion';
export class InfoCommand extends Command {
static paths = [[`--info`], [`-i`]];
async execute() {
this.context.stdout.write('\nEnvironment Info:');
const data = await envinfo.run({
System: ['OS', 'CPU'],
Binaries: ['node', 'yarn', 'npm', 'pnpm'],
Virtualization: ['Docker'],
Browsers: ['Chrome', 'Edge', 'Firefox', 'Safari'],
npmGlobalPackages: ['verdaccio'],
});
this.context.stdout.write(data);
process.exit(0);
}
}

View File

@@ -1,79 +0,0 @@
import path from 'path';
import { Command, Option } from 'clipanion';
import { startVerdaccio, listenDefaultCallback } from '../../bootstrap';
import findConfigFile from '../../config-path';
import { parseConfigFile } from '../../utils';
require('pkginfo')(module);
const pkgVersion = module.exports.version;
const pkgName = module.exports.name;
export const DEFAULT_PROCESS_NAME: string = 'verdaccio';
const logger = require('../../logger');
export class InitCommand extends Command {
static paths = [Command.Default];
listen = Option.String('-l,--listen', {
description: 'host:port number to listen on (default: localhost:4873)',
});
// eslint-disable-next-line
static usage = Command.Usage({
description: `launch the server`,
details: `
This start the registry in the default port.
When used without arguments, it:
- bootstrap the server at the port \`4873\`
The optional arguments are:
- \`--listen\` to switch the default server port,
- \`--config\` to define a different configuration path location,
`,
examples: [
[`Runs the server with the default configuration`, `verdaccio`],
[`Runs the server in the port 5000`, `verdaccio --listen 5000`],
[
`Runs the server by using a different absolute location of the configuration file`,
`verdaccio --config /home/user/verdaccio/config.yaml`,
],
],
});
config = Option.String('-c,--config', {
description: 'use this configuration file (default: ./config.yaml)',
});
async execute() {
try {
const configPathLocation = findConfigFile(this.config as string);
const verdaccioConfiguration = parseConfigFile(configPathLocation);
if (!verdaccioConfiguration.self_path) {
verdaccioConfiguration.self_path = path.resolve(configPathLocation);
}
if (!verdaccioConfiguration.https) {
verdaccioConfiguration.https = { enable: false };
}
logger.logger.warn({ file: configPathLocation }, 'config file - @{file}');
process.title =
(verdaccioConfiguration.web && verdaccioConfiguration.web.title) || 'verdaccio';
startVerdaccio(
verdaccioConfiguration,
this.listen as string,
configPathLocation,
pkgVersion,
pkgName,
listenDefaultCallback
);
} catch (err) {
process.exit(1);
}
}
}

View File

@@ -1,12 +0,0 @@
import { Command } from 'clipanion';
require('pkginfo')(module);
const pkgVersion = module.exports.version;
export class VersionCommand extends Command {
static paths = [[`--version`], [`-v`]];
async execute() {
this.context.stdout.write(`v${pkgVersion}`);
process.exit(0);
}
}

View File

@@ -1,17 +0,0 @@
import { printMessage, PrettyOptionsExtended } from './prettifier';
export type PrettyFactory = (param) => string;
/*
options eg:
{ messageKey: 'msg', levelFirst: true, prettyStamp: false }
*/
module.exports = function prettyFactory(options: PrettyOptionsExtended): PrettyFactory {
// the break line must happens in the prettify component
const breakLike = '\n';
return (inputData): string => {
// FIXME: review colors by default is true
return printMessage(inputData, options, true) + breakLike;
};
};

View File

@@ -1,102 +0,0 @@
import { inspect } from 'util';
import { white, red, green } from 'kleur';
import _ from 'lodash';
import dayjs from 'dayjs';
import { PrettyOptions } from 'pino';
import { calculateLevel, LevelCode, levelsColors, subSystemLevels } from '../levels';
import { padLeft, padRight } from '../utils';
export const CUSTOM_PAD_LENGTH = 1;
export const FORMAT_DATE = 'YYYY-MM-DD HH:mm:ss';
export function isObject(obj: unknown): boolean {
return _.isObject(obj) && _.isNull(obj) === false && _.isArray(obj) === false;
}
export function formatLoggingDate(time: number, message): string {
const timeFormatted = dayjs(time).format(FORMAT_DATE);
return `[${timeFormatted}]${message}`;
}
export interface PrettyOptionsExtended extends PrettyOptions {
prettyStamp: boolean;
}
let LEVEL_VALUE_MAX = 0;
// eslint-disable-next-line guard-for-in
for (const l in levelsColors) {
LEVEL_VALUE_MAX = Math.max(LEVEL_VALUE_MAX, l.length);
}
const ERROR_FLAG = '!';
export interface ObjectTemplate {
level: LevelCode;
msg: string;
sub?: string;
[key: string]: string | number | object | null | void;
}
export function fillInMsgTemplate(msg, templateOptions: ObjectTemplate, colors): string {
const templateRegex = /@{(!?[$A-Za-z_][$0-9A-Za-z\._]*)}/g;
return msg.replace(templateRegex, (_, name): string => {
let str = templateOptions;
let isError;
if (name[0] === ERROR_FLAG) {
name = name.substr(1);
isError = true;
}
// object can be @{foo.bar.}
const listAccessors = name.split('.');
for (let property = 0; property < listAccessors.length; property++) {
const id = listAccessors[property];
if (isObject(str)) {
str = (str as object)[id];
}
}
if (typeof str === 'string') {
if (colors === false || (str as string).includes('\n')) {
return str;
} else if (isError) {
return red(str);
}
return green(str);
}
// object, showHidden, depth, colors
return inspect(str, undefined, null, colors);
});
}
function getMessage(debugLevel, msg, sub, templateObjects, hasColors) {
const finalMessage = fillInMsgTemplate(msg, templateObjects, hasColors);
const subSystemType = subSystemLevels.color[sub ?? 'default'];
if (hasColors) {
const logString = `${levelsColors[debugLevel](padRight(debugLevel, LEVEL_VALUE_MAX))}${white(
`${subSystemType} ${finalMessage}`
)}`;
return padLeft(logString);
}
const logString = `${padRight(debugLevel, LEVEL_VALUE_MAX)}${subSystemType} ${finalMessage}`;
return padRight(logString);
}
export function printMessage(
templateObjects: ObjectTemplate,
options: PrettyOptionsExtended,
hasColors = true
): string {
const { prettyStamp } = options;
const { level, msg, sub } = templateObjects;
const debugLevel = calculateLevel(level);
const logMessage = getMessage(debugLevel, msg, sub, templateObjects, hasColors);
return prettyStamp ? formatLoggingDate(templateObjects.time as number, logMessage) : logMessage;
}

View File

@@ -1 +0,0 @@
export { setup, createLogger, logger } from './logger';

View File

@@ -1,156 +0,0 @@
import pino from 'pino';
import _ from 'lodash';
import buildDebug from 'debug';
import { yellow } from 'kleur';
import { padLeft } from './utils';
function isProd() {
return process.env.NODE_ENV === 'production';
}
export let logger;
const debug = buildDebug('verdaccio:logger');
const DEFAULT_LOG_FORMAT = isProd() ? 'json' : 'pretty';
export type LogPlugin = {
dest: string;
options?: any[];
};
export type LogType = 'file' | 'stdout';
export type LogFormat = 'json' | 'pretty-timestamped' | 'pretty';
export function createLogger(
options = { level: 'http' },
destination = pino.destination(1),
format: LogFormat = DEFAULT_LOG_FORMAT,
prettyPrintOptions = {
// we hide warning since the prettifier should not be used in production
// https://getpino.io/#/docs/pretty?id=prettifier-api
suppressFlushSyncWarning: true,
}
) {
if (_.isNil(format)) {
format = DEFAULT_LOG_FORMAT;
}
let pinoConfig = {
customLevels: {
http: 25,
},
...options,
level: options.level,
serializers: {
err: pino.stdSerializers.err,
req: pino.stdSerializers.req,
res: pino.stdSerializers.res,
},
};
debug('has prettifier? %o', !isProd());
// pretty logs are not allowed in production for performance reasons
if ((format === DEFAULT_LOG_FORMAT || format !== 'json') && isProd() === false) {
pinoConfig = Object.assign({}, pinoConfig, {
// more info
// https://github.com/pinojs/pino-pretty/issues/37
prettyPrint: {
levelFirst: true,
prettyStamp: format === 'pretty-timestamped',
...prettyPrintOptions,
},
prettifier: require('./formatter'),
});
}
const logger = pino(pinoConfig, destination);
if (process.env.DEBUG) {
logger.on('level-change', (lvl, val, prevLvl, prevVal) => {
debug('%s (%d) was changed to %s (%d)', lvl, val, prevLvl, prevVal);
});
}
return logger;
}
export function getLogger() {
if (_.isNil(logger)) {
process.emitWarning('logger is not defined');
return;
}
return logger;
}
const DEFAULT_LOGGER_CONF: LoggerConfigItem = {
type: 'stdout',
format: 'pretty',
level: 'http',
};
export type LoggerConfigItem = {
type?: LogType;
plugin?: LogPlugin;
format?: LogFormat;
path?: string;
level?: string;
};
export type LoggerConfig = LoggerConfigItem[];
export function setup(options: LoggerConfig | LoggerConfigItem = [DEFAULT_LOGGER_CONF]) {
debug('setup logger');
const isLegacyConf = Array.isArray(options);
if (isLegacyConf) {
const deprecateMessage =
'deprecate: multiple logger configuration is deprecated, please check the migration guide.';
process.emitWarning(deprecateMessage);
}
// verdaccio 5 does not allow multiple logger configuration
// backward compatible, pick only the first option
// next major will thrown an error
let loggerConfig = isLegacyConf ? options[0] : options;
if (!loggerConfig?.level) {
loggerConfig = Object.assign(
{},
{
level: 'http',
},
loggerConfig
);
}
const pinoConfig = { level: loggerConfig.level };
if (loggerConfig.type === 'file') {
debug('logging file enabled');
logger = createLogger(pinoConfig, pino.destination(loggerConfig.path), loggerConfig.format);
} else if (loggerConfig.type === 'rotating-file') {
process.emitWarning(
'rotating-file type is not longer supported, consider use [logrotate] instead'
);
debug('logging stdout enabled');
logger = createLogger(pinoConfig, pino.destination(1), loggerConfig.format);
} else {
debug('logging stdout enabled');
logger = createLogger(pinoConfig, pino.destination(1), loggerConfig.format);
}
if (isProd()) {
// why only on prod? https://github.com/pinojs/pino/issues/920#issuecomment-710807667
const finalHandler = pino.final(logger, (err, finalLogger, event) => {
finalLogger.info(`${event} caught`);
if (err) {
finalLogger.error(err, 'error caused exit');
}
process.exit(err ? 1 : 0);
});
process.on('uncaughtException', (err) => finalHandler(err, 'uncaughtException'));
process.on('unhandledRejection', (err) => finalHandler(err as Error, 'unhandledRejection'));
process.on('beforeExit', () => finalHandler(null, 'beforeExit'));
process.on('exit', () => finalHandler(null, 'exit'));
process.on('uncaughtException', (err) => finalHandler(err, 'uncaughtException'));
process.on('SIGINT', () => finalHandler(null, 'SIGINT'));
process.on('SIGQUIT', () => finalHandler(null, 'SIGQUIT'));
process.on('SIGTERM', () => finalHandler(null, 'SIGTERM'));
}
}