mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-11-08 23:25:51 +01:00
chore: update with master (#2158)
This commit is contained in:
parent
5ccb2bad16
commit
4a3e11d072
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
55
.yarn/releases/yarn-berry.cjs
vendored
55
.yarn/releases/yarn-berry.cjs
vendored
File diff suppressed because one or more lines are too long
@ -14,7 +14,33 @@ By default, the token stores in the database, but using this variable allows to
|
|||||||
|
|
||||||
#### VERDACCIO_PUBLIC_URL
|
#### VERDACCIO_PUBLIC_URL
|
||||||
|
|
||||||
Define a specific public url for your server, it overrules the `Host` and `X-Forwarded-Proto` header if a reverse proxy is
|
Define a specific public url for your server, it overrules the `Host` and `X-Forwarded-Proto` header if a reverse proxy is being used, it takes in account the `url_prefix` if is defined.
|
||||||
being used.
|
|
||||||
|
|
||||||
This is handy in such situations where a dynamic url is required.
|
This is handy in such situations where a dynamic url is required.
|
||||||
|
|
||||||
|
eg:
|
||||||
|
|
||||||
|
```
|
||||||
|
VERDACCIO_PUBLIC_URL='https://somedomain.org';
|
||||||
|
url_prefix: '/my_prefix'
|
||||||
|
|
||||||
|
// url -> https://somedomain.org/my_prefix/
|
||||||
|
|
||||||
|
VERDACCIO_PUBLIC_URL='https://somedomain.org';
|
||||||
|
url_prefix: '/'
|
||||||
|
|
||||||
|
// url -> https://somedomain.org/
|
||||||
|
|
||||||
|
VERDACCIO_PUBLIC_URL='https://somedomain.org/first_prefix';
|
||||||
|
url_prefix: '/second_prefix'
|
||||||
|
|
||||||
|
// url -> https://somedomain.org/second_prefix/'
|
||||||
|
```
|
||||||
|
|
||||||
|
#### VERDACCIO_FORWARDED_PROTO
|
||||||
|
|
||||||
|
The default header to identify the protocol is `X-Forwarded-Proto`, but there are some environments which [uses something different](https://github.com/verdaccio/verdaccio/issues/990), to change it use the variable `VERDACCIO_FORWARDED_PROTO`
|
||||||
|
|
||||||
|
```
|
||||||
|
$ VERDACCIO_FORWARDED_PROTO=CloudFront-Forwarded-Proto verdaccio --listen 5000
|
||||||
|
```
|
||||||
|
@ -49,8 +49,8 @@ export function getWebProtocol(headerProtocol: string | void, protocol: string):
|
|||||||
return validProtocols.includes(returnProtocol) ? returnProtocol : defaultProtocol;
|
return validProtocols.includes(returnProtocol) ? returnProtocol : defaultProtocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
function wrapPrefix(prefix: string): string {
|
export function wrapPrefix(prefix: string | void): string {
|
||||||
if (prefix === '' || _.isNil(prefix)) {
|
if (prefix === '' || typeof prefix === 'undefined' || prefix === null) {
|
||||||
return '';
|
return '';
|
||||||
} else if (!prefix.startsWith('/') && prefix.endsWith('/')) {
|
} else if (!prefix.startsWith('/') && prefix.endsWith('/')) {
|
||||||
return `/${prefix}`;
|
return `/${prefix}`;
|
||||||
@ -72,9 +72,10 @@ export function combineBaseUrl(protocol: string, host: string, prefix: string =
|
|||||||
debug('combined host %o', host);
|
debug('combined host %o', host);
|
||||||
const newPrefix = wrapPrefix(prefix);
|
const newPrefix = wrapPrefix(prefix);
|
||||||
debug('combined prefix %o', newPrefix);
|
debug('combined prefix %o', newPrefix);
|
||||||
const result = new URL(wrapPrefix(prefix), `${protocol}://${host}`);
|
const groupedURI = new URL(wrapPrefix(prefix), `${protocol}://${host}`);
|
||||||
debug('combined url %o', result.href);
|
const result = groupedURI.href;
|
||||||
return result.href;
|
debug('combined url %o', result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function validateURL(publicUrl: string | void) {
|
export function validateURL(publicUrl: string | void) {
|
||||||
@ -92,7 +93,7 @@ export function validateURL(publicUrl: string | void) {
|
|||||||
|
|
||||||
export function getPublicUrl(url_prefix: string = '', req): string {
|
export function getPublicUrl(url_prefix: string = '', req): string {
|
||||||
if (validateURL(process.env.VERDACCIO_PUBLIC_URL as string)) {
|
if (validateURL(process.env.VERDACCIO_PUBLIC_URL as string)) {
|
||||||
const envURL = new URL(process.env.VERDACCIO_PUBLIC_URL as string).href;
|
const envURL = new URL(wrapPrefix(url_prefix), process.env.VERDACCIO_PUBLIC_URL as string).href;
|
||||||
debug('public url by env %o', envURL);
|
debug('public url by env %o', envURL);
|
||||||
return envURL;
|
return envURL;
|
||||||
} else if (req.get('host')) {
|
} else if (req.get('host')) {
|
||||||
@ -100,7 +101,8 @@ export function getPublicUrl(url_prefix: string = '', req): string {
|
|||||||
if (!isHost(host)) {
|
if (!isHost(host)) {
|
||||||
throw new Error('invalid host');
|
throw new Error('invalid host');
|
||||||
}
|
}
|
||||||
const protocol = getWebProtocol(req.get(HEADERS.FORWARDED_PROTO), req.protocol);
|
const protoHeader = process.env.VERDACCIO_FORWARDED_PROTO ?? HEADERS.FORWARDED_PROTO;
|
||||||
|
const protocol = getWebProtocol(req.get(protoHeader), req.protocol);
|
||||||
const combinedUrl = combineBaseUrl(protocol, host, url_prefix);
|
const combinedUrl = combineBaseUrl(protocol, host, url_prefix);
|
||||||
debug('public url by request %o', combinedUrl);
|
debug('public url by request %o', combinedUrl);
|
||||||
return combinedUrl;
|
return combinedUrl;
|
||||||
|
@ -44,8 +44,6 @@
|
|||||||
"fast-safe-stringify": "2.0.7",
|
"fast-safe-stringify": "2.0.7",
|
||||||
"kleur": "3.0.3",
|
"kleur": "3.0.3",
|
||||||
"lodash": "4.17.20",
|
"lodash": "4.17.20",
|
||||||
"pad-left": "2.1.0",
|
|
||||||
"pad-right": "0.2.2",
|
|
||||||
"prettier-bytes": "1.0.4",
|
"prettier-bytes": "1.0.4",
|
||||||
"pretty-ms": "5.1.0"
|
"pretty-ms": "5.1.0"
|
||||||
},
|
},
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import { inspect } from 'util';
|
import { inspect } from 'util';
|
||||||
|
|
||||||
import { white, red, green } from 'kleur';
|
import { white, red, green } from 'kleur';
|
||||||
import padLeft from 'pad-left';
|
|
||||||
|
|
||||||
import { calculateLevel, LevelCode, levelsColors, subSystemLevels } from './levels';
|
import { calculateLevel, LevelCode, levelsColors, subSystemLevels } from './levels';
|
||||||
import { formatLoggingDate, isObject, pad } from './utils';
|
import { formatLoggingDate, isObject, padLeft, padRight } from './utils';
|
||||||
import { PrettyOptionsExtended } from './types';
|
import { PrettyOptionsExtended } from './types';
|
||||||
|
|
||||||
let LEVEL_VALUE_MAX = 0;
|
let LEVEL_VALUE_MAX = 0;
|
||||||
@ -55,22 +53,20 @@ export function fillInMsgTemplate(msg, templateOptions: ObjectTemplate, colors):
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const CUSTOM_PAD_LENGTH = 1;
|
|
||||||
|
|
||||||
function getMessage(debugLevel, msg, sub, templateObjects, hasColors) {
|
function getMessage(debugLevel, msg, sub, templateObjects, hasColors) {
|
||||||
const finalMessage = fillInMsgTemplate(msg, templateObjects, hasColors);
|
const finalMessage = fillInMsgTemplate(msg, templateObjects, hasColors);
|
||||||
|
|
||||||
const subSystemType = subSystemLevels.color[sub ?? 'default'];
|
const subSystemType = subSystemLevels.color[sub ?? 'default'];
|
||||||
if (hasColors) {
|
if (hasColors) {
|
||||||
const logString = `${levelsColors[debugLevel](pad(debugLevel, LEVEL_VALUE_MAX))}${white(
|
const logString = `${levelsColors[debugLevel](padRight(debugLevel, LEVEL_VALUE_MAX))}${white(
|
||||||
`${subSystemType} ${finalMessage}`
|
`${subSystemType} ${finalMessage}`
|
||||||
)}`;
|
)}`;
|
||||||
|
|
||||||
return padLeft(logString, logString.length + CUSTOM_PAD_LENGTH, ' ');
|
return padLeft(logString);
|
||||||
}
|
}
|
||||||
const logString = `${pad(debugLevel, LEVEL_VALUE_MAX)}${subSystemType} ${finalMessage}`;
|
const logString = `${padRight(debugLevel, LEVEL_VALUE_MAX)}${subSystemType} ${finalMessage}`;
|
||||||
|
|
||||||
return padLeft(logString, logString.length + CUSTOM_PAD_LENGTH, ' ');
|
return padRight(logString);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function printMessage(
|
export function printMessage(
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { yellow, green, black, blue, red, magenta, cyan, white } from 'kleur';
|
import { yellow, green, red, magenta, black, blue, cyan, white } from 'kleur';
|
||||||
|
|
||||||
export type LogLevel = 'trace' | 'debug' | 'info' | 'http' | 'warn' | 'error' | 'fatal';
|
export type LogLevel = 'trace' | 'debug' | 'info' | 'http' | 'warn' | 'error' | 'fatal';
|
||||||
|
|
||||||
@ -6,18 +6,20 @@ export type LevelCode = number;
|
|||||||
|
|
||||||
export function calculateLevel(levelCode: LevelCode): LogLevel {
|
export function calculateLevel(levelCode: LevelCode): LogLevel {
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case levelCode < 15:
|
case levelCode === 10:
|
||||||
return 'trace';
|
return 'trace';
|
||||||
case levelCode < 25:
|
case levelCode === 20:
|
||||||
return 'debug';
|
return 'debug';
|
||||||
case levelCode < 35:
|
case levelCode === 25:
|
||||||
return 'info';
|
|
||||||
case levelCode == 35:
|
|
||||||
return 'http';
|
return 'http';
|
||||||
case levelCode < 45:
|
case levelCode === 30:
|
||||||
|
return 'info';
|
||||||
|
case levelCode === 40:
|
||||||
return 'warn';
|
return 'warn';
|
||||||
case levelCode < 55:
|
case levelCode === 50:
|
||||||
return 'error';
|
return 'error';
|
||||||
|
case levelCode === 60:
|
||||||
|
return 'fatal';
|
||||||
default:
|
default:
|
||||||
return 'fatal';
|
return 'fatal';
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,19 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import padRight from 'pad-right';
|
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
export const FORMAT_DATE = 'YYYY-MM-DD HH:mm:ss';
|
export const FORMAT_DATE = 'YYYY-MM-DD HH:mm:ss';
|
||||||
|
export const CUSTOM_PAD_LENGTH = 1;
|
||||||
|
|
||||||
export function isObject(obj: unknown): boolean {
|
export function isObject(obj: unknown): boolean {
|
||||||
return _.isObject(obj) && _.isNull(obj) === false && _.isArray(obj) === false;
|
return _.isObject(obj) && _.isNull(obj) === false && _.isArray(obj) === false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function pad(str: string, max: number): string {
|
export function padLeft(message: string) {
|
||||||
return padRight(str, max, ' ');
|
return message.padStart(message.length + CUSTOM_PAD_LENGTH, ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function padRight(message: string, max = message.length + CUSTOM_PAD_LENGTH) {
|
||||||
|
return message.padEnd(max, ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatLoggingDate(time: number, message): string {
|
export function formatLoggingDate(time: number, message): string {
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`formatter printMessage should display a bytes request 1`] = `" [35mhttp [39m[37m[32m<--[39m[37m [33m200[39m[37m, user: [1mnull[22m([32m127.0.0.1[39m[37m), req: '[32mGET[39m[37m [32m/verdaccio[39m[37m', bytes: [33m0[39m[37m/[33m150186[39m[37m[39m"`;
|
exports[`formatter printMessage should display a bytes request 1`] = `" [31mfatal[39m[37m[32m<--[39m[37m [33m200[39m[37m, user: [1mnull[22m([32m127.0.0.1[39m[37m), req: '[32mGET[39m[37m [32m/verdaccio[39m[37m', bytes: [33m0[39m[37m/[33m150186[39m[37m[39m"`;
|
||||||
|
|
||||||
exports[`formatter printMessage should display a resource request 1`] = `" info [32m<--[39m 127.0.0.1 requested 'GET /verdaccio'"`;
|
exports[`formatter printMessage should display a resource request 1`] = `"info [32m<--[39m 127.0.0.1 requested 'GET /verdaccio' "`;
|
||||||
|
|
||||||
exports[`formatter printMessage should display a streaming request 1`] = `" [35mhttp [39m[37m[33m-->[39m[37m [33m304[39m[37m, req: '[32mGET[39m[37m [32mhttps://registry.npmjs.org/verdaccio[39m[37m' (streaming)[39m"`;
|
exports[`formatter printMessage should display a streaming request 1`] = `" [31mfatal[39m[37m[33m-->[39m[37m [33m304[39m[37m, req: '[32mGET[39m[37m [32mhttps://registry.npmjs.org/verdaccio[39m[37m' (streaming)[39m"`;
|
||||||
|
|
||||||
exports[`formatter printMessage should display an error request 1`] = `" [31merror[39m[37m[33m-->[39m[37m [31mERR[39m[37m, req: '[32mGET[39m[37m [32mhttps://registry.fake.org/aaa[39m[37m', error: [31mgetaddrinfo ENOTFOUND registry.fake.org[39m[37m[39m"`;
|
exports[`formatter printMessage should display an error request 1`] = `" [31mfatal[39m[37m[33m-->[39m[37m [31mERR[39m[37m, req: '[32mGET[39m[37m [32mhttps://registry.fake.org/aaa[39m[37m', error: [31mgetaddrinfo ENOTFOUND registry.fake.org[39m[37m[39m"`;
|
||||||
|
|
||||||
exports[`formatter printMessage should display an fatal request 1`] = `" [31mfatal[39m[37m[33m-->[39m[37m [31mERR[39m[37m, req: '[32mGET[39m[37m [32mhttps://registry.fake.org/aaa[39m[37m', error: [31mfatal error[39m[37m[39m"`;
|
exports[`formatter printMessage should display an fatal request 1`] = `" [31mfatal[39m[37m[33m-->[39m[37m [31mERR[39m[37m, req: '[32mGET[39m[37m [32mhttps://registry.fake.org/aaa[39m[37m', error: [31mfatal error[39m[37m[39m"`;
|
||||||
|
|
||||||
exports[`formatter printMessage should display config file 1`] = `" [33mwarn [39m[37m[34m---[39m[37m config file - [32m/Users/user/.config/verdaccio/config/config.yaml[39m[37m[39m"`;
|
exports[`formatter printMessage should display config file 1`] = `" [33mwarn [39m[37m[34m---[39m[37m config file - [32m/Users/user/.config/verdaccio/config/config.yaml[39m[37m[39m"`;
|
||||||
|
|
||||||
exports[`formatter printMessage should display custom log message 1`] = `" [32mdebug[39m[37m[34m---[39m[37m custom - [32mfoo[39m[37m - [90mundefined[39m[37m[39m"`;
|
exports[`formatter printMessage should display custom log message 1`] = `" [31mfatal[39m[37m[34m---[39m[37m custom - [32mfoo[39m[37m - [90mundefined[39m[37m[39m"`;
|
||||||
|
|
||||||
exports[`formatter printMessage should display trace level 1`] = `" [37mtrace[39m[37m[34m---[39m[37m [trace] - [32mfoo[39m[37m[39m"`;
|
exports[`formatter printMessage should display trace level 1`] = `" [37mtrace[39m[37m[34m---[39m[37m [trace] - [32mfoo[39m[37m[39m"`;
|
||||||
|
|
||||||
|
@ -4,18 +4,13 @@ import buildDebug from 'debug';
|
|||||||
|
|
||||||
const debug = buildDebug('verdaccio:logger');
|
const debug = buildDebug('verdaccio:logger');
|
||||||
|
|
||||||
const DEFAULT_LOG_FORMAT = 'pretty';
|
|
||||||
|
|
||||||
export let logger;
|
export let logger;
|
||||||
|
|
||||||
function isProd() {
|
function isProd() {
|
||||||
return process.env.NODE_ENV === 'production';
|
return process.env.NODE_ENV === 'production';
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPrettifier() {
|
const DEFAULT_LOG_FORMAT = isProd() ? 'json' : 'pretty';
|
||||||
// TODO: this module can be loaded dynamically and allow custom formatting
|
|
||||||
return require('@verdaccio/logger-prettify');
|
|
||||||
}
|
|
||||||
|
|
||||||
export type LogPlugin = {
|
export type LogPlugin = {
|
||||||
dest: string;
|
dest: string;
|
||||||
@ -26,7 +21,7 @@ export type LogType = 'file' | 'stdout';
|
|||||||
export type LogFormat = 'json' | 'pretty-timestamped' | 'pretty';
|
export type LogFormat = 'json' | 'pretty-timestamped' | 'pretty';
|
||||||
|
|
||||||
export function createLogger(
|
export function createLogger(
|
||||||
options = {},
|
options = { level: 'http' },
|
||||||
destination = pino.destination(1),
|
destination = pino.destination(1),
|
||||||
format: LogFormat = DEFAULT_LOG_FORMAT,
|
format: LogFormat = DEFAULT_LOG_FORMAT,
|
||||||
prettyPrintOptions = {
|
prettyPrintOptions = {
|
||||||
@ -40,10 +35,11 @@ export function createLogger(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let pinoConfig = {
|
let pinoConfig = {
|
||||||
...options,
|
|
||||||
customLevels: {
|
customLevels: {
|
||||||
http: 35,
|
http: 25,
|
||||||
},
|
},
|
||||||
|
...options,
|
||||||
|
level: options.level,
|
||||||
serializers: {
|
serializers: {
|
||||||
err: pino.stdSerializers.err,
|
err: pino.stdSerializers.err,
|
||||||
req: pino.stdSerializers.req,
|
req: pino.stdSerializers.req,
|
||||||
@ -52,26 +48,33 @@ export function createLogger(
|
|||||||
};
|
};
|
||||||
|
|
||||||
debug('has prettifier? %o', !isProd());
|
debug('has prettifier? %o', !isProd());
|
||||||
// pretty logs are not allowed in production for performance reason
|
// pretty logs are not allowed in production for performance reasons
|
||||||
if ((format === DEFAULT_LOG_FORMAT || format !== 'json') && isProd() === false) {
|
if ((format === DEFAULT_LOG_FORMAT || format !== 'json') && isProd() === false) {
|
||||||
pinoConfig = Object.assign({}, pinoConfig, {
|
pinoConfig = Object.assign({}, pinoConfig, {
|
||||||
// FIXME: this property cannot be used in combination with pino.final
|
// more info
|
||||||
// https://github.com/pinojs/pino-pretty/issues/37
|
// https://github.com/pinojs/pino-pretty/issues/37
|
||||||
prettyPrint: {
|
prettyPrint: {
|
||||||
levelFirst: true,
|
levelFirst: true,
|
||||||
prettyStamp: format === 'pretty-timestamped',
|
prettyStamp: format === 'pretty-timestamped',
|
||||||
...prettyPrintOptions,
|
...prettyPrintOptions,
|
||||||
},
|
},
|
||||||
prettifier: getPrettifier(),
|
prettifier: require('@verdaccio/logger-prettify'),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
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 pino(pinoConfig, destination);
|
return logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLogger() {
|
export function getLogger() {
|
||||||
if (_.isNil(logger)) {
|
if (_.isNil(logger)) {
|
||||||
console.warn('logger is not defined');
|
process.emitWarning('logger is not defined');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,40 +99,58 @@ export type LoggerConfig = LoggerConfigItem[];
|
|||||||
|
|
||||||
export function setup(options: LoggerConfig | LoggerConfigItem = [DEFAULT_LOGGER_CONF]) {
|
export function setup(options: LoggerConfig | LoggerConfigItem = [DEFAULT_LOGGER_CONF]) {
|
||||||
debug('setup logger');
|
debug('setup logger');
|
||||||
const isLegacyConf = _.isArray(options);
|
const isLegacyConf = Array.isArray(options);
|
||||||
// verdaccio 4 allows array configuration
|
if (isLegacyConf) {
|
||||||
// backward compatible, pick only the first option
|
const deprecateMessage =
|
||||||
let loggerConfig = isLegacyConf ? options[0] : options;
|
'deprecate: multiple logger configuration is deprecated, please check the migration guide.';
|
||||||
if (!loggerConfig?.level) {
|
process.emitWarning(deprecateMessage);
|
||||||
loggerConfig = Object.assign({}, loggerConfig, {
|
|
||||||
level: 'http',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 };
|
const pinoConfig = { level: loggerConfig.level };
|
||||||
if (loggerConfig.type === 'file') {
|
if (loggerConfig.type === 'file') {
|
||||||
|
debug('logging file enabled');
|
||||||
logger = createLogger(pinoConfig, pino.destination(loggerConfig.path), loggerConfig.format);
|
logger = createLogger(pinoConfig, pino.destination(loggerConfig.path), loggerConfig.format);
|
||||||
} else if (loggerConfig.type === 'rotating-file') {
|
} else if (loggerConfig.type === 'rotating-file') {
|
||||||
throw new Error('rotating-file type is not longer supported, consider use [logrotate] instead');
|
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 {
|
} else {
|
||||||
|
debug('logging stdout enabled');
|
||||||
logger = createLogger(pinoConfig, pino.destination(1), loggerConfig.format);
|
logger = createLogger(pinoConfig, pino.destination(1), loggerConfig.format);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isProd()) {
|
if (isProd()) {
|
||||||
process.on(
|
// why only on prod? https://github.com/pinojs/pino/issues/920#issuecomment-710807667
|
||||||
'uncaughtException',
|
const finalHandler = pino.final(logger, (err, finalLogger, event) => {
|
||||||
pino.final(logger, (err, finalLogger) => {
|
finalLogger.info(`${event} caught`);
|
||||||
finalLogger.fatal(err, 'uncaughtException');
|
if (err) {
|
||||||
process.exit(1);
|
finalLogger.error(err, 'error caused exit');
|
||||||
})
|
}
|
||||||
);
|
process.exit(err ? 1 : 0);
|
||||||
|
});
|
||||||
|
|
||||||
process.on(
|
process.on('uncaughtException', (err) => finalHandler(err, 'uncaughtException'));
|
||||||
'unhandledRejection',
|
process.on('unhandledRejection', (err) => finalHandler(err as Error, 'unhandledRejection'));
|
||||||
pino.final(logger, (err, finalLogger) => {
|
process.on('beforeExit', () => finalHandler(null, 'beforeExit'));
|
||||||
finalLogger.fatal(err, 'uncaughtException');
|
process.on('exit', () => finalHandler(null, 'exit'));
|
||||||
process.exit(1);
|
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'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,13 +314,12 @@ export function log(req: $RequestExtend, res: $ResponseExtend, next: $NextFuncti
|
|||||||
}
|
}
|
||||||
|
|
||||||
req.url = req.originalUrl;
|
req.url = req.originalUrl;
|
||||||
req.log.warn(
|
req.log.http(
|
||||||
{
|
{
|
||||||
request: {
|
request: {
|
||||||
method: req.method,
|
method: req.method,
|
||||||
url: req.url,
|
url: req.url,
|
||||||
},
|
},
|
||||||
level: 35, // http
|
|
||||||
user: (req.remote_user && req.remote_user.name) || null,
|
user: (req.remote_user && req.remote_user.name) || null,
|
||||||
remoteIP,
|
remoteIP,
|
||||||
status: res.statusCode,
|
status: res.statusCode,
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
exports.staticPath = path.join(__dirname, 'static');
|
module.exports = () => {
|
||||||
exports.manifest = require('./static/manifest.json');
|
return {
|
||||||
exports.manifestFiles = {
|
staticPath: path.join(__dirname, 'static'),
|
||||||
js: ['runtime.js', 'vendors.js', 'main.js'],
|
manifest: require('./static/manifest.json'),
|
||||||
css: [],
|
manifestFiles: {
|
||||||
ico: 'favicon.ico',
|
js: ['runtime.js', 'vendors.js', 'main.js'],
|
||||||
|
},
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
@ -8,7 +8,7 @@ import 'mutationobserver-shim';
|
|||||||
// @ts-ignore : Property '__APP_VERSION__' does not exist on type 'Global'.
|
// @ts-ignore : Property '__APP_VERSION__' does not exist on type 'Global'.
|
||||||
global.__APP_VERSION__ = '1.0.0';
|
global.__APP_VERSION__ = '1.0.0';
|
||||||
// @ts-ignore : Property '__VERDACCIO_BASENAME_UI_OPTIONS' does not exist on type 'Global'.
|
// @ts-ignore : Property '__VERDACCIO_BASENAME_UI_OPTIONS' does not exist on type 'Global'.
|
||||||
global.__VERDACCIO_BASENAME_UI_OPTIONS = { basePath: 'http://localhost' };
|
global.__VERDACCIO_BASENAME_UI_OPTIONS = { base: 'http://localhost' };
|
||||||
// @ts-ignore : Property 'VERDACCIO_API_URL' does not exist on type 'Global'.
|
// @ts-ignore : Property 'VERDACCIO_API_URL' does not exist on type 'Global'.
|
||||||
global.VERDACCIO_API_URL = 'https://verdaccio.tld';
|
global.VERDACCIO_API_URL = 'https://verdaccio.tld';
|
||||||
|
|
||||||
|
@ -26,9 +26,9 @@ describe('utils', () => {
|
|||||||
|
|
||||||
test('getRegistryURL() - should change when UI options change', () => {
|
test('getRegistryURL() - should change when UI options change', () => {
|
||||||
expect(getRegistryURL()).toBe('http://localhost');
|
expect(getRegistryURL()).toBe('http://localhost');
|
||||||
window.__VERDACCIO_BASENAME_UI_OPTIONS.basePath = 'http://localhost/test';
|
window.__VERDACCIO_BASENAME_UI_OPTIONS.base = 'http://localhost/test';
|
||||||
expect(getRegistryURL()).toBe('http://localhost/test');
|
expect(getRegistryURL()).toBe('http://localhost/test');
|
||||||
window.__VERDACCIO_BASENAME_UI_OPTIONS.basePath = 'http://localhost';
|
window.__VERDACCIO_BASENAME_UI_OPTIONS.base = 'http://localhost';
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ export function isEmail(email: string): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getRegistryURL(): string {
|
export function getRegistryURL(): string {
|
||||||
return window?.__VERDACCIO_BASENAME_UI_OPTIONS?.basePath;
|
return window?.__VERDACCIO_BASENAME_UI_OPTIONS?.base;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function extractFileName(url: string): string {
|
export function extractFileName(url: string): string {
|
||||||
|
@ -230,12 +230,11 @@ class ProxyStorage implements IProxy {
|
|||||||
let message = "@{!status}, req: '@{request.method} @{request.url}'";
|
let message = "@{!status}, req: '@{request.method} @{request.url}'";
|
||||||
// FIXME: use LOG_VERDACCIO_BYTES
|
// FIXME: use LOG_VERDACCIO_BYTES
|
||||||
message += error ? ', error: @{!error}' : ', bytes: @{bytes.in}/@{bytes.out}';
|
message += error ? ', error: @{!error}' : ', bytes: @{bytes.in}/@{bytes.out}';
|
||||||
self.logger.warn(
|
self.logger.http(
|
||||||
{
|
{
|
||||||
// if error is null/false change this to undefined so it wont log
|
// if error is null/false change this to undefined so it wont log
|
||||||
err: err || undefined,
|
err: err || undefined,
|
||||||
request: { method: method, url: uri },
|
request: { method: method, url: uri },
|
||||||
level: 35, // http
|
|
||||||
status: res != null ? res.statusCode : 'ERR',
|
status: res != null ? res.statusCode : 'ERR',
|
||||||
error: error,
|
error: error,
|
||||||
bytes: {
|
bytes: {
|
||||||
@ -282,13 +281,12 @@ class ProxyStorage implements IProxy {
|
|||||||
if (_.isNil(requestCallback) === false) {
|
if (_.isNil(requestCallback) === false) {
|
||||||
(function do_log(): void {
|
(function do_log(): void {
|
||||||
const message = "@{!status}, req: '@{request.method} @{request.url}' (streaming)";
|
const message = "@{!status}, req: '@{request.method} @{request.url}' (streaming)";
|
||||||
self.logger.warn(
|
self.logger.http(
|
||||||
{
|
{
|
||||||
request: {
|
request: {
|
||||||
method: method,
|
method: method,
|
||||||
url: uri,
|
url: uri,
|
||||||
},
|
},
|
||||||
level: 35, // http
|
|
||||||
status: _.isNull(res) === false ? res.statusCode : 'ERR',
|
status: _.isNull(res) === false ? res.statusCode : 'ERR',
|
||||||
},
|
},
|
||||||
message
|
message
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fse = require('fs-extra');
|
const fse = require('fs-extra');
|
||||||
const uiTheme = require('@verdaccio/ui-theme');
|
const { staticPath, manifest, manifestFiles } = require('@verdaccio/ui-theme')();
|
||||||
fse.copySync(uiTheme.staticPath, path.join(__dirname, '../dist/static'));
|
fse.copySync(staticPath, path.join(__dirname, '../dist/static'));
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log('theme files copied');
|
console.log('theme files copied');
|
||||||
|
@ -40,8 +40,7 @@ const sendFileCallback = (next) => (err) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function renderWebMiddleware(config, auth, storage): any {
|
export function renderWebMiddleware(config, auth, storage): any {
|
||||||
const pluginTheme = require('@verdaccio/ui-theme');
|
const { staticPath, manifest, manifestFiles } = require('@verdaccio/ui-theme')();
|
||||||
const { staticPath } = pluginTheme;
|
|
||||||
debug('static path %o', staticPath);
|
debug('static path %o', staticPath);
|
||||||
SearchInstance.configureStorage(storage);
|
SearchInstance.configureStorage(storage);
|
||||||
|
|
||||||
@ -73,12 +72,12 @@ export function renderWebMiddleware(config, auth, storage): any {
|
|||||||
});
|
});
|
||||||
|
|
||||||
router.get('/-/web/:section/*', function (req, res) {
|
router.get('/-/web/:section/*', function (req, res) {
|
||||||
renderHTML(config, req, res);
|
renderHTML(config, manifest, manifestFiles, req, res);
|
||||||
debug('render html section');
|
debug('render html section');
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/', function (req, res) {
|
router.get('/', function (req, res) {
|
||||||
renderHTML(config, req, res);
|
renderHTML(config, manifest, manifestFiles, req, res);
|
||||||
debug('render root');
|
debug('render root');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -19,11 +19,10 @@ const defaultManifestFiles = {
|
|||||||
ico: 'favicon.ico',
|
ico: 'favicon.ico',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function renderHTML(config, req, res) {
|
export default function renderHTML(config, manifest, manifestFiles, req, res) {
|
||||||
const { manifest, manifestFiles } = require('@verdaccio/ui-theme');
|
|
||||||
const { url_prefix } = config;
|
const { url_prefix } = config;
|
||||||
const basePath = getPublicUrl(config?.url_prefix, req);
|
const base = getPublicUrl(config?.url_prefix, req);
|
||||||
const basename = new URL(basePath).pathname;
|
const basename = new URL(base).pathname;
|
||||||
const language = config?.i18n?.web ?? DEFAULT_LANGUAGE;
|
const language = config?.i18n?.web ?? DEFAULT_LANGUAGE;
|
||||||
const darkMode = config?.web?.darkMode ?? false;
|
const darkMode = config?.web?.darkMode ?? false;
|
||||||
const title = config?.web?.title ?? WEB_TITLE;
|
const title = config?.web?.title ?? WEB_TITLE;
|
||||||
@ -32,12 +31,20 @@ export default function renderHTML(config, req, res) {
|
|||||||
let logoURI = config?.web?.logo ?? '';
|
let logoURI = config?.web?.logo ?? '';
|
||||||
const version = pkgJSON.version;
|
const version = pkgJSON.version;
|
||||||
const primaryColor = validatePrimaryColor(config?.web?.primary_color) ?? '#4b5e40';
|
const primaryColor = validatePrimaryColor(config?.web?.primary_color) ?? '#4b5e40';
|
||||||
const { scriptsBodyAfter, metaScripts, bodyBefore } = config?.web;
|
const { scriptsBodyAfter, metaScripts, scriptsbodyBefore } = Object.assign(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
scriptsBodyAfter: [],
|
||||||
|
bodyBefore: [],
|
||||||
|
metaScripts: [],
|
||||||
|
},
|
||||||
|
config?.web
|
||||||
|
);
|
||||||
const options = {
|
const options = {
|
||||||
darkMode,
|
darkMode,
|
||||||
url_prefix,
|
url_prefix,
|
||||||
basename,
|
basename,
|
||||||
basePath,
|
base,
|
||||||
primaryColor,
|
primaryColor,
|
||||||
version,
|
version,
|
||||||
logoURI,
|
logoURI,
|
||||||
@ -60,7 +67,7 @@ export default function renderHTML(config, req, res) {
|
|||||||
options,
|
options,
|
||||||
scriptsBodyAfter,
|
scriptsBodyAfter,
|
||||||
metaScripts,
|
metaScripts,
|
||||||
bodyBefore,
|
scriptsbodyBefore,
|
||||||
},
|
},
|
||||||
manifest
|
manifest
|
||||||
);
|
);
|
||||||
|
@ -10,8 +10,7 @@ export type TemplateUIOptions = {
|
|||||||
protocol?: string;
|
protocol?: string;
|
||||||
host?: string;
|
host?: string;
|
||||||
url_prefix?: string;
|
url_prefix?: string;
|
||||||
base?: string;
|
base: string;
|
||||||
basePath: string;
|
|
||||||
primaryColor?: string;
|
primaryColor?: string;
|
||||||
version?: string;
|
version?: string;
|
||||||
logoURI?: string;
|
logoURI?: string;
|
||||||
@ -22,9 +21,9 @@ export type TemplateUIOptions = {
|
|||||||
export type Template = {
|
export type Template = {
|
||||||
manifest: Manifest;
|
manifest: Manifest;
|
||||||
options: TemplateUIOptions;
|
options: TemplateUIOptions;
|
||||||
scriptsBodyAfter?: string[];
|
|
||||||
metaScripts?: string[];
|
metaScripts?: string[];
|
||||||
bodyBefore?: string[];
|
scriptsBodyAfter?: string[];
|
||||||
|
scriptsbodyBefore?: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
// the outcome of the Webpack Manifest Plugin
|
// the outcome of the Webpack Manifest Plugin
|
||||||
@ -35,28 +34,28 @@ export interface WebpackManifest {
|
|||||||
export default function renderTemplate(template: Template, manifest: WebpackManifest) {
|
export default function renderTemplate(template: Template, manifest: WebpackManifest) {
|
||||||
debug('template %o', template);
|
debug('template %o', template);
|
||||||
debug('manifest %o', manifest);
|
debug('manifest %o', manifest);
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en-us">
|
<html lang="en-us">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<base href="${template?.options?.basePath}">
|
<base href="${template?.options.base}">
|
||||||
<title>${template?.options?.title ?? ''}</title>
|
<title>${template?.options?.title ?? ''}</title>
|
||||||
<link rel="shortcut icon" href="/-/static/favicon.ico"/>
|
<link rel="icon" href="${template?.options.base}-/static/favicon.ico"/>
|
||||||
<link rel="icon" type="image/png" href="${template.manifest.ico}" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<script>
|
<script>
|
||||||
window.__VERDACCIO_BASENAME_UI_OPTIONS=${JSON.stringify(template.options)}
|
window.__VERDACCIO_BASENAME_UI_OPTIONS=${JSON.stringify(template.options)}
|
||||||
</script>
|
</script>
|
||||||
${template.metaScripts ? template.metaScripts.map((item) => item) : ''}
|
${template?.metaScripts ? template.metaScripts.join('') : ''}
|
||||||
</head>
|
</head>
|
||||||
<body class="body">
|
<body class="body">
|
||||||
${template.bodyBefore ? template.bodyBefore.map((item) => item) : ''}
|
${template?.scriptsbodyBefore ? template.scriptsbodyBefore.join('') : ''}
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
${getManifestValue(template.manifest.js, manifest, template?.options?.basePath).map(
|
${getManifestValue(template.manifest.js, manifest, template?.options.base)
|
||||||
(item) => `<script defer="defer" src="${item}"></script>`
|
.map((item) => `<script defer="defer" src="${item}"></script>`)
|
||||||
)}
|
.join('')}
|
||||||
${template.scriptsBodyAfter ? template.scriptsBodyAfter.map((item) => item) : ''}
|
${template?.scriptsBodyAfter ? template.scriptsBodyAfter.join('') : ''}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`;
|
`;
|
||||||
|
@ -6,21 +6,20 @@ exports[`template custom body after 1`] = `
|
|||||||
<html lang=\\"en-us\\">
|
<html lang=\\"en-us\\">
|
||||||
<head>
|
<head>
|
||||||
<meta charset=\\"utf-8\\">
|
<meta charset=\\"utf-8\\">
|
||||||
<base href=\\"undefined\\">
|
<base href=\\"http://domain.com\\">
|
||||||
<title></title>
|
<title></title>
|
||||||
<link rel=\\"shortcut icon\\" href=\\"/-/static/favicon.ico\\"/>
|
<link rel=\\"icon\\" href=\\"http://domain.com-/static/favicon.ico\\"/>
|
||||||
<link rel=\\"icon\\" type=\\"image/png\\" href=\\"/static/foo.ico\\" />
|
|
||||||
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\" />
|
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\" />
|
||||||
<script>
|
<script>
|
||||||
window.__VERDACCIO_BASENAME_UI_OPTIONS=undefined
|
window.__VERDACCIO_BASENAME_UI_OPTIONS={\\"base\\":\\"http://domain.com\\"}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body class=\\"body\\">
|
<body class=\\"body\\">
|
||||||
|
|
||||||
<div id=\\"root\\"></div>
|
<div id=\\"root\\"></div>
|
||||||
<script defer=\\"defer\\" src=\\"/-/static/runtime.6126058572f989c948b1.js\\"></script>,<script defer=\\"defer\\" src=\\"/-/static/main.6126058572f989c948b1.js\\"></script>
|
<script defer=\\"defer\\" src=\\"http://domain.com/-/static/runtime.6126058572f989c948b1.js\\"></script><script defer=\\"defer\\" src=\\"http://domain.com/-/static/main.6126058572f989c948b1.js\\"></script>
|
||||||
|
<script src=\\"foo\\"/>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
"
|
"
|
||||||
@ -32,20 +31,19 @@ exports[`template custom body before 1`] = `
|
|||||||
<html lang=\\"en-us\\">
|
<html lang=\\"en-us\\">
|
||||||
<head>
|
<head>
|
||||||
<meta charset=\\"utf-8\\">
|
<meta charset=\\"utf-8\\">
|
||||||
<base href=\\"undefined\\">
|
<base href=\\"http://domain.com\\">
|
||||||
<title></title>
|
<title></title>
|
||||||
<link rel=\\"shortcut icon\\" href=\\"/-/static/favicon.ico\\"/>
|
<link rel=\\"icon\\" href=\\"http://domain.com-/static/favicon.ico\\"/>
|
||||||
<link rel=\\"icon\\" type=\\"image/png\\" href=\\"/static/foo.ico\\" />
|
|
||||||
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\" />
|
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\" />
|
||||||
<script>
|
<script>
|
||||||
window.__VERDACCIO_BASENAME_UI_OPTIONS=undefined
|
window.__VERDACCIO_BASENAME_UI_OPTIONS={\\"base\\":\\"http://domain.com\\"}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body class=\\"body\\">
|
<body class=\\"body\\">
|
||||||
<script src=\\"fooBefore\\"/>,<script src=\\"barBefore\\"/>
|
<script src=\\"fooBefore\\"/><script src=\\"barBefore\\"/>
|
||||||
<div id=\\"root\\"></div>
|
<div id=\\"root\\"></div>
|
||||||
<script defer=\\"defer\\" src=\\"/-/static/runtime.6126058572f989c948b1.js\\"></script>,<script defer=\\"defer\\" src=\\"/-/static/main.6126058572f989c948b1.js\\"></script>
|
<script defer=\\"defer\\" src=\\"http://domain.com/-/static/runtime.6126058572f989c948b1.js\\"></script><script defer=\\"defer\\" src=\\"http://domain.com/-/static/main.6126058572f989c948b1.js\\"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@ -58,20 +56,19 @@ exports[`template custom render 1`] = `
|
|||||||
<html lang=\\"en-us\\">
|
<html lang=\\"en-us\\">
|
||||||
<head>
|
<head>
|
||||||
<meta charset=\\"utf-8\\">
|
<meta charset=\\"utf-8\\">
|
||||||
<base href=\\"undefined\\">
|
<base href=\\"http://domain.com\\">
|
||||||
<title></title>
|
<title></title>
|
||||||
<link rel=\\"shortcut icon\\" href=\\"/-/static/favicon.ico\\"/>
|
<link rel=\\"icon\\" href=\\"http://domain.com-/static/favicon.ico\\"/>
|
||||||
<link rel=\\"icon\\" type=\\"image/png\\" href=\\"/static/foo.ico\\" />
|
|
||||||
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\" />
|
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\" />
|
||||||
<script>
|
<script>
|
||||||
window.__VERDACCIO_BASENAME_UI_OPTIONS={}
|
window.__VERDACCIO_BASENAME_UI_OPTIONS={\\"base\\":\\"http://domain.com\\"}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body class=\\"body\\">
|
<body class=\\"body\\">
|
||||||
|
|
||||||
<div id=\\"root\\"></div>
|
<div id=\\"root\\"></div>
|
||||||
<script defer=\\"defer\\" src=\\"/-/static/runtime.6126058572f989c948b1.js\\"></script>,<script defer=\\"defer\\" src=\\"/-/static/main.6126058572f989c948b1.js\\"></script>
|
<script defer=\\"defer\\" src=\\"http://domain.com/-/static/runtime.6126058572f989c948b1.js\\"></script><script defer=\\"defer\\" src=\\"http://domain.com/-/static/main.6126058572f989c948b1.js\\"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@ -84,20 +81,69 @@ exports[`template custom title 1`] = `
|
|||||||
<html lang=\\"en-us\\">
|
<html lang=\\"en-us\\">
|
||||||
<head>
|
<head>
|
||||||
<meta charset=\\"utf-8\\">
|
<meta charset=\\"utf-8\\">
|
||||||
<base href=\\"undefined\\">
|
<base href=\\"http://domain.com\\">
|
||||||
<title>foo title</title>
|
<title>foo title</title>
|
||||||
<link rel=\\"shortcut icon\\" href=\\"/-/static/favicon.ico\\"/>
|
<link rel=\\"icon\\" href=\\"http://domain.com-/static/favicon.ico\\"/>
|
||||||
<link rel=\\"icon\\" type=\\"image/png\\" href=\\"/static/foo.ico\\" />
|
|
||||||
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\" />
|
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\" />
|
||||||
<script>
|
<script>
|
||||||
window.__VERDACCIO_BASENAME_UI_OPTIONS={\\"title\\":\\"foo title\\"}
|
window.__VERDACCIO_BASENAME_UI_OPTIONS={\\"base\\":\\"http://domain.com\\",\\"title\\":\\"foo title\\"}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body class=\\"body\\">
|
<body class=\\"body\\">
|
||||||
|
|
||||||
<div id=\\"root\\"></div>
|
<div id=\\"root\\"></div>
|
||||||
<script defer=\\"defer\\" src=\\"/-/static/runtime.6126058572f989c948b1.js\\"></script>,<script defer=\\"defer\\" src=\\"/-/static/main.6126058572f989c948b1.js\\"></script>
|
<script defer=\\"defer\\" src=\\"http://domain.com/-/static/runtime.6126058572f989c948b1.js\\"></script><script defer=\\"defer\\" src=\\"http://domain.com/-/static/main.6126058572f989c948b1.js\\"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`template custom title 2`] = `
|
||||||
|
"
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang=\\"en-us\\">
|
||||||
|
<head>
|
||||||
|
<meta charset=\\"utf-8\\">
|
||||||
|
<base href=\\"http://domain.com\\">
|
||||||
|
<title>foo title</title>
|
||||||
|
<link rel=\\"icon\\" href=\\"http://domain.com-/static/favicon.ico\\"/>
|
||||||
|
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\" />
|
||||||
|
<script>
|
||||||
|
window.__VERDACCIO_BASENAME_UI_OPTIONS={\\"base\\":\\"http://domain.com\\",\\"title\\":\\"foo title\\"}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body class=\\"body\\">
|
||||||
|
|
||||||
|
<div id=\\"root\\"></div>
|
||||||
|
<script defer=\\"defer\\" src=\\"http://domain.com/-/static/runtime.6126058572f989c948b1.js\\"></script><script defer=\\"defer\\" src=\\"http://domain.com/-/static/main.6126058572f989c948b1.js\\"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`template meta scripts 1`] = `
|
||||||
|
"
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang=\\"en-us\\">
|
||||||
|
<head>
|
||||||
|
<meta charset=\\"utf-8\\">
|
||||||
|
<base href=\\"http://domain.com\\">
|
||||||
|
<title></title>
|
||||||
|
<link rel=\\"icon\\" href=\\"http://domain.com-/static/favicon.ico\\"/>
|
||||||
|
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\" />
|
||||||
|
<script>
|
||||||
|
window.__VERDACCIO_BASENAME_UI_OPTIONS={\\"base\\":\\"http://domain.com\\"}
|
||||||
|
</script>
|
||||||
|
<style>.someclass{font-size:10px;}</style>
|
||||||
|
</head>
|
||||||
|
<body class=\\"body\\">
|
||||||
|
|
||||||
|
<div id=\\"root\\"></div>
|
||||||
|
<script defer=\\"defer\\" src=\\"http://domain.com/-/static/runtime.6126058572f989c948b1.js\\"></script><script defer=\\"defer\\" src=\\"http://domain.com/-/static/main.6126058572f989c948b1.js\\"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -10,22 +10,19 @@ const mockManifest = jest.fn();
|
|||||||
jest.mock('@verdaccio/ui-theme', () => mockManifest());
|
jest.mock('@verdaccio/ui-theme', () => mockManifest());
|
||||||
|
|
||||||
describe('test web server', () => {
|
describe('test web server', () => {
|
||||||
beforeAll(() => {
|
|
||||||
mockManifest.mockReturnValue({
|
|
||||||
staticPath: path.join(__dirname, 'static'),
|
|
||||||
manifest: require('./partials/manifest/manifest.json'),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
mockManifest.mockClear();
|
mockManifest.mockClear();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should OK to package api', async () => {
|
test('should OK to package api', async () => {
|
||||||
mockManifest.mockReturnValue({
|
mockManifest.mockReturnValue(() => ({
|
||||||
|
staticPath: path.join(__dirname, 'static'),
|
||||||
|
manifestFiles: {
|
||||||
|
js: ['runtime.js', 'vendors.js', 'main.js'],
|
||||||
|
},
|
||||||
manifest: require('./partials/manifest/manifest.json'),
|
manifest: require('./partials/manifest/manifest.json'),
|
||||||
});
|
}));
|
||||||
const response = await supertest(await initializeServer('default-test.yaml'))
|
const response = await supertest(await initializeServer('default-test.yaml'))
|
||||||
.get('/-/verdaccio/packages')
|
.get('/-/verdaccio/packages')
|
||||||
.set('Accept', HEADERS.JSON_CHARSET)
|
.set('Accept', HEADERS.JSON_CHARSET)
|
||||||
|
@ -38,10 +38,13 @@ jest.mock('@verdaccio/store', () => ({
|
|||||||
|
|
||||||
describe('readme api', () => {
|
describe('readme api', () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
mockManifest.mockReturnValue({
|
mockManifest.mockReturnValue(() => ({
|
||||||
staticPath: path.join(__dirname, 'static'),
|
staticPath: path.join(__dirname, 'static'),
|
||||||
|
manifestFiles: {
|
||||||
|
js: ['runtime.js', 'vendors.js', 'main.js'],
|
||||||
|
},
|
||||||
manifest: require('./partials/manifest/manifest.json'),
|
manifest: require('./partials/manifest/manifest.json'),
|
||||||
});
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@ -50,9 +53,6 @@ describe('readme api', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should fetch readme scoped package', async () => {
|
test('should fetch readme scoped package', async () => {
|
||||||
mockManifest.mockReturnValue({
|
|
||||||
manifest: require('./partials/manifest/manifest.json'),
|
|
||||||
});
|
|
||||||
const response = await supertest(await initializeServer('default-test.yaml'))
|
const response = await supertest(await initializeServer('default-test.yaml'))
|
||||||
.get('/-/verdaccio/package/readme/@scope/pk1-test')
|
.get('/-/verdaccio/package/readme/@scope/pk1-test')
|
||||||
.set('Accept', HEADERS.TEXT_PLAIN)
|
.set('Accept', HEADERS.TEXT_PLAIN)
|
||||||
@ -62,9 +62,6 @@ describe('readme api', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should fetch readme a package', async () => {
|
test('should fetch readme a package', async () => {
|
||||||
mockManifest.mockReturnValue({
|
|
||||||
manifest: require('./partials/manifest/manifest.json'),
|
|
||||||
});
|
|
||||||
const response = await supertest(await initializeServer('default-test.yaml'))
|
const response = await supertest(await initializeServer('default-test.yaml'))
|
||||||
.get('/-/verdaccio/package/readme/pk1-test')
|
.get('/-/verdaccio/package/readme/pk1-test')
|
||||||
.set('Accept', HEADERS.TEXT_PLAIN)
|
.set('Accept', HEADERS.TEXT_PLAIN)
|
||||||
|
@ -39,10 +39,13 @@ jest.mock('@verdaccio/store', () => ({
|
|||||||
|
|
||||||
describe('test web server', () => {
|
describe('test web server', () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
mockManifest.mockReturnValue({
|
mockManifest.mockReturnValue(() => ({
|
||||||
staticPath: path.join(__dirname, 'static'),
|
staticPath: path.join(__dirname, 'static'),
|
||||||
|
manifestFiles: {
|
||||||
|
js: ['runtime.js', 'vendors.js', 'main.js'],
|
||||||
|
},
|
||||||
manifest: require('./partials/manifest/manifest.json'),
|
manifest: require('./partials/manifest/manifest.json'),
|
||||||
});
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@ -51,9 +54,6 @@ describe('test web server', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should OK to search api', async () => {
|
test('should OK to search api', async () => {
|
||||||
mockManifest.mockReturnValue({
|
|
||||||
manifest: require('./partials/manifest/manifest.json'),
|
|
||||||
});
|
|
||||||
const response = await supertest(await initializeServer('default-test.yaml'))
|
const response = await supertest(await initializeServer('default-test.yaml'))
|
||||||
.get('/-/verdaccio/search/keyword')
|
.get('/-/verdaccio/search/keyword')
|
||||||
.set('Accept', HEADERS.JSON_CHARSET)
|
.set('Accept', HEADERS.JSON_CHARSET)
|
||||||
@ -63,9 +63,6 @@ describe('test web server', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should 404 to search api', async () => {
|
test('should 404 to search api', async () => {
|
||||||
mockManifest.mockReturnValue({
|
|
||||||
manifest: require('./partials/manifest/manifest.json'),
|
|
||||||
});
|
|
||||||
mockQuery.mockReturnValue([]);
|
mockQuery.mockReturnValue([]);
|
||||||
const response = await supertest(await initializeServer('default-test.yaml'))
|
const response = await supertest(await initializeServer('default-test.yaml'))
|
||||||
.get('/-/verdaccio/search/notFound')
|
.get('/-/verdaccio/search/notFound')
|
||||||
@ -76,9 +73,6 @@ describe('test web server', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should fail search api', async () => {
|
test('should fail search api', async () => {
|
||||||
mockManifest.mockReturnValue({
|
|
||||||
manifest: require('./partials/manifest/manifest.json'),
|
|
||||||
});
|
|
||||||
mockQuery.mockImplementation(() => {
|
mockQuery.mockImplementation(() => {
|
||||||
return ['aa', 'bb', 'cc'];
|
return ['aa', 'bb', 'cc'];
|
||||||
});
|
});
|
||||||
|
@ -11,10 +11,13 @@ jest.mock('@verdaccio/ui-theme', () => mockManifest());
|
|||||||
|
|
||||||
describe('test web server', () => {
|
describe('test web server', () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
mockManifest.mockReturnValue({
|
mockManifest.mockReturnValue(() => ({
|
||||||
staticPath: path.join(__dirname, '../static'),
|
staticPath: path.join(__dirname, 'static'),
|
||||||
|
manifestFiles: {
|
||||||
|
js: ['runtime.js', 'vendors.js', 'main.js'],
|
||||||
|
},
|
||||||
manifest: require('./partials/manifest/manifest.json'),
|
manifest: require('./partials/manifest/manifest.json'),
|
||||||
});
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@ -23,9 +26,6 @@ describe('test web server', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should get 401', async () => {
|
test('should get 401', async () => {
|
||||||
mockManifest.mockReturnValue({
|
|
||||||
manifest: require('./partials/manifest/manifest.json'),
|
|
||||||
});
|
|
||||||
return supertest(await initializeServer('default-test.yaml'))
|
return supertest(await initializeServer('default-test.yaml'))
|
||||||
.post('/-/verdaccio/login')
|
.post('/-/verdaccio/login')
|
||||||
.send(
|
.send(
|
||||||
@ -43,9 +43,6 @@ describe('test web server', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should log in', async () => {
|
test('should log in', async () => {
|
||||||
mockManifest.mockReturnValue({
|
|
||||||
manifest: require('./partials/manifest/manifest.json'),
|
|
||||||
});
|
|
||||||
return supertest(await initializeServer('default-test.yaml'))
|
return supertest(await initializeServer('default-test.yaml'))
|
||||||
.post('/-/verdaccio/login')
|
.post('/-/verdaccio/login')
|
||||||
.send(
|
.send(
|
||||||
|
@ -2,7 +2,6 @@ import path from 'path';
|
|||||||
import supertest from 'supertest';
|
import supertest from 'supertest';
|
||||||
import { setup } from '@verdaccio/logger';
|
import { setup } from '@verdaccio/logger';
|
||||||
import { HEADER_TYPE, HEADERS, HTTP_STATUS } from '@verdaccio/commons-api';
|
import { HEADER_TYPE, HEADERS, HTTP_STATUS } from '@verdaccio/commons-api';
|
||||||
import { combineBaseUrl } from '../src/renderHTML';
|
|
||||||
import { initializeServer } from './helper';
|
import { initializeServer } from './helper';
|
||||||
|
|
||||||
setup([]);
|
setup([]);
|
||||||
@ -12,10 +11,13 @@ jest.mock('@verdaccio/ui-theme', () => mockManifest());
|
|||||||
|
|
||||||
describe('test web server', () => {
|
describe('test web server', () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
mockManifest.mockReturnValue({
|
mockManifest.mockReturnValue(() => ({
|
||||||
|
manifestFiles: {
|
||||||
|
js: ['runtime.js', 'vendors.js', 'main.js'],
|
||||||
|
},
|
||||||
staticPath: path.join(__dirname, 'static'),
|
staticPath: path.join(__dirname, 'static'),
|
||||||
manifest: require('./partials/manifest/manifest.json'),
|
manifest: require('./partials/manifest/manifest.json'),
|
||||||
});
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
@ -9,18 +9,52 @@ const exampleManifest = {
|
|||||||
|
|
||||||
describe('template', () => {
|
describe('template', () => {
|
||||||
test('custom render', () => {
|
test('custom render', () => {
|
||||||
expect(template({ options: {}, manifest: exampleManifest }, manifest)).toMatchSnapshot();
|
expect(
|
||||||
|
template({ options: { base: 'http://domain.com' }, manifest: exampleManifest }, manifest)
|
||||||
|
).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('custom title', () => {
|
test('custom title', () => {
|
||||||
expect(
|
expect(
|
||||||
template({ options: { title: 'foo title' }, manifest: exampleManifest }, manifest)
|
template(
|
||||||
|
{ options: { base: 'http://domain.com', title: 'foo title' }, manifest: exampleManifest },
|
||||||
|
manifest
|
||||||
|
)
|
||||||
|
).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('custom title', () => {
|
||||||
|
expect(
|
||||||
|
template(
|
||||||
|
{ options: { base: 'http://domain.com', title: 'foo title' }, manifest: exampleManifest },
|
||||||
|
manifest
|
||||||
|
)
|
||||||
|
).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('meta scripts', () => {
|
||||||
|
expect(
|
||||||
|
template(
|
||||||
|
{
|
||||||
|
options: { base: 'http://domain.com' },
|
||||||
|
metaScripts: [`<style>.someclass{font-size:10px;}</style>`],
|
||||||
|
manifest: exampleManifest,
|
||||||
|
},
|
||||||
|
manifest
|
||||||
|
)
|
||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('custom body after', () => {
|
test('custom body after', () => {
|
||||||
expect(
|
expect(
|
||||||
template({ bodyAfter: [`<script src="foo"/>`], manifest: exampleManifest }, manifest)
|
template(
|
||||||
|
{
|
||||||
|
options: { base: 'http://domain.com' },
|
||||||
|
scriptsBodyAfter: [`<script src="foo"/>`],
|
||||||
|
manifest: exampleManifest,
|
||||||
|
},
|
||||||
|
manifest
|
||||||
|
)
|
||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -28,7 +62,8 @@ describe('template', () => {
|
|||||||
expect(
|
expect(
|
||||||
template(
|
template(
|
||||||
{
|
{
|
||||||
bodyBefore: [`<script src="fooBefore"/>`, `<script src="barBefore"/>`],
|
options: { base: 'http://domain.com' },
|
||||||
|
scriptsbodyBefore: [`<script src="fooBefore"/>`, `<script src="barBefore"/>`],
|
||||||
manifest: exampleManifest,
|
manifest: exampleManifest,
|
||||||
},
|
},
|
||||||
manifest
|
manifest
|
||||||
|
20
pnpm-lock.yaml
generated
20
pnpm-lock.yaml
generated
@ -520,8 +520,6 @@ importers:
|
|||||||
fast-safe-stringify: 2.0.7
|
fast-safe-stringify: 2.0.7
|
||||||
kleur: 3.0.3
|
kleur: 3.0.3
|
||||||
lodash: 4.17.20
|
lodash: 4.17.20
|
||||||
pad-left: 2.1.0
|
|
||||||
pad-right: 0.2.2
|
|
||||||
prettier-bytes: 1.0.4
|
prettier-bytes: 1.0.4
|
||||||
pretty-ms: 5.1.0
|
pretty-ms: 5.1.0
|
||||||
devDependencies:
|
devDependencies:
|
||||||
@ -534,8 +532,6 @@ importers:
|
|||||||
fast-safe-stringify: 2.0.7
|
fast-safe-stringify: 2.0.7
|
||||||
kleur: 3.0.3
|
kleur: 3.0.3
|
||||||
lodash: 4.17.20
|
lodash: 4.17.20
|
||||||
pad-left: 2.1.0
|
|
||||||
pad-right: 0.2.2
|
|
||||||
pino: 6.2.1
|
pino: 6.2.1
|
||||||
prettier-bytes: 1.0.4
|
prettier-bytes: 1.0.4
|
||||||
pretty-ms: 5.1.0
|
pretty-ms: 5.1.0
|
||||||
@ -21345,22 +21341,6 @@ packages:
|
|||||||
node: '>=8'
|
node: '>=8'
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==
|
integrity: sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==
|
||||||
/pad-left/2.1.0:
|
|
||||||
dependencies:
|
|
||||||
repeat-string: 1.6.1
|
|
||||||
dev: false
|
|
||||||
engines:
|
|
||||||
node: '>=0.10.0'
|
|
||||||
resolution:
|
|
||||||
integrity: sha1-FuajstRKjhOMsIOMx8tAOk/J6ZQ=
|
|
||||||
/pad-right/0.2.2:
|
|
||||||
dependencies:
|
|
||||||
repeat-string: 1.6.1
|
|
||||||
dev: false
|
|
||||||
engines:
|
|
||||||
node: '>=0.10.0'
|
|
||||||
resolution:
|
|
||||||
integrity: sha1-b7ySQEXSRPKiokRQMGDTv8YAl3Q=
|
|
||||||
/pako/1.0.11:
|
/pako/1.0.11:
|
||||||
dev: false
|
dev: false
|
||||||
resolution:
|
resolution:
|
||||||
|
Loading…
Reference in New Issue
Block a user