@verdaccio/middleware 7.0.0-next.6 → 8.0.0-next-8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +216 -0
- package/build/index.js.map +1 -1
- package/build/middlewares/allow.js +2 -2
- package/build/middlewares/allow.js.map +1 -1
- package/build/middlewares/antiLoop.js +1 -1
- package/build/middlewares/antiLoop.js.map +1 -1
- package/build/middlewares/encode-pkg.js.map +1 -1
- package/build/middlewares/error.js +1 -1
- package/build/middlewares/error.js.map +1 -1
- package/build/middlewares/final.js +2 -2
- package/build/middlewares/final.js.map +1 -1
- package/build/middlewares/json.js.map +1 -1
- package/build/middlewares/log.js +1 -1
- package/build/middlewares/log.js.map +1 -1
- package/build/middlewares/match.js.map +1 -1
- package/build/middlewares/media.js.map +1 -1
- package/build/middlewares/rate-limit.js +1 -1
- package/build/middlewares/rate-limit.js.map +1 -1
- package/build/middlewares/security-headers.js.map +1 -1
- package/build/middlewares/user-agent.js.map +1 -1
- package/build/middlewares/validation.js.map +1 -1
- package/build/middlewares/web/index.js +1 -1
- package/build/middlewares/web/index.js.map +1 -1
- package/build/middlewares/web/render-web.js +46 -26
- package/build/middlewares/web/render-web.js.map +1 -1
- package/build/middlewares/web/security.js.map +1 -1
- package/build/middlewares/web/utils/manifest.js +8 -2
- package/build/middlewares/web/utils/manifest.js.map +1 -1
- package/build/middlewares/web/utils/renderHTML.d.ts +6 -2
- package/build/middlewares/web/utils/renderHTML.js +30 -24
- package/build/middlewares/web/utils/renderHTML.js.map +1 -1
- package/build/middlewares/web/utils/template.js +7 -7
- package/build/middlewares/web/utils/template.js.map +1 -1
- package/build/middlewares/web/utils/web-utils.js +2 -2
- package/build/middlewares/web/utils/web-utils.js.map +1 -1
- package/build/middlewares/web/web-api.js +1 -1
- package/build/middlewares/web/web-api.js.map +1 -1
- package/build/middlewares/web/web-middleware.js +1 -1
- package/build/middlewares/web/web-middleware.js.map +1 -1
- package/build/types.js.map +1 -1
- package/package.json +14 -13
- package/src/middlewares/web/render-web.ts +46 -26
- package/src/middlewares/web/utils/manifest.ts +9 -1
- package/src/middlewares/web/utils/renderHTML.ts +34 -12
- package/src/middlewares/web/utils/template.ts +6 -6
- package/test/__snapshots__/template.test.ts.snap +49 -69
- package/test/config/favicon.ico +0 -0
- package/test/config/file-logo.yaml +2 -0
- package/test/config/http-logo.yaml +26 -0
- package/test/config/no-logo.yaml +1 -0
- package/test/manifest.test.ts +12 -0
- package/test/render.spec.ts +23 -0
- package/test/template.test.ts +10 -15
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verdaccio/middleware",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0-next-8.1",
|
|
4
4
|
"description": "express middleware utils",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -29,25 +29,25 @@
|
|
|
29
29
|
"node": ">=12"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@verdaccio/
|
|
33
|
-
"@verdaccio/
|
|
34
|
-
"@verdaccio/
|
|
35
|
-
"@verdaccio/
|
|
36
|
-
"debug": "4.3.
|
|
37
|
-
"
|
|
38
|
-
"express": "
|
|
32
|
+
"@verdaccio/config": "8.0.0-next-8.1",
|
|
33
|
+
"@verdaccio/core": "8.0.0-next-8.1",
|
|
34
|
+
"@verdaccio/url": "13.0.0-next-8.1",
|
|
35
|
+
"@verdaccio/utils": "7.0.1-next-8.1",
|
|
36
|
+
"debug": "4.3.7",
|
|
37
|
+
"express": "4.21.0",
|
|
38
|
+
"express-rate-limit": "5.5.1",
|
|
39
39
|
"lodash": "4.17.21",
|
|
40
|
-
"
|
|
41
|
-
"
|
|
40
|
+
"lru-cache": "7.18.3",
|
|
41
|
+
"mime": "2.6.0"
|
|
42
42
|
},
|
|
43
43
|
"funding": {
|
|
44
44
|
"type": "opencollective",
|
|
45
45
|
"url": "https://opencollective.com/verdaccio"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@verdaccio/logger": "
|
|
49
|
-
"body-parser": "1.20.
|
|
50
|
-
"supertest": "
|
|
48
|
+
"@verdaccio/logger": "8.0.0-next-8.1",
|
|
49
|
+
"body-parser": "1.20.3",
|
|
50
|
+
"supertest": "7.0.0"
|
|
51
51
|
},
|
|
52
52
|
"scripts": {
|
|
53
53
|
"clean": "rimraf ./build",
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
"build:js": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps",
|
|
57
57
|
"watch": "pnpm build:js -- --watch",
|
|
58
58
|
"test": "jest",
|
|
59
|
+
"test:snap": "jest --updateSnapshot",
|
|
59
60
|
"build": "pnpm run build:js && pnpm run build:types"
|
|
60
61
|
}
|
|
61
62
|
}
|
|
@@ -37,39 +37,59 @@ export function renderWebMiddleware(config, tokenMiddleware, pluginOptions) {
|
|
|
37
37
|
// any match within the static is routed to the file system
|
|
38
38
|
router.get('/-/static/*', function (req, res, next) {
|
|
39
39
|
const filename = req.params[0];
|
|
40
|
-
|
|
40
|
+
let file = `${staticPath}/${filename}`;
|
|
41
|
+
if (filename === 'favicon.ico' && config?.web?.favicon) {
|
|
42
|
+
file = config?.web?.favicon;
|
|
43
|
+
if (isURLhasValidProtocol(file)) {
|
|
44
|
+
debug('redirect to favicon %s', file);
|
|
45
|
+
req.url = file;
|
|
46
|
+
return next();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
41
49
|
debug('render static file %o', file);
|
|
42
50
|
res.sendFile(file, sendFileCallback(next));
|
|
43
51
|
});
|
|
44
52
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
53
|
+
function renderLogo(logo: string | undefined): string | undefined {
|
|
54
|
+
// check the origin of the logo
|
|
55
|
+
if (logo && !isURLhasValidProtocol(logo)) {
|
|
56
|
+
// URI related to a local file
|
|
57
|
+
const absoluteLocalFile = path.posix.resolve(logo);
|
|
58
|
+
debug('serve local logo %s', absoluteLocalFile);
|
|
59
|
+
try {
|
|
60
|
+
// TODO: replace existsSync by async alternative
|
|
61
|
+
if (
|
|
62
|
+
fs.existsSync(absoluteLocalFile) &&
|
|
63
|
+
typeof fs.accessSync(absoluteLocalFile, fs.constants.R_OK) === 'undefined'
|
|
64
|
+
) {
|
|
65
|
+
// Note: `path.join` will break on Windows, because it transforms `/` to `\`
|
|
66
|
+
// Use POSIX version `path.posix.join` instead.
|
|
67
|
+
logo = path.posix.join('/-/static/', path.basename(logo));
|
|
68
|
+
router.get(logo, function (_req, res, next) {
|
|
69
|
+
// @ts-ignore
|
|
70
|
+
debug('serve custom logo web:%s - local:%s', logo, absoluteLocalFile);
|
|
71
|
+
res.sendFile(absoluteLocalFile, sendFileCallback(next));
|
|
72
|
+
});
|
|
73
|
+
debug('enabled custom logo %s', logo);
|
|
74
|
+
} else {
|
|
75
|
+
logo = undefined;
|
|
76
|
+
debug(`web logo is wrong, path ${absoluteLocalFile} does not exist or is not readable`);
|
|
77
|
+
}
|
|
78
|
+
} catch {
|
|
79
|
+
logo = undefined;
|
|
67
80
|
debug(`web logo is wrong, path ${absoluteLocalFile} does not exist or is not readable`);
|
|
68
81
|
}
|
|
69
|
-
} catch {
|
|
70
|
-
config.web.logo = undefined;
|
|
71
|
-
debug(`web logo is wrong, path ${absoluteLocalFile} does not exist or is not readable`);
|
|
72
82
|
}
|
|
83
|
+
return logo;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const logo = renderLogo(config?.web?.logo);
|
|
87
|
+
if (config?.web?.logo) {
|
|
88
|
+
config.web.logo = logo;
|
|
89
|
+
}
|
|
90
|
+
const logoDark = renderLogo(config?.web?.logoDark);
|
|
91
|
+
if (config?.web?.logoDark) {
|
|
92
|
+
config.web.logoDark = logoDark;
|
|
73
93
|
}
|
|
74
94
|
|
|
75
95
|
router.get('/-/web/:section/*', function (req, res) {
|
|
@@ -16,8 +16,16 @@ export function getManifestValue(
|
|
|
16
16
|
): string[] {
|
|
17
17
|
return manifestItems?.map((item) => {
|
|
18
18
|
debug('resolve item %o', item);
|
|
19
|
-
const resolvedItem = `${basePath}
|
|
19
|
+
const resolvedItem = `${stripTrailingSlash(basePath)}/${stripLeadingSlash(manifest[item])}`;
|
|
20
20
|
debug('resolved item %o', resolvedItem);
|
|
21
21
|
return resolvedItem;
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
|
+
|
|
25
|
+
function stripTrailingSlash(path: string): string {
|
|
26
|
+
return path.replace(/\/$/, '');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function stripLeadingSlash(path: string): string {
|
|
30
|
+
return path.replace(/^\//, '');
|
|
31
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import buildDebug from 'debug';
|
|
2
|
+
import type { Response } from 'express';
|
|
2
3
|
import LRU from 'lru-cache';
|
|
3
4
|
import path from 'path';
|
|
4
5
|
import { URL } from 'url';
|
|
@@ -6,10 +7,12 @@ import { URL } from 'url';
|
|
|
6
7
|
import { WEB_TITLE } from '@verdaccio/config';
|
|
7
8
|
import { HEADERS } from '@verdaccio/core';
|
|
8
9
|
import { ConfigYaml, TemplateUIOptions } from '@verdaccio/types';
|
|
9
|
-
import {
|
|
10
|
-
import { getPublicUrl } from '@verdaccio/url';
|
|
10
|
+
import type { RequestOptions } from '@verdaccio/url';
|
|
11
|
+
import { getPublicUrl, isURLhasValidProtocol } from '@verdaccio/url';
|
|
11
12
|
|
|
13
|
+
import type { Manifest } from './manifest';
|
|
12
14
|
import renderTemplate from './template';
|
|
15
|
+
import type { WebpackManifest } from './template';
|
|
13
16
|
import { hasLogin, validatePrimaryColor } from './web-utils';
|
|
14
17
|
|
|
15
18
|
const DEFAULT_LANGUAGE = 'es-US';
|
|
@@ -17,29 +20,40 @@ const cache = new LRU({ max: 500, ttl: 1000 * 60 * 60 });
|
|
|
17
20
|
|
|
18
21
|
const debug = buildDebug('verdaccio:web:render');
|
|
19
22
|
|
|
20
|
-
const defaultManifestFiles = {
|
|
23
|
+
const defaultManifestFiles: Manifest = {
|
|
21
24
|
js: ['runtime.js', 'vendors.js', 'main.js'],
|
|
22
25
|
ico: 'favicon.ico',
|
|
26
|
+
css: [],
|
|
23
27
|
};
|
|
24
28
|
|
|
25
|
-
export function resolveLogo(
|
|
26
|
-
|
|
29
|
+
export function resolveLogo(
|
|
30
|
+
logo: string | undefined,
|
|
31
|
+
url_prefix: string | undefined,
|
|
32
|
+
requestOptions: RequestOptions
|
|
33
|
+
) {
|
|
34
|
+
if (typeof logo !== 'string') {
|
|
27
35
|
return '';
|
|
28
36
|
}
|
|
29
|
-
const isLocalFile =
|
|
37
|
+
const isLocalFile = logo && !isURLhasValidProtocol(logo);
|
|
30
38
|
|
|
31
39
|
if (isLocalFile) {
|
|
32
|
-
return `${getPublicUrl(
|
|
33
|
-
} else if (isURLhasValidProtocol(
|
|
34
|
-
return
|
|
40
|
+
return `${getPublicUrl(url_prefix, requestOptions)}-/static/${path.basename(logo)}`;
|
|
41
|
+
} else if (isURLhasValidProtocol(logo)) {
|
|
42
|
+
return logo;
|
|
35
43
|
} else {
|
|
36
44
|
return '';
|
|
37
45
|
}
|
|
38
46
|
}
|
|
39
47
|
|
|
40
|
-
export default function renderHTML(
|
|
48
|
+
export default function renderHTML(
|
|
49
|
+
config: ConfigYaml,
|
|
50
|
+
manifest: WebpackManifest,
|
|
51
|
+
manifestFiles: Manifest | null | undefined,
|
|
52
|
+
requestOptions: RequestOptions,
|
|
53
|
+
res: Response
|
|
54
|
+
) {
|
|
41
55
|
const { url_prefix } = config;
|
|
42
|
-
const base = getPublicUrl(config?.url_prefix,
|
|
56
|
+
const base = getPublicUrl(config?.url_prefix, requestOptions);
|
|
43
57
|
const basename = new URL(base).pathname;
|
|
44
58
|
const language = config?.i18n?.web ?? DEFAULT_LANGUAGE;
|
|
45
59
|
const hideDeprecatedVersions = config?.web?.hideDeprecatedVersions ?? false;
|
|
@@ -51,7 +65,9 @@ export default function renderHTML(config: ConfigYaml, manifest, manifestFiles,
|
|
|
51
65
|
const title = config?.web?.title ?? WEB_TITLE;
|
|
52
66
|
const login = hasLogin(config);
|
|
53
67
|
const scope = config?.web?.scope ?? '';
|
|
54
|
-
const
|
|
68
|
+
const favicon = resolveLogo(config?.web?.favicon, config?.url_prefix, requestOptions);
|
|
69
|
+
const logo = resolveLogo(config?.web?.logo, config?.url_prefix, requestOptions);
|
|
70
|
+
const logoDark = resolveLogo(config?.web?.logoDark, config?.url_prefix, requestOptions);
|
|
55
71
|
const pkgManagers = config?.web?.pkgManagers ?? ['yarn', 'pnpm', 'npm'];
|
|
56
72
|
const version = res.locals.app_version ?? '';
|
|
57
73
|
const flags = {
|
|
@@ -71,6 +87,8 @@ export default function renderHTML(config: ConfigYaml, manifest, manifestFiles,
|
|
|
71
87
|
showFooter,
|
|
72
88
|
showSearch,
|
|
73
89
|
showDownloadTarball,
|
|
90
|
+
showRaw,
|
|
91
|
+
showUplinks,
|
|
74
92
|
} = Object.assign(
|
|
75
93
|
{},
|
|
76
94
|
{
|
|
@@ -87,6 +105,8 @@ export default function renderHTML(config: ConfigYaml, manifest, manifestFiles,
|
|
|
87
105
|
showFooter,
|
|
88
106
|
showSearch,
|
|
89
107
|
showDownloadTarball,
|
|
108
|
+
showRaw,
|
|
109
|
+
showUplinks,
|
|
90
110
|
darkMode,
|
|
91
111
|
url_prefix,
|
|
92
112
|
basename,
|
|
@@ -94,6 +114,8 @@ export default function renderHTML(config: ConfigYaml, manifest, manifestFiles,
|
|
|
94
114
|
primaryColor,
|
|
95
115
|
version,
|
|
96
116
|
logo,
|
|
117
|
+
logoDark,
|
|
118
|
+
favicon,
|
|
97
119
|
flags,
|
|
98
120
|
login,
|
|
99
121
|
pkgManagers,
|
|
@@ -25,24 +25,24 @@ export default function renderTemplate(template: Template, manifest: WebpackMani
|
|
|
25
25
|
|
|
26
26
|
return `
|
|
27
27
|
<!DOCTYPE html>
|
|
28
|
-
<html lang="en-us">
|
|
28
|
+
<html lang="en-us">
|
|
29
29
|
<head>
|
|
30
30
|
<meta charset="utf-8">
|
|
31
31
|
<base href="${template?.options.base}">
|
|
32
|
-
<title>${template?.options?.title ?? ''}</title>
|
|
32
|
+
<title>${template?.options?.title ?? ''}</title>
|
|
33
33
|
<link rel="icon" href="${template?.options.base}-/static/favicon.ico"/>
|
|
34
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
34
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
35
35
|
<script>
|
|
36
36
|
window.__VERDACCIO_BASENAME_UI_OPTIONS=${JSON.stringify(template.options)}
|
|
37
37
|
</script>
|
|
38
38
|
${template?.metaScripts ? template.metaScripts.join('') : ''}
|
|
39
|
-
</head>
|
|
39
|
+
</head>
|
|
40
40
|
<body class="body">
|
|
41
|
-
|
|
41
|
+
${template?.scriptsbodyBefore ? template.scriptsbodyBefore.join('') : ''}
|
|
42
42
|
<div id="root"></div>
|
|
43
43
|
${getManifestValue(template.manifest.js, manifest, template?.options.base)
|
|
44
44
|
.map((item) => `<script defer="defer" src="${item}"></script>`)
|
|
45
|
-
.join(
|
|
45
|
+
.join(`\n `)}
|
|
46
46
|
${template?.scriptsBodyAfter ? template.scriptsBodyAfter.join('') : ''}
|
|
47
47
|
</body>
|
|
48
48
|
</html>
|
|
@@ -3,22 +3,23 @@
|
|
|
3
3
|
exports[`template custom body after 1`] = `
|
|
4
4
|
"
|
|
5
5
|
<!DOCTYPE html>
|
|
6
|
-
<html lang="en-us">
|
|
6
|
+
<html lang="en-us">
|
|
7
7
|
<head>
|
|
8
8
|
<meta charset="utf-8">
|
|
9
|
-
<base href="http://domain.com">
|
|
10
|
-
<title></title>
|
|
11
|
-
<link rel="icon" href="http://domain.com
|
|
12
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
9
|
+
<base href="http://domain.com/">
|
|
10
|
+
<title></title>
|
|
11
|
+
<link rel="icon" href="http://domain.com/-/static/favicon.ico"/>
|
|
12
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
13
13
|
<script>
|
|
14
|
-
window.__VERDACCIO_BASENAME_UI_OPTIONS={"base":"http://domain.com"}
|
|
14
|
+
window.__VERDACCIO_BASENAME_UI_OPTIONS={"base":"http://domain.com/"}
|
|
15
15
|
</script>
|
|
16
16
|
|
|
17
|
-
</head>
|
|
17
|
+
</head>
|
|
18
18
|
<body class="body">
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
<div id="root"></div>
|
|
21
|
-
<script defer="defer" src="http://domain.com/-/static/runtime.6126058572f989c948b1.js"></script
|
|
21
|
+
<script defer="defer" src="http://domain.com/-/static/runtime.6126058572f989c948b1.js"></script>
|
|
22
|
+
<script defer="defer" src="http://domain.com/-/static/main.6126058572f989c948b1.js"></script>
|
|
22
23
|
<script src="foo"/>
|
|
23
24
|
</body>
|
|
24
25
|
</html>
|
|
@@ -28,22 +29,23 @@ exports[`template custom body after 1`] = `
|
|
|
28
29
|
exports[`template custom body before 1`] = `
|
|
29
30
|
"
|
|
30
31
|
<!DOCTYPE html>
|
|
31
|
-
<html lang="en-us">
|
|
32
|
+
<html lang="en-us">
|
|
32
33
|
<head>
|
|
33
34
|
<meta charset="utf-8">
|
|
34
|
-
<base href="http://domain.com">
|
|
35
|
-
<title></title>
|
|
36
|
-
<link rel="icon" href="http://domain.com
|
|
37
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
35
|
+
<base href="http://domain.com/">
|
|
36
|
+
<title></title>
|
|
37
|
+
<link rel="icon" href="http://domain.com/-/static/favicon.ico"/>
|
|
38
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
38
39
|
<script>
|
|
39
|
-
window.__VERDACCIO_BASENAME_UI_OPTIONS={"base":"http://domain.com"}
|
|
40
|
+
window.__VERDACCIO_BASENAME_UI_OPTIONS={"base":"http://domain.com/"}
|
|
40
41
|
</script>
|
|
41
42
|
|
|
42
|
-
</head>
|
|
43
|
+
</head>
|
|
43
44
|
<body class="body">
|
|
44
|
-
|
|
45
|
+
<script src="fooBefore"/><script src="barBefore"/>
|
|
45
46
|
<div id="root"></div>
|
|
46
|
-
<script defer="defer" src="http://domain.com/-/static/runtime.6126058572f989c948b1.js"></script
|
|
47
|
+
<script defer="defer" src="http://domain.com/-/static/runtime.6126058572f989c948b1.js"></script>
|
|
48
|
+
<script defer="defer" src="http://domain.com/-/static/main.6126058572f989c948b1.js"></script>
|
|
47
49
|
|
|
48
50
|
</body>
|
|
49
51
|
</html>
|
|
@@ -53,22 +55,23 @@ exports[`template custom body before 1`] = `
|
|
|
53
55
|
exports[`template custom render 1`] = `
|
|
54
56
|
"
|
|
55
57
|
<!DOCTYPE html>
|
|
56
|
-
<html lang="en-us">
|
|
58
|
+
<html lang="en-us">
|
|
57
59
|
<head>
|
|
58
60
|
<meta charset="utf-8">
|
|
59
|
-
<base href="http://domain.com">
|
|
60
|
-
<title></title>
|
|
61
|
-
<link rel="icon" href="http://domain.com
|
|
62
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
61
|
+
<base href="http://domain.com/">
|
|
62
|
+
<title></title>
|
|
63
|
+
<link rel="icon" href="http://domain.com/-/static/favicon.ico"/>
|
|
64
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
63
65
|
<script>
|
|
64
|
-
window.__VERDACCIO_BASENAME_UI_OPTIONS={"base":"http://domain.com"}
|
|
66
|
+
window.__VERDACCIO_BASENAME_UI_OPTIONS={"base":"http://domain.com/"}
|
|
65
67
|
</script>
|
|
66
68
|
|
|
67
|
-
</head>
|
|
69
|
+
</head>
|
|
68
70
|
<body class="body">
|
|
69
|
-
|
|
71
|
+
|
|
70
72
|
<div id="root"></div>
|
|
71
|
-
<script defer="defer" src="http://domain.com/-/static/runtime.6126058572f989c948b1.js"></script
|
|
73
|
+
<script defer="defer" src="http://domain.com/-/static/runtime.6126058572f989c948b1.js"></script>
|
|
74
|
+
<script defer="defer" src="http://domain.com/-/static/main.6126058572f989c948b1.js"></script>
|
|
72
75
|
|
|
73
76
|
</body>
|
|
74
77
|
</html>
|
|
@@ -78,47 +81,23 @@ exports[`template custom render 1`] = `
|
|
|
78
81
|
exports[`template custom title 1`] = `
|
|
79
82
|
"
|
|
80
83
|
<!DOCTYPE html>
|
|
81
|
-
<html lang="en-us">
|
|
84
|
+
<html lang="en-us">
|
|
82
85
|
<head>
|
|
83
86
|
<meta charset="utf-8">
|
|
84
|
-
<base href="http://domain.com">
|
|
85
|
-
<title>foo title</title>
|
|
86
|
-
<link rel="icon" href="http://domain.com
|
|
87
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
87
|
+
<base href="http://domain.com/">
|
|
88
|
+
<title>foo title</title>
|
|
89
|
+
<link rel="icon" href="http://domain.com/-/static/favicon.ico"/>
|
|
90
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
88
91
|
<script>
|
|
89
|
-
window.__VERDACCIO_BASENAME_UI_OPTIONS={"base":"http://domain.com","title":"foo title"}
|
|
92
|
+
window.__VERDACCIO_BASENAME_UI_OPTIONS={"base":"http://domain.com/","title":"foo title"}
|
|
90
93
|
</script>
|
|
91
94
|
|
|
92
|
-
</head>
|
|
95
|
+
</head>
|
|
93
96
|
<body class="body">
|
|
94
|
-
|
|
95
|
-
<div id="root"></div>
|
|
96
|
-
<script defer="defer" src="http://domain.com/-/static/runtime.6126058572f989c948b1.js"></script><script defer="defer" src="http://domain.com/-/static/main.6126058572f989c948b1.js"></script>
|
|
97
97
|
|
|
98
|
-
</body>
|
|
99
|
-
</html>
|
|
100
|
-
"
|
|
101
|
-
`;
|
|
102
|
-
|
|
103
|
-
exports[`template custom title 2`] = `
|
|
104
|
-
"
|
|
105
|
-
<!DOCTYPE html>
|
|
106
|
-
<html lang="en-us">
|
|
107
|
-
<head>
|
|
108
|
-
<meta charset="utf-8">
|
|
109
|
-
<base href="http://domain.com">
|
|
110
|
-
<title>foo title</title>
|
|
111
|
-
<link rel="icon" href="http://domain.com-/static/favicon.ico"/>
|
|
112
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
113
|
-
<script>
|
|
114
|
-
window.__VERDACCIO_BASENAME_UI_OPTIONS={"base":"http://domain.com","title":"foo title"}
|
|
115
|
-
</script>
|
|
116
|
-
|
|
117
|
-
</head>
|
|
118
|
-
<body class="body">
|
|
119
|
-
|
|
120
98
|
<div id="root"></div>
|
|
121
|
-
<script defer="defer" src="http://domain.com/-/static/runtime.6126058572f989c948b1.js"></script
|
|
99
|
+
<script defer="defer" src="http://domain.com/-/static/runtime.6126058572f989c948b1.js"></script>
|
|
100
|
+
<script defer="defer" src="http://domain.com/-/static/main.6126058572f989c948b1.js"></script>
|
|
122
101
|
|
|
123
102
|
</body>
|
|
124
103
|
</html>
|
|
@@ -128,22 +107,23 @@ exports[`template custom title 2`] = `
|
|
|
128
107
|
exports[`template meta scripts 1`] = `
|
|
129
108
|
"
|
|
130
109
|
<!DOCTYPE html>
|
|
131
|
-
<html lang="en-us">
|
|
110
|
+
<html lang="en-us">
|
|
132
111
|
<head>
|
|
133
112
|
<meta charset="utf-8">
|
|
134
|
-
<base href="http://domain.com">
|
|
135
|
-
<title></title>
|
|
136
|
-
<link rel="icon" href="http://domain.com
|
|
137
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
113
|
+
<base href="http://domain.com/">
|
|
114
|
+
<title></title>
|
|
115
|
+
<link rel="icon" href="http://domain.com/-/static/favicon.ico"/>
|
|
116
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
138
117
|
<script>
|
|
139
|
-
window.__VERDACCIO_BASENAME_UI_OPTIONS={"base":"http://domain.com"}
|
|
118
|
+
window.__VERDACCIO_BASENAME_UI_OPTIONS={"base":"http://domain.com/"}
|
|
140
119
|
</script>
|
|
141
120
|
<style>.someclass{font-size:10px;}</style>
|
|
142
|
-
</head>
|
|
121
|
+
</head>
|
|
143
122
|
<body class="body">
|
|
144
|
-
|
|
123
|
+
|
|
145
124
|
<div id="root"></div>
|
|
146
|
-
<script defer="defer" src="http://domain.com/-/static/runtime.6126058572f989c948b1.js"></script
|
|
125
|
+
<script defer="defer" src="http://domain.com/-/static/runtime.6126058572f989c948b1.js"></script>
|
|
126
|
+
<script defer="defer" src="http://domain.com/-/static/main.6126058572f989c948b1.js"></script>
|
|
147
127
|
|
|
148
128
|
</body>
|
|
149
129
|
</html>
|
|
Binary file
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
web:
|
|
2
|
+
title: verdaccio web
|
|
3
|
+
login: true
|
|
4
|
+
scope: '@scope'
|
|
5
|
+
pkgManagers:
|
|
6
|
+
- pnpm
|
|
7
|
+
- yarn
|
|
8
|
+
showInfo: true
|
|
9
|
+
showSettings: true
|
|
10
|
+
showSearch: true
|
|
11
|
+
showFooter: true
|
|
12
|
+
showThemeSwitch: true
|
|
13
|
+
showDownloadTarball: true
|
|
14
|
+
showRaw: true
|
|
15
|
+
primary_color: '#ffffff'
|
|
16
|
+
logo: https://raw.githubusercontent.com/verdaccio/verdaccio/master/assets/svg/logo-small.svg
|
|
17
|
+
logoDark: https://raw.githubusercontent.com/verdaccio/verdaccio/master/assets/svg/logo-blackwhite.svg
|
|
18
|
+
favicon: https://raw.githubusercontent.com/verdaccio/verdaccio/master/website/static/img/favicon/favicon.ico
|
|
19
|
+
html_cache: false
|
|
20
|
+
|
|
21
|
+
url_prefix: /prefix
|
|
22
|
+
|
|
23
|
+
log: { type: stdout, format: pretty, level: trace }
|
|
24
|
+
|
|
25
|
+
flags:
|
|
26
|
+
changePassword: true
|
package/test/config/no-logo.yaml
CHANGED
package/test/manifest.test.ts
CHANGED
|
@@ -8,4 +8,16 @@ describe('manifest', () => {
|
|
|
8
8
|
'/-/static/main.6126058572f989c948b1.js',
|
|
9
9
|
]);
|
|
10
10
|
});
|
|
11
|
+
|
|
12
|
+
test('getManifestValue with base', () => {
|
|
13
|
+
expect(getManifestValue(['favicon.ico'], manifest, 'http://domain.com')).toEqual([
|
|
14
|
+
'http://domain.com/-/static/favicon.ico',
|
|
15
|
+
]);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('getManifestValue with base with trailing slash', () => {
|
|
19
|
+
expect(getManifestValue(['favicon.ico'], manifest, 'http://domain.com/')).toEqual([
|
|
20
|
+
'http://domain.com/-/static/favicon.ico',
|
|
21
|
+
]);
|
|
22
|
+
});
|
|
11
23
|
});
|
package/test/render.spec.ts
CHANGED
|
@@ -79,6 +79,28 @@ describe('test web server', () => {
|
|
|
79
79
|
return loadLogo('file-logo.yaml', '/-/static/dark-logo.png');
|
|
80
80
|
});
|
|
81
81
|
|
|
82
|
+
test('should render dark logo as file', async () => {
|
|
83
|
+
const {
|
|
84
|
+
window: { __VERDACCIO_BASENAME_UI_OPTIONS },
|
|
85
|
+
} = await render('file-logo.yaml');
|
|
86
|
+
expect(__VERDACCIO_BASENAME_UI_OPTIONS.logoDark).toMatch('/prefix/-/static/dark-logo.png');
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('should render favicon as file', async () => {
|
|
90
|
+
const {
|
|
91
|
+
window: { __VERDACCIO_BASENAME_UI_OPTIONS },
|
|
92
|
+
} = await render('file-logo.yaml');
|
|
93
|
+
expect(__VERDACCIO_BASENAME_UI_OPTIONS.favicon).toMatch('/prefix/-/static/favicon.ico');
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('should render logo and favicon as URL', async () => {
|
|
97
|
+
const {
|
|
98
|
+
window: { __VERDACCIO_BASENAME_UI_OPTIONS },
|
|
99
|
+
} = await render('http-logo.yaml');
|
|
100
|
+
expect(__VERDACCIO_BASENAME_UI_OPTIONS.logo).toMatch(/https:.*logo-small.svg/i);
|
|
101
|
+
expect(__VERDACCIO_BASENAME_UI_OPTIONS.favicon).toMatch(/https:.*favicon.ico/i);
|
|
102
|
+
});
|
|
103
|
+
|
|
82
104
|
test('should not render logo as absolute file is wrong', async () => {
|
|
83
105
|
const {
|
|
84
106
|
window: { __VERDACCIO_BASENAME_UI_OPTIONS },
|
|
@@ -91,6 +113,7 @@ describe('test web server', () => {
|
|
|
91
113
|
window: { __VERDACCIO_BASENAME_UI_OPTIONS },
|
|
92
114
|
} = await render('no-logo.yaml');
|
|
93
115
|
expect(__VERDACCIO_BASENAME_UI_OPTIONS.logo).toEqual('');
|
|
116
|
+
expect(__VERDACCIO_BASENAME_UI_OPTIONS.favicon).toEqual('');
|
|
94
117
|
});
|
|
95
118
|
|
|
96
119
|
test.todo('should default title');
|