@verdaccio/middleware 8.0.0-next-8.36 → 8.0.0-next-8.37

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.
@@ -12,6 +12,7 @@ var _core = require("@verdaccio/core");
12
12
  var _url = require("@verdaccio/url");
13
13
  var _security = require("./security");
14
14
  var _renderHTML = _interopRequireDefault(require("./utils/renderHTML"));
15
+ var _uiOptions = require("./utils/ui-options");
15
16
  var _webUrls = require("./web-urls");
16
17
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
17
18
  const debug = (0, _debug.default)('verdaccio:web:render');
@@ -93,13 +94,24 @@ function renderWebMiddleware(config, tokenMiddleware, pluginOptions) {
93
94
  config.web.logoDark = logoDark;
94
95
  }
95
96
 
97
+ // Serve external script that loads UI options
98
+ router.get(_webUrls.WebUrlsNamespace.static + 'ui-options.js', function (req, res) {
99
+ const options = (0, _uiOptions.getUIOptions)(config, req, res);
100
+ const script = `window.__VERDACCIO_BASENAME_UI_OPTIONS=${JSON.stringify(options)};`;
101
+ res.setHeader(_core.HEADERS.CACHE_CONTROL, _core.HEADERS.NO_CACHE);
102
+ res.setHeader(_core.HEADERS.CONTENT_TYPE, _core.HEADERS.JAVASCRIPT_CHARSET);
103
+ res.send(script);
104
+ });
105
+
96
106
  // Handle all web routes including security routes
97
107
  router.get(_webUrls.WebUrlsNamespace.web + '*', function (req, res) {
98
- (0, _renderHTML.default)(config, manifest, manifestFiles, req, res);
108
+ const options = (0, _uiOptions.getUIOptions)(config, req, res);
109
+ (0, _renderHTML.default)(config, manifest, manifestFiles, options, res);
99
110
  debug('render html section');
100
111
  });
101
112
  router.get(_webUrls.WebUrlsNamespace.root, function (req, res) {
102
- (0, _renderHTML.default)(config, manifest, manifestFiles, req, res);
113
+ const options = (0, _uiOptions.getUIOptions)(config, req, res);
114
+ (0, _renderHTML.default)(config, manifest, manifestFiles, options, res);
103
115
  debug('render root');
104
116
  });
105
117
  return router;
@@ -1 +1 @@
1
- {"version":3,"file":"render-web.js","names":["_debug","_interopRequireDefault","require","_express","_nodeFs","_nodePath","_core","_url","_security","_renderHTML","_webUrls","e","__esModule","default","debug","buildDebug","sendFileCallback","next","err","status","HTTP_STATUS","NOT_FOUND","renderWebMiddleware","config","tokenMiddleware","pluginOptions","staticPath","manifest","manifestFiles","router","express","Router","use","setSecurityWebHeaders","get","WebUrlsNamespace","static","req","res","filename","params","file","web","favicon","isURLhasValidProtocol","url","sendFile","renderLogo","logo","absoluteLocalFile","path","posix","resolve","fs","existsSync","accessSync","constants","R_OK","join","basename","_req","undefined","logoDark","renderHTML","root"],"sources":["../../../src/middlewares/web/render-web.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport express from 'express';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport { HTTP_STATUS } from '@verdaccio/core';\nimport { isURLhasValidProtocol } from '@verdaccio/url';\n\nimport { setSecurityWebHeaders } from './security';\nimport renderHTML from './utils/renderHTML';\nimport { WebUrlsNamespace } from './web-urls';\n\nconst debug = buildDebug('verdaccio:web:render');\n\nconst sendFileCallback = (next) => (err) => {\n if (!err) {\n return;\n }\n if (err.status === HTTP_STATUS.NOT_FOUND) {\n next();\n } else {\n next(err);\n }\n};\n\nexport function renderWebMiddleware(config, tokenMiddleware, pluginOptions) {\n const { staticPath, manifest, manifestFiles } = pluginOptions;\n debug('static path %o', staticPath);\n\n /* eslint new-cap:off */\n const router = express.Router();\n if (typeof tokenMiddleware === 'function') {\n router.use(tokenMiddleware);\n }\n\n router.use(setSecurityWebHeaders);\n\n // any match within the static is routed to the file system\n router.get(WebUrlsNamespace.static + '*', function (req, res, next) {\n const filename = req.params[0];\n let file = `${staticPath}/${filename}`;\n if (filename === 'favicon.ico' && config?.web?.favicon) {\n file = config?.web?.favicon;\n if (isURLhasValidProtocol(file)) {\n debug('redirect to favicon %s', file);\n req.url = file;\n return next();\n }\n }\n debug('render static file %o', file);\n res.sendFile(file, sendFileCallback(next));\n });\n\n function renderLogo(logo: string | undefined): string | undefined {\n // check the origin of the logo\n if (logo && !isURLhasValidProtocol(logo)) {\n // URI related to a local file\n const absoluteLocalFile = path.posix.resolve(logo);\n debug('serve local logo %s', absoluteLocalFile);\n try {\n // TODO: replace existsSync by async alternative\n if (\n fs.existsSync(absoluteLocalFile) &&\n typeof fs.accessSync(absoluteLocalFile, fs.constants.R_OK) === 'undefined'\n ) {\n // Note: `path.join` will break on Windows, because it transforms `/` to `\\`\n // Use POSIX version `path.posix.join` instead.\n logo = path.posix.join(WebUrlsNamespace.static, path.basename(logo));\n router.get(logo, function (_req, res, next) {\n // @ts-ignore\n debug('serve custom logo web:%s - local:%s', logo, absoluteLocalFile);\n res.sendFile(absoluteLocalFile, sendFileCallback(next));\n });\n debug('enabled custom logo %s', logo);\n } else {\n logo = undefined;\n debug(`web logo is wrong, path ${absoluteLocalFile} does not exist or is not readable`);\n }\n } catch {\n logo = undefined;\n debug(`web logo is wrong, path ${absoluteLocalFile} does not exist or is not readable`);\n }\n }\n return logo;\n }\n\n const logo = renderLogo(config?.web?.logo);\n if (config?.web?.logo) {\n config.web.logo = logo;\n }\n const logoDark = renderLogo(config?.web?.logoDark);\n if (config?.web?.logoDark) {\n config.web.logoDark = logoDark;\n }\n\n // Handle all web routes including security routes\n router.get(WebUrlsNamespace.web + '*', function (req, res) {\n renderHTML(config, manifest, manifestFiles, req, res);\n debug('render html section');\n });\n\n router.get(WebUrlsNamespace.root, function (req, res) {\n renderHTML(config, manifest, manifestFiles, req, res);\n debug('render root');\n });\n\n return router;\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"render-web.js","names":["_debug","_interopRequireDefault","require","_express","_nodeFs","_nodePath","_core","_url","_security","_renderHTML","_uiOptions","_webUrls","e","__esModule","default","debug","buildDebug","sendFileCallback","next","err","status","HTTP_STATUS","NOT_FOUND","renderWebMiddleware","config","tokenMiddleware","pluginOptions","staticPath","manifest","manifestFiles","router","express","Router","use","setSecurityWebHeaders","get","WebUrlsNamespace","static","req","res","filename","params","file","web","favicon","isURLhasValidProtocol","url","sendFile","renderLogo","logo","absoluteLocalFile","path","posix","resolve","fs","existsSync","accessSync","constants","R_OK","join","basename","_req","undefined","logoDark","options","getUIOptions","script","JSON","stringify","setHeader","HEADERS","CACHE_CONTROL","NO_CACHE","CONTENT_TYPE","JAVASCRIPT_CHARSET","send","renderHTML","root"],"sources":["../../../src/middlewares/web/render-web.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport express from 'express';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport { HEADERS, HTTP_STATUS } from '@verdaccio/core';\nimport { isURLhasValidProtocol } from '@verdaccio/url';\n\nimport { setSecurityWebHeaders } from './security';\nimport renderHTML from './utils/renderHTML';\nimport { getUIOptions } from './utils/ui-options';\nimport { WebUrlsNamespace } from './web-urls';\n\nconst debug = buildDebug('verdaccio:web:render');\n\nconst sendFileCallback = (next) => (err) => {\n if (!err) {\n return;\n }\n if (err.status === HTTP_STATUS.NOT_FOUND) {\n next();\n } else {\n next(err);\n }\n};\n\nexport function renderWebMiddleware(config, tokenMiddleware, pluginOptions) {\n const { staticPath, manifest, manifestFiles } = pluginOptions;\n debug('static path %o', staticPath);\n\n /* eslint new-cap:off */\n const router = express.Router();\n if (typeof tokenMiddleware === 'function') {\n router.use(tokenMiddleware);\n }\n\n router.use(setSecurityWebHeaders);\n\n // any match within the static is routed to the file system\n router.get(WebUrlsNamespace.static + '*', function (req, res, next) {\n const filename = req.params[0];\n let file = `${staticPath}/${filename}`;\n if (filename === 'favicon.ico' && config?.web?.favicon) {\n file = config?.web?.favicon;\n if (isURLhasValidProtocol(file)) {\n debug('redirect to favicon %s', file);\n req.url = file;\n return next();\n }\n }\n debug('render static file %o', file);\n res.sendFile(file, sendFileCallback(next));\n });\n\n function renderLogo(logo: string | undefined): string | undefined {\n // check the origin of the logo\n if (logo && !isURLhasValidProtocol(logo)) {\n // URI related to a local file\n const absoluteLocalFile = path.posix.resolve(logo);\n debug('serve local logo %s', absoluteLocalFile);\n try {\n // TODO: replace existsSync by async alternative\n if (\n fs.existsSync(absoluteLocalFile) &&\n typeof fs.accessSync(absoluteLocalFile, fs.constants.R_OK) === 'undefined'\n ) {\n // Note: `path.join` will break on Windows, because it transforms `/` to `\\`\n // Use POSIX version `path.posix.join` instead.\n logo = path.posix.join(WebUrlsNamespace.static, path.basename(logo));\n router.get(logo, function (_req, res, next) {\n // @ts-ignore\n debug('serve custom logo web:%s - local:%s', logo, absoluteLocalFile);\n res.sendFile(absoluteLocalFile, sendFileCallback(next));\n });\n debug('enabled custom logo %s', logo);\n } else {\n logo = undefined;\n debug(`web logo is wrong, path ${absoluteLocalFile} does not exist or is not readable`);\n }\n } catch {\n logo = undefined;\n debug(`web logo is wrong, path ${absoluteLocalFile} does not exist or is not readable`);\n }\n }\n return logo;\n }\n\n const logo = renderLogo(config?.web?.logo);\n if (config?.web?.logo) {\n config.web.logo = logo;\n }\n const logoDark = renderLogo(config?.web?.logoDark);\n if (config?.web?.logoDark) {\n config.web.logoDark = logoDark;\n }\n\n // Serve external script that loads UI options\n router.get(WebUrlsNamespace.static + 'ui-options.js', function (req, res) {\n const options = getUIOptions(config, req, res);\n const script = `window.__VERDACCIO_BASENAME_UI_OPTIONS=${JSON.stringify(options)};`;\n res.setHeader(HEADERS.CACHE_CONTROL, HEADERS.NO_CACHE);\n res.setHeader(HEADERS.CONTENT_TYPE, HEADERS.JAVASCRIPT_CHARSET);\n res.send(script);\n });\n\n // Handle all web routes including security routes\n router.get(WebUrlsNamespace.web + '*', function (req, res) {\n const options = getUIOptions(config, req, res);\n renderHTML(config, manifest, manifestFiles, options, res);\n debug('render html section');\n });\n\n router.get(WebUrlsNamespace.root, function (req, res) {\n const options = getUIOptions(config, req, res);\n renderHTML(config, manifest, manifestFiles, options, res);\n debug('render root');\n });\n\n return router;\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,7 +1,5 @@
1
1
  import type { Response } from 'express';
2
- import type { ConfigYaml } from '@verdaccio/types';
3
- import type { RequestOptions } from '@verdaccio/url';
2
+ import type { ConfigYaml, TemplateUIOptions } from '@verdaccio/types';
4
3
  import type { Manifest } from './manifest';
5
4
  import type { AssetManifest } from './template';
6
- export declare function resolveLogo(logo: string | undefined, url_prefix: string | undefined, requestOptions: RequestOptions): string;
7
- export default function renderHTML(config: ConfigYaml, manifest: AssetManifest, manifestFiles: Manifest | null | undefined, requestOptions: RequestOptions, res: Response): void;
5
+ export default function renderHTML(config: ConfigYaml, manifest: AssetManifest, manifestFiles: Manifest | null | undefined, options: TemplateUIOptions, res: Response): void;
@@ -4,18 +4,12 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = renderHTML;
7
- exports.resolveLogo = resolveLogo;
8
7
  var _debug = _interopRequireDefault(require("debug"));
9
8
  var _lruCache = _interopRequireDefault(require("lru-cache"));
10
- var _nodePath = _interopRequireDefault(require("node:path"));
11
- var _nodeUrl = require("node:url");
12
- var _config = require("@verdaccio/config");
13
9
  var _core = require("@verdaccio/core");
14
- var _url = require("@verdaccio/url");
15
10
  var _template = _interopRequireDefault(require("./template"));
16
- var _webUtils = require("./web-utils");
17
11
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
18
- const DEFAULT_LANGUAGE = 'es-US';
12
+ // Cache for rendered HTML templates: max 500 entries, 1 hour TTL
19
13
  const cache = new _lruCache.default({
20
14
  max: 500,
21
15
  ttl: 1000 * 60 * 60
@@ -26,93 +20,12 @@ const defaultManifestFiles = {
26
20
  ico: 'favicon.ico',
27
21
  css: []
28
22
  };
29
- function resolveLogo(logo, url_prefix, requestOptions) {
30
- if (typeof logo !== 'string') {
31
- return '';
32
- }
33
- const isLocalFile = logo && !(0, _url.isURLhasValidProtocol)(logo);
34
- if (isLocalFile) {
35
- return `${(0, _url.getPublicUrl)(url_prefix, requestOptions)}-/static/${_nodePath.default.basename(logo)}`;
36
- } else if ((0, _url.isURLhasValidProtocol)(logo)) {
37
- return logo;
38
- } else {
39
- return '';
40
- }
41
- }
42
- function renderHTML(config, manifest, manifestFiles, requestOptions, res) {
43
- const {
44
- url_prefix
45
- } = config;
46
- const base = (0, _url.getPublicUrl)(config?.url_prefix, requestOptions);
47
- const basename = _nodeUrl.URL.canParse(base) ? new _nodeUrl.URL(base).pathname : base;
48
- const language = config?.i18n?.web ?? DEFAULT_LANGUAGE;
49
- const hideDeprecatedVersions = config?.web?.hideDeprecatedVersions ?? false;
23
+ function renderHTML(config, manifest, manifestFiles, options, res) {
50
24
  // @ts-ignore
51
25
  const needHtmlCache = [undefined, null].includes(config?.web?.html_cache) ? true : config?.web?.html_cache;
52
- const darkMode = config?.web?.darkMode ?? false;
53
- const title = config?.web?.title ?? _config.WEB_TITLE;
54
- const login = (0, _webUtils.hasLogin)(config);
55
- const scope = config?.web?.scope ?? '';
56
- const favicon = resolveLogo(config?.web?.favicon, config?.url_prefix, requestOptions);
57
- const logo = resolveLogo(config?.web?.logo, config?.url_prefix, requestOptions);
58
- const logoDark = resolveLogo(config?.web?.logoDark, config?.url_prefix, requestOptions);
59
- const pkgManagers = config?.web?.pkgManagers ?? ['yarn', 'pnpm', 'npm'];
60
- const version = res.locals.app_version ?? '';
61
- const flags = {
62
- ...config.flags,
63
- // legacy from 5.x
64
- ...config.experiments
65
- };
66
- const primaryColor = (0, _webUtils.validatePrimaryColor)(config?.web?.primary_color ?? config?.web?.primaryColor) ?? '#4b5e40';
67
- const {
68
- scriptsBodyAfter,
69
- metaScripts,
70
- scriptsbodyBefore,
71
- // deprecated
72
- showInfo,
73
- showSettings,
74
- showThemeSwitch,
75
- showFooter,
76
- showSearch,
77
- showDownloadTarball,
78
- showRaw,
79
- showUplinks
80
- } = Object.assign({}, {
81
- scriptsBodyAfter: [],
82
- bodyBefore: [],
83
- metaScripts: []
84
- }, config?.web);
85
- // Fallback
86
- let scriptsBodyBefore = config?.web?.scriptsBodyBefore;
87
- if (scriptsbodyBefore && !scriptsBodyBefore) {
88
- scriptsBodyBefore = scriptsbodyBefore;
89
- }
90
- const options = {
91
- showInfo,
92
- showSettings,
93
- showThemeSwitch,
94
- showFooter,
95
- showSearch,
96
- showDownloadTarball,
97
- showRaw,
98
- showUplinks,
99
- darkMode,
100
- url_prefix,
101
- basename,
102
- base,
103
- primaryColor,
104
- version,
105
- logo,
106
- logoDark,
107
- favicon,
108
- flags,
109
- login,
110
- pkgManagers,
111
- title,
112
- scope,
113
- language,
114
- hideDeprecatedVersions
115
- };
26
+ const scriptsBodyBefore = config?.web?.scriptsBodyBefore || config?.web?.scriptsbodyBefore || [];
27
+ const scriptsBodyAfter = config?.web?.scriptsBodyAfter || [];
28
+ const metaScripts = config?.web?.metaScripts || [];
116
29
  let webPage;
117
30
  const cacheKey = `template:${JSON.stringify(options)}`;
118
31
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"renderHTML.js","names":["_debug","_interopRequireDefault","require","_lruCache","_nodePath","_nodeUrl","_config","_core","_url","_template","_webUtils","e","__esModule","default","DEFAULT_LANGUAGE","cache","LRU","max","ttl","debug","buildDebug","defaultManifestFiles","js","ico","css","resolveLogo","logo","url_prefix","requestOptions","isLocalFile","isURLhasValidProtocol","getPublicUrl","path","basename","renderHTML","config","manifest","manifestFiles","res","base","URL","canParse","pathname","language","i18n","web","hideDeprecatedVersions","needHtmlCache","undefined","includes","html_cache","darkMode","title","WEB_TITLE","login","hasLogin","scope","favicon","logoDark","pkgManagers","version","locals","app_version","flags","experiments","primaryColor","validatePrimaryColor","primary_color","scriptsBodyAfter","metaScripts","scriptsbodyBefore","showInfo","showSettings","showThemeSwitch","showFooter","showSearch","showDownloadTarball","showRaw","showUplinks","Object","assign","bodyBefore","scriptsBodyBefore","options","webPage","cacheKey","JSON","stringify","get","renderTemplate","set","error","Error","stack","setHeader","HEADERS","TEXT_HTML","send"],"sources":["../../../../src/middlewares/web/utils/renderHTML.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport type { Response } from 'express';\nimport LRU from 'lru-cache';\nimport path from 'node:path';\nimport { URL } from 'node:url';\n\nimport { WEB_TITLE } from '@verdaccio/config';\nimport { HEADERS } from '@verdaccio/core';\nimport type { ConfigYaml, TemplateUIOptions } from '@verdaccio/types';\nimport type { RequestOptions } from '@verdaccio/url';\nimport { getPublicUrl, isURLhasValidProtocol } from '@verdaccio/url';\n\nimport type { Manifest } from './manifest';\nimport renderTemplate from './template';\nimport type { AssetManifest } from './template';\nimport { hasLogin, validatePrimaryColor } from './web-utils';\n\nconst DEFAULT_LANGUAGE = 'es-US';\nconst cache = new LRU({ max: 500, ttl: 1000 * 60 * 60 });\n\nconst debug = buildDebug('verdaccio:web:render');\n\nconst defaultManifestFiles: Manifest = {\n js: ['vendors.js', 'main.js'],\n ico: 'favicon.ico',\n css: [],\n};\n\nexport function resolveLogo(\n logo: string | undefined,\n url_prefix: string | undefined,\n requestOptions: RequestOptions\n) {\n if (typeof logo !== 'string') {\n return '';\n }\n const isLocalFile = logo && !isURLhasValidProtocol(logo);\n\n if (isLocalFile) {\n return `${getPublicUrl(url_prefix, requestOptions)}-/static/${path.basename(logo)}`;\n } else if (isURLhasValidProtocol(logo)) {\n return logo;\n } else {\n return '';\n }\n}\n\nexport default function renderHTML(\n config: ConfigYaml,\n manifest: AssetManifest,\n manifestFiles: Manifest | null | undefined,\n requestOptions: RequestOptions,\n res: Response\n) {\n const { url_prefix } = config;\n const base = getPublicUrl(config?.url_prefix, requestOptions);\n const basename = URL.canParse(base) ? new URL(base).pathname : base;\n const language = config?.i18n?.web ?? DEFAULT_LANGUAGE;\n const hideDeprecatedVersions = config?.web?.hideDeprecatedVersions ?? false;\n // @ts-ignore\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 favicon = resolveLogo(config?.web?.favicon, config?.url_prefix, requestOptions);\n const logo = resolveLogo(config?.web?.logo, config?.url_prefix, requestOptions);\n const logoDark = resolveLogo(config?.web?.logoDark, config?.url_prefix, requestOptions);\n const pkgManagers = config?.web?.pkgManagers ?? ['yarn', 'pnpm', 'npm'];\n const version = res.locals.app_version ?? '';\n const flags = {\n ...config.flags,\n // legacy from 5.x\n ...config.experiments,\n };\n const primaryColor =\n validatePrimaryColor(config?.web?.primary_color ?? config?.web?.primaryColor) ?? '#4b5e40';\n const {\n scriptsBodyAfter,\n metaScripts,\n scriptsbodyBefore, // deprecated\n showInfo,\n showSettings,\n showThemeSwitch,\n showFooter,\n showSearch,\n showDownloadTarball,\n showRaw,\n showUplinks,\n } = Object.assign(\n {},\n {\n scriptsBodyAfter: [],\n bodyBefore: [],\n metaScripts: [],\n },\n config?.web\n );\n // Fallback\n let scriptsBodyBefore = config?.web?.scriptsBodyBefore;\n if (scriptsbodyBefore && !scriptsBodyBefore) {\n scriptsBodyBefore = scriptsbodyBefore;\n }\n const options: TemplateUIOptions = {\n showInfo,\n showSettings,\n showThemeSwitch,\n showFooter,\n showSearch,\n showDownloadTarball,\n showRaw,\n showUplinks,\n darkMode,\n url_prefix,\n basename,\n base,\n primaryColor,\n version,\n logo,\n logoDark,\n favicon,\n flags,\n login,\n pkgManagers,\n title,\n scope,\n language,\n hideDeprecatedVersions,\n };\n\n let webPage;\n\n const cacheKey = `template:${JSON.stringify(options)}`;\n\n try {\n webPage = cache.get(cacheKey);\n if (!webPage) {\n webPage = renderTemplate(\n {\n manifest: manifestFiles ?? defaultManifestFiles,\n options,\n scriptsBodyAfter,\n metaScripts,\n scriptsBodyBefore,\n },\n manifest\n );\n\n if (needHtmlCache) {\n cache.set(cacheKey, 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"],"mappings":";;;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AAEA,IAAAC,SAAA,GAAAF,sBAAA,CAAAC,OAAA;AACA,IAAAE,SAAA,GAAAH,sBAAA,CAAAC,OAAA;AACA,IAAAG,QAAA,GAAAH,OAAA;AAEA,IAAAI,OAAA,GAAAJ,OAAA;AACA,IAAAK,KAAA,GAAAL,OAAA;AAGA,IAAAM,IAAA,GAAAN,OAAA;AAGA,IAAAO,SAAA,GAAAR,sBAAA,CAAAC,OAAA;AAEA,IAAAQ,SAAA,GAAAR,OAAA;AAA6D,SAAAD,uBAAAU,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAE7D,MAAMG,gBAAgB,GAAG,OAAO;AAChC,MAAMC,KAAK,GAAG,IAAIC,iBAAG,CAAC;EAAEC,GAAG,EAAE,GAAG;EAAEC,GAAG,EAAE,IAAI,GAAG,EAAE,GAAG;AAAG,CAAC,CAAC;AAExD,MAAMC,KAAK,GAAG,IAAAC,cAAU,EAAC,sBAAsB,CAAC;AAEhD,MAAMC,oBAA8B,GAAG;EACrCC,EAAE,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC;EAC7BC,GAAG,EAAE,aAAa;EAClBC,GAAG,EAAE;AACP,CAAC;AAEM,SAASC,WAAWA,CACzBC,IAAwB,EACxBC,UAA8B,EAC9BC,cAA8B,EAC9B;EACA,IAAI,OAAOF,IAAI,KAAK,QAAQ,EAAE;IAC5B,OAAO,EAAE;EACX;EACA,MAAMG,WAAW,GAAGH,IAAI,IAAI,CAAC,IAAAI,0BAAqB,EAACJ,IAAI,CAAC;EAExD,IAAIG,WAAW,EAAE;IACf,OAAO,GAAG,IAAAE,iBAAY,EAACJ,UAAU,EAAEC,cAAc,CAAC,YAAYI,iBAAI,CAACC,QAAQ,CAACP,IAAI,CAAC,EAAE;EACrF,CAAC,MAAM,IAAI,IAAAI,0BAAqB,EAACJ,IAAI,CAAC,EAAE;IACtC,OAAOA,IAAI;EACb,CAAC,MAAM;IACL,OAAO,EAAE;EACX;AACF;AAEe,SAASQ,UAAUA,CAChCC,MAAkB,EAClBC,QAAuB,EACvBC,aAA0C,EAC1CT,cAA8B,EAC9BU,GAAa,EACb;EACA,MAAM;IAAEX;EAAW,CAAC,GAAGQ,MAAM;EAC7B,MAAMI,IAAI,GAAG,IAAAR,iBAAY,EAACI,MAAM,EAAER,UAAU,EAAEC,cAAc,CAAC;EAC7D,MAAMK,QAAQ,GAAGO,YAAG,CAACC,QAAQ,CAACF,IAAI,CAAC,GAAG,IAAIC,YAAG,CAACD,IAAI,CAAC,CAACG,QAAQ,GAAGH,IAAI;EACnE,MAAMI,QAAQ,GAAGR,MAAM,EAAES,IAAI,EAAEC,GAAG,IAAI/B,gBAAgB;EACtD,MAAMgC,sBAAsB,GAAGX,MAAM,EAAEU,GAAG,EAAEC,sBAAsB,IAAI,KAAK;EAC3E;EACA,MAAMC,aAAa,GAAG,CAACC,SAAS,EAAE,IAAI,CAAC,CAACC,QAAQ,CAACd,MAAM,EAAEU,GAAG,EAAEK,UAAU,CAAC,GACrE,IAAI,GACJf,MAAM,EAAEU,GAAG,EAAEK,UAAU;EAC3B,MAAMC,QAAQ,GAAGhB,MAAM,EAAEU,GAAG,EAAEM,QAAQ,IAAI,KAAK;EAC/C,MAAMC,KAAK,GAAGjB,MAAM,EAAEU,GAAG,EAAEO,KAAK,IAAIC,iBAAS;EAC7C,MAAMC,KAAK,GAAG,IAAAC,kBAAQ,EAACpB,MAAM,CAAC;EAC9B,MAAMqB,KAAK,GAAGrB,MAAM,EAAEU,GAAG,EAAEW,KAAK,IAAI,EAAE;EACtC,MAAMC,OAAO,GAAGhC,WAAW,CAACU,MAAM,EAAEU,GAAG,EAAEY,OAAO,EAAEtB,MAAM,EAAER,UAAU,EAAEC,cAAc,CAAC;EACrF,MAAMF,IAAI,GAAGD,WAAW,CAACU,MAAM,EAAEU,GAAG,EAAEnB,IAAI,EAAES,MAAM,EAAER,UAAU,EAAEC,cAAc,CAAC;EAC/E,MAAM8B,QAAQ,GAAGjC,WAAW,CAACU,MAAM,EAAEU,GAAG,EAAEa,QAAQ,EAAEvB,MAAM,EAAER,UAAU,EAAEC,cAAc,CAAC;EACvF,MAAM+B,WAAW,GAAGxB,MAAM,EAAEU,GAAG,EAAEc,WAAW,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC;EACvE,MAAMC,OAAO,GAAGtB,GAAG,CAACuB,MAAM,CAACC,WAAW,IAAI,EAAE;EAC5C,MAAMC,KAAK,GAAG;IACZ,GAAG5B,MAAM,CAAC4B,KAAK;IACf;IACA,GAAG5B,MAAM,CAAC6B;EACZ,CAAC;EACD,MAAMC,YAAY,GAChB,IAAAC,8BAAoB,EAAC/B,MAAM,EAAEU,GAAG,EAAEsB,aAAa,IAAIhC,MAAM,EAAEU,GAAG,EAAEoB,YAAY,CAAC,IAAI,SAAS;EAC5F,MAAM;IACJG,gBAAgB;IAChBC,WAAW;IACXC,iBAAiB;IAAE;IACnBC,QAAQ;IACRC,YAAY;IACZC,eAAe;IACfC,UAAU;IACVC,UAAU;IACVC,mBAAmB;IACnBC,OAAO;IACPC;EACF,CAAC,GAAGC,MAAM,CAACC,MAAM,CACf,CAAC,CAAC,EACF;IACEZ,gBAAgB,EAAE,EAAE;IACpBa,UAAU,EAAE,EAAE;IACdZ,WAAW,EAAE;EACf,CAAC,EACDlC,MAAM,EAAEU,GACV,CAAC;EACD;EACA,IAAIqC,iBAAiB,GAAG/C,MAAM,EAAEU,GAAG,EAAEqC,iBAAiB;EACtD,IAAIZ,iBAAiB,IAAI,CAACY,iBAAiB,EAAE;IAC3CA,iBAAiB,GAAGZ,iBAAiB;EACvC;EACA,MAAMa,OAA0B,GAAG;IACjCZ,QAAQ;IACRC,YAAY;IACZC,eAAe;IACfC,UAAU;IACVC,UAAU;IACVC,mBAAmB;IACnBC,OAAO;IACPC,WAAW;IACX3B,QAAQ;IACRxB,UAAU;IACVM,QAAQ;IACRM,IAAI;IACJ0B,YAAY;IACZL,OAAO;IACPlC,IAAI;IACJgC,QAAQ;IACRD,OAAO;IACPM,KAAK;IACLT,KAAK;IACLK,WAAW;IACXP,KAAK;IACLI,KAAK;IACLb,QAAQ;IACRG;EACF,CAAC;EAED,IAAIsC,OAAO;EAEX,MAAMC,QAAQ,GAAG,YAAYC,IAAI,CAACC,SAAS,CAACJ,OAAO,CAAC,EAAE;EAEtD,IAAI;IACFC,OAAO,GAAGrE,KAAK,CAACyE,GAAG,CAACH,QAAQ,CAAC;IAC7B,IAAI,CAACD,OAAO,EAAE;MACZA,OAAO,GAAG,IAAAK,iBAAc,EACtB;QACErD,QAAQ,EAAEC,aAAa,IAAIhB,oBAAoB;QAC/C8D,OAAO;QACPf,gBAAgB;QAChBC,WAAW;QACXa;MACF,CAAC,EACD9C,QACF,CAAC;MAED,IAAIW,aAAa,EAAE;QACjBhC,KAAK,CAAC2E,GAAG,CAACL,QAAQ,EAAED,OAAO,CAAC;QAC5BjE,KAAK,CAAC,oBAAoB,CAAC;MAC7B;IACF,CAAC,MAAM;MACLA,KAAK,CAAC,sBAAsB,CAAC;IAC/B;EACF,CAAC,CAAC,OAAOwE,KAAU,EAAE;IACnB,MAAM,IAAIC,KAAK,CAAC,kCAAkCD,KAAK,CAACE,KAAK,EAAE,CAAC;EAClE;EACAvD,GAAG,CAACwD,SAAS,CAAC,cAAc,EAAEC,aAAO,CAACC,SAAS,CAAC;EAChD1D,GAAG,CAAC2D,IAAI,CAACb,OAAO,CAAC;EACjBjE,KAAK,CAAC,cAAc,CAAC;AACvB","ignoreList":[]}
1
+ {"version":3,"file":"renderHTML.js","names":["_debug","_interopRequireDefault","require","_lruCache","_core","_template","e","__esModule","default","cache","LRUCache","max","ttl","debug","buildDebug","defaultManifestFiles","js","ico","css","renderHTML","config","manifest","manifestFiles","options","res","needHtmlCache","undefined","includes","web","html_cache","scriptsBodyBefore","scriptsbodyBefore","scriptsBodyAfter","metaScripts","webPage","cacheKey","JSON","stringify","get","renderTemplate","set","error","Error","stack","setHeader","HEADERS","TEXT_HTML","send"],"sources":["../../../../src/middlewares/web/utils/renderHTML.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport type { Response } from 'express';\nimport LRUCache from 'lru-cache';\n\nimport { HEADERS } from '@verdaccio/core';\nimport type { ConfigYaml, TemplateUIOptions } from '@verdaccio/types';\n\nimport type { Manifest } from './manifest';\nimport renderTemplate from './template';\nimport type { AssetManifest } from './template';\n\n// Cache for rendered HTML templates: max 500 entries, 1 hour TTL\nconst cache = new LRUCache({ max: 500, ttl: 1000 * 60 * 60 });\n\nconst debug = buildDebug('verdaccio:web:render');\n\nconst defaultManifestFiles: Manifest = {\n js: ['vendors.js', 'main.js'],\n ico: 'favicon.ico',\n css: [],\n};\n\nexport default function renderHTML(\n config: ConfigYaml,\n manifest: AssetManifest,\n manifestFiles: Manifest | null | undefined,\n options: TemplateUIOptions,\n res: Response\n) {\n // @ts-ignore\n const needHtmlCache = [undefined, null].includes(config?.web?.html_cache)\n ? true\n : config?.web?.html_cache;\n\n const scriptsBodyBefore = config?.web?.scriptsBodyBefore || config?.web?.scriptsbodyBefore || [];\n const scriptsBodyAfter = config?.web?.scriptsBodyAfter || [];\n const metaScripts = config?.web?.metaScripts || [];\n\n let webPage;\n\n const cacheKey = `template:${JSON.stringify(options)}`;\n\n try {\n webPage = cache.get(cacheKey);\n if (!webPage) {\n webPage = renderTemplate(\n {\n manifest: manifestFiles ?? defaultManifestFiles,\n options,\n scriptsBodyAfter,\n metaScripts,\n scriptsBodyBefore,\n },\n manifest\n );\n\n if (needHtmlCache) {\n cache.set(cacheKey, 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"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AAEA,IAAAC,SAAA,GAAAF,sBAAA,CAAAC,OAAA;AAEA,IAAAE,KAAA,GAAAF,OAAA;AAIA,IAAAG,SAAA,GAAAJ,sBAAA,CAAAC,OAAA;AAAwC,SAAAD,uBAAAK,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAGxC;AACA,MAAMG,KAAK,GAAG,IAAIC,iBAAQ,CAAC;EAAEC,GAAG,EAAE,GAAG;EAAEC,GAAG,EAAE,IAAI,GAAG,EAAE,GAAG;AAAG,CAAC,CAAC;AAE7D,MAAMC,KAAK,GAAG,IAAAC,cAAU,EAAC,sBAAsB,CAAC;AAEhD,MAAMC,oBAA8B,GAAG;EACrCC,EAAE,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC;EAC7BC,GAAG,EAAE,aAAa;EAClBC,GAAG,EAAE;AACP,CAAC;AAEc,SAASC,UAAUA,CAChCC,MAAkB,EAClBC,QAAuB,EACvBC,aAA0C,EAC1CC,OAA0B,EAC1BC,GAAa,EACb;EACA;EACA,MAAMC,aAAa,GAAG,CAACC,SAAS,EAAE,IAAI,CAAC,CAACC,QAAQ,CAACP,MAAM,EAAEQ,GAAG,EAAEC,UAAU,CAAC,GACrE,IAAI,GACJT,MAAM,EAAEQ,GAAG,EAAEC,UAAU;EAE3B,MAAMC,iBAAiB,GAAGV,MAAM,EAAEQ,GAAG,EAAEE,iBAAiB,IAAIV,MAAM,EAAEQ,GAAG,EAAEG,iBAAiB,IAAI,EAAE;EAChG,MAAMC,gBAAgB,GAAGZ,MAAM,EAAEQ,GAAG,EAAEI,gBAAgB,IAAI,EAAE;EAC5D,MAAMC,WAAW,GAAGb,MAAM,EAAEQ,GAAG,EAAEK,WAAW,IAAI,EAAE;EAElD,IAAIC,OAAO;EAEX,MAAMC,QAAQ,GAAG,YAAYC,IAAI,CAACC,SAAS,CAACd,OAAO,CAAC,EAAE;EAEtD,IAAI;IACFW,OAAO,GAAGzB,KAAK,CAAC6B,GAAG,CAACH,QAAQ,CAAC;IAC7B,IAAI,CAACD,OAAO,EAAE;MACZA,OAAO,GAAG,IAAAK,iBAAc,EACtB;QACElB,QAAQ,EAAEC,aAAa,IAAIP,oBAAoB;QAC/CQ,OAAO;QACPS,gBAAgB;QAChBC,WAAW;QACXH;MACF,CAAC,EACDT,QACF,CAAC;MAED,IAAII,aAAa,EAAE;QACjBhB,KAAK,CAAC+B,GAAG,CAACL,QAAQ,EAAED,OAAO,CAAC;QAC5BrB,KAAK,CAAC,oBAAoB,CAAC;MAC7B;IACF,CAAC,MAAM;MACLA,KAAK,CAAC,sBAAsB,CAAC;IAC/B;EACF,CAAC,CAAC,OAAO4B,KAAU,EAAE;IACnB,MAAM,IAAIC,KAAK,CAAC,kCAAkCD,KAAK,CAACE,KAAK,EAAE,CAAC;EAClE;EACAnB,GAAG,CAACoB,SAAS,CAAC,cAAc,EAAEC,aAAO,CAACC,SAAS,CAAC;EAChDtB,GAAG,CAACuB,IAAI,CAACb,OAAO,CAAC;EACjBrB,KAAK,CAAC,cAAc,CAAC;AACvB","ignoreList":[]}
@@ -20,15 +20,14 @@ function renderTemplate(template, manifest) {
20
20
  <title>${template?.options?.title ?? ''}</title>
21
21
  <link rel="icon" href="${template?.options.base}-/static/favicon.ico">
22
22
  <meta name="viewport" content="width=device-width, initial-scale=1">
23
- <script>
24
- window.__VERDACCIO_BASENAME_UI_OPTIONS=${JSON.stringify(template.options)}
25
- </script>
23
+ <script src="${template?.options.base}-/static/ui-options.js"></script>
24
+ ${template.manifest.css?.length ? (0, _manifest.getManifestValue)(template.manifest.css, manifest, template?.options.base).map(item => `<link rel="stylesheet" href="${item}">`).join('\n ') : ''}
26
25
  ${template?.metaScripts ? template.metaScripts.join('') : ''}
27
26
  </head>
28
27
  <body class="body">
29
28
  ${template?.scriptsBodyBefore ? template.scriptsBodyBefore.join('') : ''}
30
29
  <div id="root"></div>
31
- ${(0, _manifest.getManifestValue)(template.manifest.js, manifest, template?.options.base).map(item => `<script defer="defer" src="${item}"></script>`).join(`\n `)}
30
+ ${(0, _manifest.getManifestValue)(template.manifest.js, manifest, template?.options.base).map(item => `<script type="module" src="${item}"></script>`).join(`\n `)}
32
31
  ${template?.scriptsBodyAfter ? template.scriptsBodyAfter.join('') : ''}
33
32
  </body>
34
33
  </html>
@@ -1 +1 @@
1
- {"version":3,"file":"template.js","names":["_debug","_interopRequireDefault","require","_manifest","e","__esModule","default","debug","buildDebug","renderTemplate","template","manifest","options","base","title","JSON","stringify","metaScripts","join","scriptsBodyBefore","getManifestValue","js","map","item","scriptsBodyAfter"],"sources":["../../../../src/middlewares/web/utils/template.ts"],"sourcesContent":["import buildDebug from 'debug';\n\nimport type { TemplateUIOptions } from '@verdaccio/types';\n\nimport type { Manifest } from './manifest';\nimport { getManifestValue } from './manifest';\n\nconst debug = buildDebug('verdaccio:web:render:template');\n\nexport type Template = {\n manifest: Manifest;\n options: TemplateUIOptions;\n metaScripts?: string[];\n scriptsBodyAfter?: string[];\n scriptsBodyBefore?: string[];\n};\n\nexport interface AssetManifest {\n [key: string]: string;\n}\n\nexport default function renderTemplate(template: Template, manifest: AssetManifest) {\n debug('template %o', template);\n debug('manifest %o', manifest);\n\n return `\n <!DOCTYPE html>\n <html lang=\"en-us\">\n <head>\n <meta charset=\"utf-8\">\n <base href=\"${template?.options.base}\">\n <title>${template?.options?.title ?? ''}</title>\n <link rel=\"icon\" href=\"${template?.options.base}-/static/favicon.ico\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <script>\n window.__VERDACCIO_BASENAME_UI_OPTIONS=${JSON.stringify(template.options)}\n </script>\n ${template?.metaScripts ? template.metaScripts.join('') : ''}\n </head>\n <body class=\"body\">\n ${template?.scriptsBodyBefore ? template.scriptsBodyBefore.join('') : ''}\n <div id=\"root\"></div>\n ${getManifestValue(template.manifest.js, manifest, template?.options.base)\n .map((item) => `<script defer=\"defer\" src=\"${item}\"></script>`)\n .join(`\\n `)}\n ${template?.scriptsBodyAfter ? template.scriptsBodyAfter.join('') : ''}\n </body>\n </html>\n `;\n}\n"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AAKA,IAAAC,SAAA,GAAAD,OAAA;AAA8C,SAAAD,uBAAAG,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAE9C,MAAMG,KAAK,GAAG,IAAAC,cAAU,EAAC,+BAA+B,CAAC;AAc1C,SAASC,cAAcA,CAACC,QAAkB,EAAEC,QAAuB,EAAE;EAClFJ,KAAK,CAAC,aAAa,EAAEG,QAAQ,CAAC;EAC9BH,KAAK,CAAC,aAAa,EAAEI,QAAQ,CAAC;EAE9B,OAAO;AACT;AACA;AACA;AACA;AACA,sBAAsBD,QAAQ,EAAEE,OAAO,CAACC,IAAI;AAC5C,iBAAiBH,QAAQ,EAAEE,OAAO,EAAEE,KAAK,IAAI,EAAE;AAC/C,iCAAiCJ,QAAQ,EAAEE,OAAO,CAACC,IAAI;AACvD;AACA;AACA,qDAAqDE,IAAI,CAACC,SAAS,CAACN,QAAQ,CAACE,OAAO,CAAC;AACrF;AACA,UAAUF,QAAQ,EAAEO,WAAW,GAAGP,QAAQ,CAACO,WAAW,CAACC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE;AACpE;AACA;AACA,UAAUR,QAAQ,EAAES,iBAAiB,GAAGT,QAAQ,CAACS,iBAAiB,CAACD,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE;AAChF;AACA,UAAU,IAAAE,0BAAgB,EAACV,QAAQ,CAACC,QAAQ,CAACU,EAAE,EAAEV,QAAQ,EAAED,QAAQ,EAAEE,OAAO,CAACC,IAAI,CAAC,CACvES,GAAG,CAAEC,IAAI,IAAK,8BAA8BA,IAAI,aAAa,CAAC,CAC9DL,IAAI,CAAC,YAAY,CAAC;AAC7B,UAAUR,QAAQ,EAAEc,gBAAgB,GAAGd,QAAQ,CAACc,gBAAgB,CAACN,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE;AAC9E;AACA;AACA,GAAG;AACH","ignoreList":[]}
1
+ {"version":3,"file":"template.js","names":["_debug","_interopRequireDefault","require","_manifest","e","__esModule","default","debug","buildDebug","renderTemplate","template","manifest","options","base","title","css","length","getManifestValue","map","item","join","metaScripts","scriptsBodyBefore","js","scriptsBodyAfter"],"sources":["../../../../src/middlewares/web/utils/template.ts"],"sourcesContent":["import buildDebug from 'debug';\n\nimport type { TemplateUIOptions } from '@verdaccio/types';\n\nimport type { Manifest } from './manifest';\nimport { getManifestValue } from './manifest';\n\nconst debug = buildDebug('verdaccio:web:render:template');\n\nexport type Template = {\n manifest: Manifest;\n options: TemplateUIOptions;\n metaScripts?: string[];\n scriptsBodyAfter?: string[];\n scriptsBodyBefore?: string[];\n};\n\nexport interface AssetManifest {\n [key: string]: string;\n}\n\nexport default function renderTemplate(template: Template, manifest: AssetManifest) {\n debug('template %o', template);\n debug('manifest %o', manifest);\n\n return `\n <!DOCTYPE html>\n <html lang=\"en-us\">\n <head>\n <meta charset=\"utf-8\">\n <base href=\"${template?.options.base}\">\n <title>${template?.options?.title ?? ''}</title>\n <link rel=\"icon\" href=\"${template?.options.base}-/static/favicon.ico\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <script src=\"${template?.options.base}-/static/ui-options.js\"></script>\n ${\n template.manifest.css?.length\n ? getManifestValue(template.manifest.css, manifest, template?.options.base)\n .map((item) => `<link rel=\"stylesheet\" href=\"${item}\">`)\n .join('\\n ')\n : ''\n }\n ${template?.metaScripts ? template.metaScripts.join('') : ''}\n </head>\n <body class=\"body\">\n ${template?.scriptsBodyBefore ? template.scriptsBodyBefore.join('') : ''}\n <div id=\"root\"></div>\n ${getManifestValue(template.manifest.js, manifest, template?.options.base)\n .map((item) => `<script type=\"module\" src=\"${item}\"></script>`)\n .join(`\\n `)}\n ${template?.scriptsBodyAfter ? template.scriptsBodyAfter.join('') : ''}\n </body>\n </html>\n `;\n}\n"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AAKA,IAAAC,SAAA,GAAAD,OAAA;AAA8C,SAAAD,uBAAAG,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAE9C,MAAMG,KAAK,GAAG,IAAAC,cAAU,EAAC,+BAA+B,CAAC;AAc1C,SAASC,cAAcA,CAACC,QAAkB,EAAEC,QAAuB,EAAE;EAClFJ,KAAK,CAAC,aAAa,EAAEG,QAAQ,CAAC;EAC9BH,KAAK,CAAC,aAAa,EAAEI,QAAQ,CAAC;EAE9B,OAAO;AACT;AACA;AACA;AACA;AACA,sBAAsBD,QAAQ,EAAEE,OAAO,CAACC,IAAI;AAC5C,iBAAiBH,QAAQ,EAAEE,OAAO,EAAEE,KAAK,IAAI,EAAE;AAC/C,iCAAiCJ,QAAQ,EAAEE,OAAO,CAACC,IAAI;AACvD;AACA,uBAAuBH,QAAQ,EAAEE,OAAO,CAACC,IAAI;AAC7C,UACUH,QAAQ,CAACC,QAAQ,CAACI,GAAG,EAAEC,MAAM,GACzB,IAAAC,0BAAgB,EAACP,QAAQ,CAACC,QAAQ,CAACI,GAAG,EAAEJ,QAAQ,EAAED,QAAQ,EAAEE,OAAO,CAACC,IAAI,CAAC,CACtEK,GAAG,CAAEC,IAAI,IAAK,gCAAgCA,IAAI,IAAI,CAAC,CACvDC,IAAI,CAAC,YAAY,CAAC,GACrB,EAAE;AAChB,UACUV,QAAQ,EAAEW,WAAW,GAAGX,QAAQ,CAACW,WAAW,CAACD,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE;AACpE;AACA;AACA,UAAUV,QAAQ,EAAEY,iBAAiB,GAAGZ,QAAQ,CAACY,iBAAiB,CAACF,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE;AAChF;AACA,UAAU,IAAAH,0BAAgB,EAACP,QAAQ,CAACC,QAAQ,CAACY,EAAE,EAAEZ,QAAQ,EAAED,QAAQ,EAAEE,OAAO,CAACC,IAAI,CAAC,CACvEK,GAAG,CAAEC,IAAI,IAAK,8BAA8BA,IAAI,aAAa,CAAC,CAC9DC,IAAI,CAAC,YAAY,CAAC;AAC7B,UAAUV,QAAQ,EAAEc,gBAAgB,GAAGd,QAAQ,CAACc,gBAAgB,CAACJ,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE;AAC9E;AACA;AACA,GAAG;AACH","ignoreList":[]}
@@ -0,0 +1,4 @@
1
+ import type { Response } from 'express';
2
+ import type { ConfigYaml, TemplateUIOptions } from '@verdaccio/types';
3
+ import { type RequestOptions } from '@verdaccio/url';
4
+ export declare function getUIOptions(config: ConfigYaml, requestOptions: RequestOptions, res: Response): TemplateUIOptions;
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getUIOptions = getUIOptions;
7
+ var _nodePath = _interopRequireDefault(require("node:path"));
8
+ var _nodeUrl = require("node:url");
9
+ var _config = require("@verdaccio/config");
10
+ var _url = require("@verdaccio/url");
11
+ var _webUtils = require("./web-utils");
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
+ const DEFAULT_LANGUAGE = 'en-US';
14
+ function resolveLogo(logo, url_prefix, requestOptions) {
15
+ if (typeof logo !== 'string') {
16
+ return '';
17
+ }
18
+ const isLocalFile = logo && !(0, _url.isURLhasValidProtocol)(logo);
19
+ if (isLocalFile) {
20
+ return `${(0, _url.getPublicUrl)(url_prefix, requestOptions)}-/static/${_nodePath.default.basename(logo)}`;
21
+ } else if ((0, _url.isURLhasValidProtocol)(logo)) {
22
+ return logo;
23
+ } else {
24
+ return '';
25
+ }
26
+ }
27
+ function getUIOptions(config, requestOptions, res) {
28
+ const {
29
+ url_prefix
30
+ } = config;
31
+ const base = (0, _url.getPublicUrl)(config?.url_prefix, requestOptions);
32
+ const basename = _nodeUrl.URL.canParse(base) ? new _nodeUrl.URL(base).pathname : base;
33
+ const language = config?.i18n?.web ?? DEFAULT_LANGUAGE;
34
+ const hideDeprecatedVersions = config?.web?.hideDeprecatedVersions ?? false;
35
+ const darkMode = config?.web?.darkMode ?? false;
36
+ const title = config?.web?.title ?? _config.WEB_TITLE;
37
+ const login = (0, _webUtils.hasLogin)(config);
38
+ const scope = config?.web?.scope ?? '';
39
+ const favicon = resolveLogo(config?.web?.favicon, config?.url_prefix, requestOptions);
40
+ const logo = resolveLogo(config?.web?.logo, config?.url_prefix, requestOptions);
41
+ const logoDark = resolveLogo(config?.web?.logoDark, config?.url_prefix, requestOptions);
42
+ const pkgManagers = config?.web?.pkgManagers ?? ['yarn', 'pnpm', 'npm'];
43
+ const version = res.locals.app_version ?? '';
44
+ const flags = {
45
+ ...config.flags,
46
+ // legacy from 5.x
47
+ ...config.experiments
48
+ };
49
+ const primaryColor = (0, _webUtils.validatePrimaryColor)(config?.web?.primary_color ?? config?.web?.primaryColor) ?? '#4b5e40';
50
+ const {
51
+ showInfo,
52
+ showSettings,
53
+ showThemeSwitch,
54
+ showFooter,
55
+ showSearch,
56
+ showDownloadTarball,
57
+ showRaw,
58
+ showUplinks
59
+ } = Object.assign({}, config?.web);
60
+ return {
61
+ showInfo,
62
+ showSettings,
63
+ showThemeSwitch,
64
+ showFooter,
65
+ showSearch,
66
+ showDownloadTarball,
67
+ showRaw,
68
+ showUplinks,
69
+ darkMode,
70
+ url_prefix,
71
+ basename,
72
+ base,
73
+ primaryColor,
74
+ version,
75
+ logo,
76
+ logoDark,
77
+ favicon,
78
+ flags,
79
+ login,
80
+ pkgManagers,
81
+ title,
82
+ scope,
83
+ language,
84
+ hideDeprecatedVersions
85
+ };
86
+ }
87
+ //# sourceMappingURL=ui-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-options.js","names":["_nodePath","_interopRequireDefault","require","_nodeUrl","_config","_url","_webUtils","e","__esModule","default","DEFAULT_LANGUAGE","resolveLogo","logo","url_prefix","requestOptions","isLocalFile","isURLhasValidProtocol","getPublicUrl","path","basename","getUIOptions","config","res","base","URL","canParse","pathname","language","i18n","web","hideDeprecatedVersions","darkMode","title","WEB_TITLE","login","hasLogin","scope","favicon","logoDark","pkgManagers","version","locals","app_version","flags","experiments","primaryColor","validatePrimaryColor","primary_color","showInfo","showSettings","showThemeSwitch","showFooter","showSearch","showDownloadTarball","showRaw","showUplinks","Object","assign"],"sources":["../../../../src/middlewares/web/utils/ui-options.ts"],"sourcesContent":["import type { Response } from 'express';\nimport path from 'node:path';\nimport { URL } from 'node:url';\n\nimport { WEB_TITLE } from '@verdaccio/config';\nimport type { ConfigYaml, TemplateUIOptions } from '@verdaccio/types';\nimport { type RequestOptions, getPublicUrl, isURLhasValidProtocol } from '@verdaccio/url';\n\nimport { hasLogin, validatePrimaryColor } from './web-utils';\n\nconst DEFAULT_LANGUAGE = 'en-US';\n\nfunction resolveLogo(\n logo: string | undefined,\n url_prefix: string | undefined,\n requestOptions: RequestOptions\n) {\n if (typeof logo !== 'string') {\n return '';\n }\n const isLocalFile = logo && !isURLhasValidProtocol(logo);\n\n if (isLocalFile) {\n return `${getPublicUrl(url_prefix, requestOptions)}-/static/${path.basename(logo)}`;\n } else if (isURLhasValidProtocol(logo)) {\n return logo;\n } else {\n return '';\n }\n}\n\nexport function getUIOptions(\n config: ConfigYaml,\n requestOptions: RequestOptions,\n res: Response\n): TemplateUIOptions {\n const { url_prefix } = config;\n const base = getPublicUrl(config?.url_prefix, requestOptions);\n const basename = URL.canParse(base) ? new URL(base).pathname : base;\n const language = config?.i18n?.web ?? DEFAULT_LANGUAGE;\n const hideDeprecatedVersions = config?.web?.hideDeprecatedVersions ?? false;\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 favicon = resolveLogo(config?.web?.favicon, config?.url_prefix, requestOptions);\n const logo = resolveLogo(config?.web?.logo, config?.url_prefix, requestOptions);\n const logoDark = resolveLogo(config?.web?.logoDark, config?.url_prefix, requestOptions);\n const pkgManagers = config?.web?.pkgManagers ?? ['yarn', 'pnpm', 'npm'];\n const version = res.locals.app_version ?? '';\n const flags = {\n ...config.flags,\n // legacy from 5.x\n ...config.experiments,\n };\n const primaryColor =\n validatePrimaryColor(config?.web?.primary_color ?? config?.web?.primaryColor) ?? '#4b5e40';\n const {\n showInfo,\n showSettings,\n showThemeSwitch,\n showFooter,\n showSearch,\n showDownloadTarball,\n showRaw,\n showUplinks,\n } = Object.assign({}, config?.web);\n\n return {\n showInfo,\n showSettings,\n showThemeSwitch,\n showFooter,\n showSearch,\n showDownloadTarball,\n showRaw,\n showUplinks,\n darkMode,\n url_prefix,\n basename,\n base,\n primaryColor,\n version,\n logo,\n logoDark,\n favicon,\n flags,\n login,\n pkgManagers,\n title,\n scope,\n language,\n hideDeprecatedVersions,\n };\n}\n"],"mappings":";;;;;;AACA,IAAAA,SAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,QAAA,GAAAD,OAAA;AAEA,IAAAE,OAAA,GAAAF,OAAA;AAEA,IAAAG,IAAA,GAAAH,OAAA;AAEA,IAAAI,SAAA,GAAAJ,OAAA;AAA6D,SAAAD,uBAAAM,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAE7D,MAAMG,gBAAgB,GAAG,OAAO;AAEhC,SAASC,WAAWA,CAClBC,IAAwB,EACxBC,UAA8B,EAC9BC,cAA8B,EAC9B;EACA,IAAI,OAAOF,IAAI,KAAK,QAAQ,EAAE;IAC5B,OAAO,EAAE;EACX;EACA,MAAMG,WAAW,GAAGH,IAAI,IAAI,CAAC,IAAAI,0BAAqB,EAACJ,IAAI,CAAC;EAExD,IAAIG,WAAW,EAAE;IACf,OAAO,GAAG,IAAAE,iBAAY,EAACJ,UAAU,EAAEC,cAAc,CAAC,YAAYI,iBAAI,CAACC,QAAQ,CAACP,IAAI,CAAC,EAAE;EACrF,CAAC,MAAM,IAAI,IAAAI,0BAAqB,EAACJ,IAAI,CAAC,EAAE;IACtC,OAAOA,IAAI;EACb,CAAC,MAAM;IACL,OAAO,EAAE;EACX;AACF;AAEO,SAASQ,YAAYA,CAC1BC,MAAkB,EAClBP,cAA8B,EAC9BQ,GAAa,EACM;EACnB,MAAM;IAAET;EAAW,CAAC,GAAGQ,MAAM;EAC7B,MAAME,IAAI,GAAG,IAAAN,iBAAY,EAACI,MAAM,EAAER,UAAU,EAAEC,cAAc,CAAC;EAC7D,MAAMK,QAAQ,GAAGK,YAAG,CAACC,QAAQ,CAACF,IAAI,CAAC,GAAG,IAAIC,YAAG,CAACD,IAAI,CAAC,CAACG,QAAQ,GAAGH,IAAI;EACnE,MAAMI,QAAQ,GAAGN,MAAM,EAAEO,IAAI,EAAEC,GAAG,IAAInB,gBAAgB;EACtD,MAAMoB,sBAAsB,GAAGT,MAAM,EAAEQ,GAAG,EAAEC,sBAAsB,IAAI,KAAK;EAC3E,MAAMC,QAAQ,GAAGV,MAAM,EAAEQ,GAAG,EAAEE,QAAQ,IAAI,KAAK;EAC/C,MAAMC,KAAK,GAAGX,MAAM,EAAEQ,GAAG,EAAEG,KAAK,IAAIC,iBAAS;EAC7C,MAAMC,KAAK,GAAG,IAAAC,kBAAQ,EAACd,MAAM,CAAC;EAC9B,MAAMe,KAAK,GAAGf,MAAM,EAAEQ,GAAG,EAAEO,KAAK,IAAI,EAAE;EACtC,MAAMC,OAAO,GAAG1B,WAAW,CAACU,MAAM,EAAEQ,GAAG,EAAEQ,OAAO,EAAEhB,MAAM,EAAER,UAAU,EAAEC,cAAc,CAAC;EACrF,MAAMF,IAAI,GAAGD,WAAW,CAACU,MAAM,EAAEQ,GAAG,EAAEjB,IAAI,EAAES,MAAM,EAAER,UAAU,EAAEC,cAAc,CAAC;EAC/E,MAAMwB,QAAQ,GAAG3B,WAAW,CAACU,MAAM,EAAEQ,GAAG,EAAES,QAAQ,EAAEjB,MAAM,EAAER,UAAU,EAAEC,cAAc,CAAC;EACvF,MAAMyB,WAAW,GAAGlB,MAAM,EAAEQ,GAAG,EAAEU,WAAW,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC;EACvE,MAAMC,OAAO,GAAGlB,GAAG,CAACmB,MAAM,CAACC,WAAW,IAAI,EAAE;EAC5C,MAAMC,KAAK,GAAG;IACZ,GAAGtB,MAAM,CAACsB,KAAK;IACf;IACA,GAAGtB,MAAM,CAACuB;EACZ,CAAC;EACD,MAAMC,YAAY,GAChB,IAAAC,8BAAoB,EAACzB,MAAM,EAAEQ,GAAG,EAAEkB,aAAa,IAAI1B,MAAM,EAAEQ,GAAG,EAAEgB,YAAY,CAAC,IAAI,SAAS;EAC5F,MAAM;IACJG,QAAQ;IACRC,YAAY;IACZC,eAAe;IACfC,UAAU;IACVC,UAAU;IACVC,mBAAmB;IACnBC,OAAO;IACPC;EACF,CAAC,GAAGC,MAAM,CAACC,MAAM,CAAC,CAAC,CAAC,EAAEpC,MAAM,EAAEQ,GAAG,CAAC;EAElC,OAAO;IACLmB,QAAQ;IACRC,YAAY;IACZC,eAAe;IACfC,UAAU;IACVC,UAAU;IACVC,mBAAmB;IACnBC,OAAO;IACPC,WAAW;IACXxB,QAAQ;IACRlB,UAAU;IACVM,QAAQ;IACRI,IAAI;IACJsB,YAAY;IACZL,OAAO;IACP5B,IAAI;IACJ0B,QAAQ;IACRD,OAAO;IACPM,KAAK;IACLT,KAAK;IACLK,WAAW;IACXP,KAAK;IACLI,KAAK;IACLT,QAAQ;IACRG;EACF,CAAC;AACH","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verdaccio/middleware",
3
- "version": "8.0.0-next-8.36",
3
+ "version": "8.0.0-next-8.37",
4
4
  "description": "Verdaccio Express Middleware",
5
5
  "main": "./build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -33,9 +33,9 @@
33
33
  "node": ">=18"
34
34
  },
35
35
  "dependencies": {
36
- "@verdaccio/config": "8.0.0-next-8.36",
37
- "@verdaccio/core": "8.0.0-next-8.36",
38
- "@verdaccio/url": "13.0.0-next-8.36",
36
+ "@verdaccio/config": "8.0.0-next-8.37",
37
+ "@verdaccio/core": "8.0.0-next-8.37",
38
+ "@verdaccio/url": "13.0.0-next-8.37",
39
39
  "debug": "4.4.3",
40
40
  "express": "4.22.1",
41
41
  "express-rate-limit": "5.5.1",
@@ -47,7 +47,7 @@
47
47
  "url": "https://opencollective.com/verdaccio"
48
48
  },
49
49
  "devDependencies": {
50
- "@verdaccio/logger": "8.0.0-next-8.36",
50
+ "@verdaccio/logger": "8.0.0-next-8.37",
51
51
  "@verdaccio/types": "13.0.0-next-8.12",
52
52
  "http-errors": "2.0.1",
53
53
  "supertest": "7.1.4",