@verdaccio/web 6.0.0-6-next.28 → 6.0.0-6-next.29
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 +7 -0
- package/build/renderHTML.js +14 -5
- package/build/renderHTML.js.map +1 -1
- package/build/utils/web-utils.js +1 -1
- package/build/utils/web-utils.js.map +1 -1
- package/package.json +70 -69
- package/src/renderHTML.ts +18 -6
- package/src/utils/web-utils.ts +1 -1
- package/test/config/web.yaml +46 -0
- package/test/render.test.ts +71 -24
- package/test/utils.spec.ts +10 -1
package/CHANGELOG.md
CHANGED
package/build/renderHTML.js
CHANGED
|
@@ -59,13 +59,25 @@ function renderHTML(config, manifest, manifestFiles, req, res) {
|
|
|
59
59
|
const {
|
|
60
60
|
scriptsBodyAfter,
|
|
61
61
|
metaScripts,
|
|
62
|
-
scriptsbodyBefore
|
|
62
|
+
scriptsbodyBefore,
|
|
63
|
+
showInfo,
|
|
64
|
+
showSettings,
|
|
65
|
+
showThemeSwitch,
|
|
66
|
+
showFooter,
|
|
67
|
+
showSearch,
|
|
68
|
+
showDownloadTarball
|
|
63
69
|
} = Object.assign({}, {
|
|
64
70
|
scriptsBodyAfter: [],
|
|
65
71
|
bodyBefore: [],
|
|
66
72
|
metaScripts: []
|
|
67
73
|
}, config === null || config === void 0 ? void 0 : config.web);
|
|
68
74
|
const options = {
|
|
75
|
+
showInfo,
|
|
76
|
+
showSettings,
|
|
77
|
+
showThemeSwitch,
|
|
78
|
+
showFooter,
|
|
79
|
+
showSearch,
|
|
80
|
+
showDownloadTarball,
|
|
69
81
|
darkMode,
|
|
70
82
|
url_prefix,
|
|
71
83
|
basename,
|
|
@@ -86,8 +98,6 @@ function renderHTML(config, manifest, manifestFiles, req, res) {
|
|
|
86
98
|
webPage = cache.get('template');
|
|
87
99
|
|
|
88
100
|
if (!webPage) {
|
|
89
|
-
debug('web options %o', options);
|
|
90
|
-
debug('web manifestFiles %o', manifestFiles);
|
|
91
101
|
webPage = (0, _template.default)({
|
|
92
102
|
manifest: manifestFiles ?? defaultManifestFiles,
|
|
93
103
|
options,
|
|
@@ -95,7 +105,6 @@ function renderHTML(config, manifest, manifestFiles, req, res) {
|
|
|
95
105
|
metaScripts,
|
|
96
106
|
scriptsbodyBefore
|
|
97
107
|
}, manifest);
|
|
98
|
-
debug('template :: %o', webPage);
|
|
99
108
|
|
|
100
109
|
if (needHtmlCache) {
|
|
101
110
|
cache.set('template', webPage);
|
|
@@ -110,6 +119,6 @@ function renderHTML(config, manifest, manifestFiles, req, res) {
|
|
|
110
119
|
|
|
111
120
|
res.setHeader('Content-Type', _core.HEADERS.TEXT_HTML);
|
|
112
121
|
res.send(webPage);
|
|
113
|
-
debug('
|
|
122
|
+
debug('web rendered');
|
|
114
123
|
}
|
|
115
124
|
//# sourceMappingURL=renderHTML.js.map
|
package/build/renderHTML.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/renderHTML.ts"],"names":["pkgJSON","require","DEFAULT_LANGUAGE","cache","LRU","max","maxAge","debug","defaultManifestFiles","js","ico","renderHTML","config","manifest","manifestFiles","req","res","url_prefix","base","basename","URL","pathname","language","i18n","web","needHtmlCache","undefined","includes","html_cache","darkMode","title","WEB_TITLE","login","scope","logoURI","logo","pkgManagers","version","flags","primaryColor","primary_color","scriptsBodyAfter","metaScripts","scriptsbodyBefore","Object","assign","bodyBefore","options","webPage","get","set","error","Error","stack","setHeader","HEADERS","TEXT_HTML","send"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AAEA;;AACA;;AAEA;;AAEA;;AACA;;;;AAEA,MAAMA,OAAO,GAAGC,OAAO,CAAC,iBAAD,CAAvB;;AACA,MAAMC,gBAAgB,GAAG,OAAzB;AACA,MAAMC,KAAK,GAAG,IAAIC,iBAAJ,CAAQ;AAAEC,EAAAA,GAAG,EAAE,GAAP;AAAYC,EAAAA,MAAM,EAAE,OAAO,EAAP,GAAY;AAAhC,CAAR,CAAd;AAEA,MAAMC,KAAK,GAAG,oBAAW,sBAAX,CAAd;AAEA,MAAMC,oBAAoB,GAAG;AAC3BC,EAAAA,EAAE,EAAE,CAAC,YAAD,EAAe,YAAf,EAA6B,SAA7B,CADuB;AAE3BC,EAAAA,GAAG,EAAE;AAFsB,CAA7B;;AAKe,SAASC,UAAT,CAAoBC,MAApB,EAA4BC,QAA5B,EAAsCC,aAAtC,EAAqDC,GAArD,EAA0DC,GAA1D,EAA+D;AAAA;;AAC5E,QAAM;AAAEC,IAAAA;AAAF,MAAiBL,MAAvB;AACA,QAAMM,IAAI,GAAG,wBAAaN,MAAb,aAAaA,MAAb,uBAAaA,MAAM,CAAEK,UAArB,EAAiCF,GAAjC,CAAb;AACA,QAAMI,QAAQ,GAAG,IAAIC,QAAJ,CAAQF,IAAR,EAAcG,QAA/B;AACA,QAAMC,QAAQ,GAAG,CAAAV,MAAM,SAAN,IAAAA,MAAM,WAAN,4BAAAA,MAAM,CAAEW,IAAR,8DAAcC,GAAd,KAAqBtB,gBAAtC;AACA,QAAMuB,aAAa,GAAG,CAACC,SAAD,EAAY,IAAZ,EAAkBC,QAAlB,CAA2Bf,MAA3B,aAA2BA,MAA3B,sCAA2BA,MAAM,CAAEY,GAAnC,gDAA2B,YAAaI,UAAxC,IAClB,IADkB,GAElBhB,MAAM,CAACY,GAAP,CAAWI,UAFf;AAGA,QAAMC,QAAQ,GAAG,CAAAjB,MAAM,SAAN,IAAAA,MAAM,WAAN,4BAAAA,MAAM,CAAEY,GAAR,8DAAaK,QAAb,KAAyB,KAA1C;AACA,QAAMC,KAAK,GAAG,CAAAlB,MAAM,SAAN,IAAAA,MAAM,WAAN,4BAAAA,MAAM,CAAEY,GAAR,8DAAaM,KAAb,KAAsBC,iBAApC;AACA,QAAMC,KAAK,GAAG,wBAASpB,MAAT,CAAd;AACA,QAAMqB,KAAK,GAAG,CAAArB,MAAM,SAAN,IAAAA,MAAM,WAAN,4BAAAA,MAAM,CAAEY,GAAR,8DAAaS,KAAb,KAAsB,EAApC;AACA,QAAMC,OAAO,GAAG,CAAAtB,MAAM,SAAN,IAAAA,MAAM,WAAN,4BAAAA,MAAM,CAAEY,GAAR,8DAAaW,IAAb,KAAqB,EAArC;AACA,QAAMC,WAAW,GAAG,CAAAxB,MAAM,SAAN,IAAAA,MAAM,WAAN,4BAAAA,MAAM,CAAEY,GAAR,8DAAaY,WAAb,KAA4B,CAAC,MAAD,EAAS,MAAT,EAAiB,KAAjB,CAAhD;AACA,QAAMC,OAAO,GAAGrC,OAAO,CAACqC,OAAxB;AACA,QAAMC,KAAK,GAAG,EACZ,GAAG1B,MAAM,CAAC0B;AADE,GAAd;AAGA,QAAMC,YAAY,GAAG,oCAAqB3B,MAArB,aAAqBA,MAArB,uCAAqBA,MAAM,CAAEY,GAA7B,iDAAqB,aAAagB,aAAlC,KAAoD,SAAzE;AACA,QAAM;
|
|
1
|
+
{"version":3,"sources":["../src/renderHTML.ts"],"names":["pkgJSON","require","DEFAULT_LANGUAGE","cache","LRU","max","maxAge","debug","defaultManifestFiles","js","ico","renderHTML","config","manifest","manifestFiles","req","res","url_prefix","base","basename","URL","pathname","language","i18n","web","needHtmlCache","undefined","includes","html_cache","darkMode","title","WEB_TITLE","login","scope","logoURI","logo","pkgManagers","version","flags","primaryColor","primary_color","scriptsBodyAfter","metaScripts","scriptsbodyBefore","showInfo","showSettings","showThemeSwitch","showFooter","showSearch","showDownloadTarball","Object","assign","bodyBefore","options","webPage","get","set","error","Error","stack","setHeader","HEADERS","TEXT_HTML","send"],"mappings":"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","sourcesContent":["import buildDebug from 'debug';\nimport LRU from 'lru-cache';\nimport { URL } from 'url';\n\nimport { WEB_TITLE } from '@verdaccio/config';\nimport { HEADERS } from '@verdaccio/core';\nimport { TemplateUIOptions } from '@verdaccio/types';\nimport { getPublicUrl } from '@verdaccio/url';\n\nimport renderTemplate from './template';\nimport { hasLogin, validatePrimaryColor } from './utils/web-utils';\n\nconst pkgJSON = require('../package.json');\nconst DEFAULT_LANGUAGE = 'es-US';\nconst cache = new LRU({ max: 500, maxAge: 1000 * 60 * 60 });\n\nconst debug = buildDebug('verdaccio:web:render');\n\nconst defaultManifestFiles = {\n js: ['runtime.js', 'vendors.js', 'main.js'],\n ico: 'favicon.ico',\n};\n\nexport default function renderHTML(config, manifest, manifestFiles, req, res) {\n const { url_prefix } = config;\n const base = getPublicUrl(config?.url_prefix, req);\n const basename = new URL(base).pathname;\n const language = config?.i18n?.web ?? DEFAULT_LANGUAGE;\n const needHtmlCache = [undefined, null].includes(config?.web?.html_cache)\n ? true\n : config.web.html_cache;\n const darkMode = config?.web?.darkMode ?? false;\n const title = config?.web?.title ?? WEB_TITLE;\n const login = hasLogin(config);\n const scope = config?.web?.scope ?? '';\n const logoURI = config?.web?.logo ?? '';\n const pkgManagers = config?.web?.pkgManagers ?? ['yarn', 'pnpm', 'npm'];\n const version = pkgJSON.version;\n const flags = {\n ...config.flags,\n };\n const primaryColor = validatePrimaryColor(config?.web?.primary_color) ?? '#4b5e40';\n const {\n scriptsBodyAfter,\n metaScripts,\n scriptsbodyBefore,\n showInfo,\n showSettings,\n showThemeSwitch,\n showFooter,\n showSearch,\n showDownloadTarball,\n } = Object.assign(\n {},\n {\n scriptsBodyAfter: [],\n bodyBefore: [],\n metaScripts: [],\n },\n config?.web\n );\n const options: TemplateUIOptions = {\n showInfo,\n showSettings,\n showThemeSwitch,\n showFooter,\n showSearch,\n showDownloadTarball,\n darkMode,\n url_prefix,\n basename,\n base,\n primaryColor,\n version,\n logoURI,\n flags,\n login,\n pkgManagers,\n title,\n scope,\n language,\n };\n\n let webPage;\n\n try {\n webPage = cache.get('template');\n if (!webPage) {\n webPage = renderTemplate(\n {\n manifest: manifestFiles ?? defaultManifestFiles,\n options,\n scriptsBodyAfter,\n metaScripts,\n scriptsbodyBefore,\n },\n manifest\n );\n if (needHtmlCache) {\n cache.set('template', webPage);\n debug('set template cache');\n }\n } else {\n debug('reuse template cache');\n }\n } catch (error: any) {\n throw new Error(`theme could not be load, stack ${error.stack}`);\n }\n res.setHeader('Content-Type', HEADERS.TEXT_HTML);\n res.send(webPage);\n debug('web rendered');\n}\n"],"file":"renderHTML.js"}
|
package/build/utils/web-utils.js
CHANGED
|
@@ -21,7 +21,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
21
21
|
const debug = (0, _debug.default)('verdaccio:web:utils');
|
|
22
22
|
|
|
23
23
|
function validatePrimaryColor(primaryColor) {
|
|
24
|
-
const isHex =
|
|
24
|
+
const isHex = /^#([0-9A-F]{3}){1,2}$/i.test(primaryColor);
|
|
25
25
|
|
|
26
26
|
if (!isHex) {
|
|
27
27
|
debug('invalid primary color %o', primaryColor);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/web-utils.ts"],"names":["debug","validatePrimaryColor","primaryColor","isHex","test","parseReadme","packageName","readme","_","isEmpty","Error","deleteProperties","propertiesToDelete","objectItem","forEach","property","addScope","scope","sortByName","packages","orderAscending","slice","sort","a","b","comparatorNames","name","toLowerCase","hasLogin","config","isNil","web","login"],"mappings":";;;;;;;;;;;;AAAA;;AACA;;AAEA;;;;AAMA,MAAMA,KAAK,GAAG,oBAAW,qBAAX,CAAd;;AAEO,SAASC,oBAAT,CAA8BC,YAA9B,EAA4C;AACjD,QAAMC,KAAK,GAAG,
|
|
1
|
+
{"version":3,"sources":["../../src/utils/web-utils.ts"],"names":["debug","validatePrimaryColor","primaryColor","isHex","test","parseReadme","packageName","readme","_","isEmpty","Error","deleteProperties","propertiesToDelete","objectItem","forEach","property","addScope","scope","sortByName","packages","orderAscending","slice","sort","a","b","comparatorNames","name","toLowerCase","hasLogin","config","isNil","web","login"],"mappings":";;;;;;;;;;;;AAAA;;AACA;;AAEA;;;;AAMA,MAAMA,KAAK,GAAG,oBAAW,qBAAX,CAAd;;AAEO,SAASC,oBAAT,CAA8BC,YAA9B,EAA4C;AACjD,QAAMC,KAAK,GAAG,yBAAyBC,IAAzB,CAA8BF,YAA9B,CAAd;;AACA,MAAI,CAACC,KAAL,EAAY;AACVH,IAAAA,KAAK,CAAC,0BAAD,EAA6BE,YAA7B,CAAL;AACA;AACD;;AAED,SAAOA,YAAP;AACD;AAED;AACA;AACA;AACA;AACA;AACA;;;AACO,SAASG,WAAT,CAAqBC,WAArB,EAA0CC,MAA1C,EAAyE;AAC9E,MAAIC,gBAAEC,OAAF,CAAUF,MAAV,MAAsB,KAA1B,EAAiC;AAC/BP,IAAAA,KAAK,CAAC,iBAAD,CAAL;AACA,WAAO,qBAAeO,MAAf,CAAP;AACD,GAJ6E,CAM9E;AACA;;;AACA,QAAM,IAAIG,KAAJ,CAAU,8BAAV,CAAN;AACD;;AAEM,SAASC,gBAAT,CAA0BC,kBAA1B,EAAwDC,UAAxD,EAA8E;AACnFb,EAAAA,KAAK,CAAC,mCAAD,CAAL;;AACAQ,kBAAEM,OAAF,CAAUF,kBAAV,EAA+BG,QAAD,IAAmB;AAC/C,WAAOF,UAAU,CAACE,QAAD,CAAjB;AACD,GAFD;;AAIA,SAAOF,UAAP;AACD;;AAEM,SAASG,QAAT,CAAkBC,KAAlB,EAAiCX,WAAjC,EAA8D;AACnE,SAAQ,IAAGW,KAAM,IAAGX,WAAY,EAAhC;AACD;;AAEM,SAASY,UAAT,CAAoBC,QAApB,EAAqCC,cAA8B,GAAG,IAAtE,EAAsF;AAC3F,SAAOD,QAAQ,CAACE,KAAT,GAAiBC,IAAjB,CAAsB,UAAUC,CAAV,EAAaC,CAAb,EAAwB;AACnD,UAAMC,eAAe,GAAGF,CAAC,CAACG,IAAF,CAAOC,WAAP,KAAuBH,CAAC,CAACE,IAAF,CAAOC,WAAP,EAA/C;AACA,WAAOP,cAAc,GAAIK,eAAe,GAAG,CAAC,CAAJ,GAAQ,CAA3B,GAAgCA,eAAe,GAAG,CAAH,GAAO,CAAC,CAA5E;AACD,GAHM,CAAP;AAID;;AAEM,SAASG,QAAT,CAAkBC,MAAlB,EAAsC;AAAA;;AAC3C,SAAOrB,gBAAEsB,KAAF,CAAQD,MAAR,aAAQA,MAAR,sCAAQA,MAAM,CAAEE,GAAhB,gDAAQ,YAAaC,KAArB,KAA+B,CAAAH,MAAM,SAAN,IAAAA,MAAM,WAAN,4BAAAA,MAAM,CAAEE,GAAR,8DAAaC,KAAb,MAAuB,IAA7D;AACD","sourcesContent":["import buildDebug from 'debug';\nimport _ from 'lodash';\n\nimport sanitizyReadme from '@verdaccio/readme';\n// import { normalizeContributors } from '@verdaccio/store';\nimport { Author, ConfigYaml } from '@verdaccio/types';\n\nexport type AuthorAvatar = Author & { avatar?: string };\n\nconst debug = buildDebug('verdaccio:web:utils');\n\nexport function validatePrimaryColor(primaryColor) {\n const isHex = /^#([0-9A-F]{3}){1,2}$/i.test(primaryColor);\n if (!isHex) {\n debug('invalid primary color %o', primaryColor);\n return;\n }\n\n return primaryColor;\n}\n\n/**\n * parse package readme - markdown/ascii\n * @param {String} packageName name of package\n * @param {String} readme package readme\n * @return {String} converted html template\n */\nexport function parseReadme(packageName: string, readme: string): string | void {\n if (_.isEmpty(readme) === false) {\n debug('sanizity readme');\n return sanitizyReadme(readme);\n }\n\n // logs readme not found error\n // logger.error({ packageName }, '@{packageName}: No readme found');\n throw new Error('ERROR: No README data found!');\n}\n\nexport function deleteProperties(propertiesToDelete: string[], objectItem: any): any {\n debug('deleted unused version properties');\n _.forEach(propertiesToDelete, (property): any => {\n delete objectItem[property];\n });\n\n return objectItem;\n}\n\nexport function addScope(scope: string, packageName: string): string {\n return `@${scope}/${packageName}`;\n}\n\nexport function sortByName(packages: any[], orderAscending: boolean | void = true): string[] {\n return packages.slice().sort(function (a, b): number {\n const comparatorNames = a.name.toLowerCase() < b.name.toLowerCase();\n return orderAscending ? (comparatorNames ? -1 : 1) : comparatorNames ? 1 : -1;\n });\n}\n\nexport function hasLogin(config: ConfigYaml) {\n return _.isNil(config?.web?.login) || config?.web?.login === true;\n}\n"],"file":"web-utils.js"}
|
package/package.json
CHANGED
|
@@ -1,70 +1,71 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
2
|
+
"name": "@verdaccio/web",
|
|
3
|
+
"version": "6.0.0-6-next.29",
|
|
4
|
+
"description": "web ui middleware",
|
|
5
|
+
"main": "./build/index.js",
|
|
6
|
+
"types": "build/index.d.ts",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "https",
|
|
9
|
+
"url": "https://github.com/verdaccio/verdaccio"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"private",
|
|
13
|
+
"package",
|
|
14
|
+
"repository",
|
|
15
|
+
"registry",
|
|
16
|
+
"enterprise",
|
|
17
|
+
"modules",
|
|
18
|
+
"proxy",
|
|
19
|
+
"server",
|
|
20
|
+
"verdaccio"
|
|
21
|
+
],
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=14",
|
|
24
|
+
"npm": ">=6"
|
|
25
|
+
},
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@verdaccio/auth": "6.0.0-6-next.22",
|
|
29
|
+
"@verdaccio/core": "6.0.0-6-next.5",
|
|
30
|
+
"@verdaccio/config": "6.0.0-6-next.14",
|
|
31
|
+
"@verdaccio/loaders": "6.0.0-6-next.12",
|
|
32
|
+
"@verdaccio/logger": "6.0.0-6-next.11",
|
|
33
|
+
"@verdaccio/middleware": "6.0.0-6-next.22",
|
|
34
|
+
"@verdaccio/readme": "11.0.0-6-next.4",
|
|
35
|
+
"@verdaccio/store": "6.0.0-6-next.22",
|
|
36
|
+
"@verdaccio/tarball": "11.0.0-6-next.12",
|
|
37
|
+
"@verdaccio/url": "11.0.0-6-next.9",
|
|
38
|
+
"@verdaccio/utils": "6.0.0-6-next.11",
|
|
39
|
+
"body-parser": "1.19.1",
|
|
40
|
+
"debug": "4.3.3",
|
|
41
|
+
"express": "4.17.2",
|
|
42
|
+
"lodash": "4.17.21",
|
|
43
|
+
"lru-cache": "6.0.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/node": "16.11.21",
|
|
47
|
+
"@verdaccio/types": "11.0.0-6-next.12",
|
|
48
|
+
"@verdaccio/test-helper": "1.1.0-6-next.1",
|
|
49
|
+
"@verdaccio/api": "6.0.0-6-next.25",
|
|
50
|
+
"node-html-parser": "4.1.5",
|
|
51
|
+
"supertest": "6.2.2",
|
|
52
|
+
"nock": "13.2.2",
|
|
53
|
+
"jsdom": "20.0.0",
|
|
54
|
+
"undici": "4.15.0",
|
|
55
|
+
"verdaccio-auth-memory": "11.0.0-6-next.8",
|
|
56
|
+
"verdaccio-memory": "11.0.0-6-next.10"
|
|
57
|
+
},
|
|
58
|
+
"funding": {
|
|
59
|
+
"type": "opencollective",
|
|
60
|
+
"url": "https://opencollective.com/verdaccio"
|
|
61
|
+
},
|
|
62
|
+
"scripts": {
|
|
63
|
+
"clean": "rimraf ./build",
|
|
64
|
+
"test": "jest",
|
|
65
|
+
"type-check": "tsc --noEmit -p tsconfig.build.json",
|
|
66
|
+
"build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json",
|
|
67
|
+
"build:js": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps",
|
|
68
|
+
"watch": "pnpm build:js -- --watch",
|
|
69
|
+
"build": "pnpm run build:js && pnpm run build:types"
|
|
70
|
+
}
|
|
71
|
+
}
|
package/src/renderHTML.ts
CHANGED
|
@@ -40,7 +40,17 @@ export default function renderHTML(config, manifest, manifestFiles, req, res) {
|
|
|
40
40
|
...config.flags,
|
|
41
41
|
};
|
|
42
42
|
const primaryColor = validatePrimaryColor(config?.web?.primary_color) ?? '#4b5e40';
|
|
43
|
-
const {
|
|
43
|
+
const {
|
|
44
|
+
scriptsBodyAfter,
|
|
45
|
+
metaScripts,
|
|
46
|
+
scriptsbodyBefore,
|
|
47
|
+
showInfo,
|
|
48
|
+
showSettings,
|
|
49
|
+
showThemeSwitch,
|
|
50
|
+
showFooter,
|
|
51
|
+
showSearch,
|
|
52
|
+
showDownloadTarball,
|
|
53
|
+
} = Object.assign(
|
|
44
54
|
{},
|
|
45
55
|
{
|
|
46
56
|
scriptsBodyAfter: [],
|
|
@@ -50,6 +60,12 @@ export default function renderHTML(config, manifest, manifestFiles, req, res) {
|
|
|
50
60
|
config?.web
|
|
51
61
|
);
|
|
52
62
|
const options: TemplateUIOptions = {
|
|
63
|
+
showInfo,
|
|
64
|
+
showSettings,
|
|
65
|
+
showThemeSwitch,
|
|
66
|
+
showFooter,
|
|
67
|
+
showSearch,
|
|
68
|
+
showDownloadTarball,
|
|
53
69
|
darkMode,
|
|
54
70
|
url_prefix,
|
|
55
71
|
basename,
|
|
@@ -69,10 +85,7 @@ export default function renderHTML(config, manifest, manifestFiles, req, res) {
|
|
|
69
85
|
|
|
70
86
|
try {
|
|
71
87
|
webPage = cache.get('template');
|
|
72
|
-
|
|
73
88
|
if (!webPage) {
|
|
74
|
-
debug('web options %o', options);
|
|
75
|
-
debug('web manifestFiles %o', manifestFiles);
|
|
76
89
|
webPage = renderTemplate(
|
|
77
90
|
{
|
|
78
91
|
manifest: manifestFiles ?? defaultManifestFiles,
|
|
@@ -83,7 +96,6 @@ export default function renderHTML(config, manifest, manifestFiles, req, res) {
|
|
|
83
96
|
},
|
|
84
97
|
manifest
|
|
85
98
|
);
|
|
86
|
-
debug('template :: %o', webPage);
|
|
87
99
|
if (needHtmlCache) {
|
|
88
100
|
cache.set('template', webPage);
|
|
89
101
|
debug('set template cache');
|
|
@@ -96,5 +108,5 @@ export default function renderHTML(config, manifest, manifestFiles, req, res) {
|
|
|
96
108
|
}
|
|
97
109
|
res.setHeader('Content-Type', HEADERS.TEXT_HTML);
|
|
98
110
|
res.send(webPage);
|
|
99
|
-
debug('
|
|
111
|
+
debug('web rendered');
|
|
100
112
|
}
|
package/src/utils/web-utils.ts
CHANGED
|
@@ -10,7 +10,7 @@ export type AuthorAvatar = Author & { avatar?: string };
|
|
|
10
10
|
const debug = buildDebug('verdaccio:web:utils');
|
|
11
11
|
|
|
12
12
|
export function validatePrimaryColor(primaryColor) {
|
|
13
|
-
const isHex =
|
|
13
|
+
const isHex = /^#([0-9A-F]{3}){1,2}$/i.test(primaryColor);
|
|
14
14
|
if (!isHex) {
|
|
15
15
|
debug('invalid primary color %o', primaryColor);
|
|
16
16
|
return;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
auth:
|
|
2
|
+
auth-memory:
|
|
3
|
+
users:
|
|
4
|
+
test:
|
|
5
|
+
name: test
|
|
6
|
+
password: test
|
|
7
|
+
|
|
8
|
+
web:
|
|
9
|
+
title: verdaccio web
|
|
10
|
+
login: true
|
|
11
|
+
scope: '@scope'
|
|
12
|
+
pkgManagers:
|
|
13
|
+
- pnpm
|
|
14
|
+
- yarn
|
|
15
|
+
showInfo: true
|
|
16
|
+
showSettings: true
|
|
17
|
+
showSearch: true
|
|
18
|
+
showFooter: true
|
|
19
|
+
showThemeSwitch: true
|
|
20
|
+
showDownloadTarball: true
|
|
21
|
+
showRaw: true
|
|
22
|
+
primary_color: '#ffffff'
|
|
23
|
+
logoURI: 'http://logo.org/logo.png'
|
|
24
|
+
flags:
|
|
25
|
+
- something: false
|
|
26
|
+
|
|
27
|
+
url_prefix: /prefix
|
|
28
|
+
|
|
29
|
+
publish:
|
|
30
|
+
allow_offline: false
|
|
31
|
+
|
|
32
|
+
uplinks:
|
|
33
|
+
|
|
34
|
+
log: { type: stdout, format: pretty, level: trace }
|
|
35
|
+
|
|
36
|
+
packages:
|
|
37
|
+
'@*/*':
|
|
38
|
+
access: $anonymous
|
|
39
|
+
publish: $anonymous
|
|
40
|
+
'**':
|
|
41
|
+
access: $anonymous
|
|
42
|
+
publish: $anonymous
|
|
43
|
+
_debug: true
|
|
44
|
+
|
|
45
|
+
flags:
|
|
46
|
+
changePassword: true
|
package/test/render.test.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { JSDOM } from 'jsdom';
|
|
1
2
|
import path from 'path';
|
|
2
3
|
import supertest from 'supertest';
|
|
3
4
|
|
|
@@ -28,34 +29,80 @@ describe('test web server', () => {
|
|
|
28
29
|
});
|
|
29
30
|
|
|
30
31
|
describe('render', () => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
describe('output', () => {
|
|
33
|
+
const render = async (config = 'default-test.yaml') => {
|
|
34
|
+
const response = await supertest(await initializeServer(config))
|
|
35
|
+
.get('/')
|
|
36
|
+
.set('Accept', HEADERS.TEXT_HTML)
|
|
37
|
+
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.TEXT_HTML_UTF8)
|
|
38
|
+
.expect(HTTP_STATUS.OK);
|
|
39
|
+
return new JSDOM(response.text, { runScripts: 'dangerously' });
|
|
40
|
+
};
|
|
38
41
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
test('should match render set ui properties', async () => {
|
|
43
|
+
const {
|
|
44
|
+
window: { __VERDACCIO_BASENAME_UI_OPTIONS },
|
|
45
|
+
} = await render('web.yaml');
|
|
46
|
+
expect(__VERDACCIO_BASENAME_UI_OPTIONS).toEqual(
|
|
47
|
+
expect.objectContaining({
|
|
48
|
+
showInfo: true,
|
|
49
|
+
showSettings: true,
|
|
50
|
+
showThemeSwitch: true,
|
|
51
|
+
showFooter: true,
|
|
52
|
+
showSearch: true,
|
|
53
|
+
showDownloadTarball: true,
|
|
54
|
+
darkMode: false,
|
|
55
|
+
url_prefix: '/prefix',
|
|
56
|
+
basename: '/prefix/',
|
|
57
|
+
primaryColor: '#ffffff',
|
|
58
|
+
// FIXME: mock these values, avoid random
|
|
59
|
+
// base: 'http://127.0.0.1:60864/prefix/',
|
|
60
|
+
// version: '6.0.0-6-next.28',
|
|
61
|
+
logoURI: '',
|
|
62
|
+
flags: { searchRemote: true },
|
|
63
|
+
login: true,
|
|
64
|
+
pkgManagers: ['pnpm', 'yarn'],
|
|
65
|
+
title: 'verdaccio web',
|
|
66
|
+
scope: '@scope',
|
|
67
|
+
language: 'es-US',
|
|
68
|
+
})
|
|
69
|
+
);
|
|
70
|
+
});
|
|
46
71
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
.get('/-/static/not-found.js')
|
|
50
|
-
.set('Accept', HEADERS.TEXT_HTML)
|
|
51
|
-
.expect(HTTP_STATUS.NOT_FOUND);
|
|
72
|
+
test.todo('test default title');
|
|
73
|
+
test.todo('test need html cache');
|
|
52
74
|
});
|
|
53
75
|
|
|
54
|
-
|
|
55
|
-
return
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
76
|
+
describe('status', () => {
|
|
77
|
+
test('should return the http status 200 for root', async () => {
|
|
78
|
+
return supertest(await initializeServer('default-test.yaml'))
|
|
79
|
+
.get('/')
|
|
80
|
+
.set('Accept', HEADERS.TEXT_HTML)
|
|
81
|
+
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.TEXT_HTML_UTF8)
|
|
82
|
+
.expect(HTTP_STATUS.OK);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test('should return the body for a package detail page', async () => {
|
|
86
|
+
return supertest(await initializeServer('default-test.yaml'))
|
|
87
|
+
.get('/-/web/section/some-package')
|
|
88
|
+
.set('Accept', HEADERS.TEXT_HTML)
|
|
89
|
+
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.TEXT_HTML_UTF8)
|
|
90
|
+
.expect(HTTP_STATUS.OK);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test('should static file not found', async () => {
|
|
94
|
+
return supertest(await initializeServer('default-test.yaml'))
|
|
95
|
+
.get('/-/static/not-found.js')
|
|
96
|
+
.set('Accept', HEADERS.TEXT_HTML)
|
|
97
|
+
.expect(HTTP_STATUS.NOT_FOUND);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('should static file found', async () => {
|
|
101
|
+
return supertest(await initializeServer('default-test.yaml'))
|
|
102
|
+
.get('/-/static/main.js')
|
|
103
|
+
.set('Accept', HEADERS.TEXT_HTML)
|
|
104
|
+
.expect(HTTP_STATUS.OK);
|
|
105
|
+
});
|
|
59
106
|
});
|
|
60
107
|
});
|
|
61
108
|
});
|
package/test/utils.spec.ts
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
|
|
4
|
-
import { parseReadme } from '../src/utils/web-utils';
|
|
4
|
+
import { parseReadme, validatePrimaryColor } from '../src/utils/web-utils';
|
|
5
5
|
|
|
6
6
|
const readmeFile = (fileName = 'markdown.md') => {
|
|
7
7
|
return fs.readFileSync(path.join(__dirname, `./partials/readme/${fileName}`));
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
describe('Utilities', () => {
|
|
11
|
+
describe('validatePrimaryColor', () => {
|
|
12
|
+
test('is valid', () => {
|
|
13
|
+
expect(validatePrimaryColor('#222222')).toEqual('#222222');
|
|
14
|
+
expect(validatePrimaryColor('#222fff')).toEqual('#222fff');
|
|
15
|
+
});
|
|
16
|
+
test('is invalid', () => {
|
|
17
|
+
expect(validatePrimaryColor('fff')).toBeUndefined();
|
|
18
|
+
});
|
|
19
|
+
});
|
|
11
20
|
describe('parseReadme', () => {
|
|
12
21
|
test('should parse makrdown text to html template', () => {
|
|
13
22
|
const markdown = '# markdown';
|