@verdaccio/ui-components 5.0.0-next-9.6 → 5.0.0-next-9.8

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.
Files changed (61) hide show
  1. package/build/components/ActionBar/ActionBarAction.mjs +2 -2
  2. package/build/components/ActionBar/ActionBarAction.mjs.map +1 -1
  3. package/build/components/Dependencies/DependencyBlock.mjs +2 -2
  4. package/build/components/Dependencies/DependencyBlock.mjs.map +1 -1
  5. package/build/components/Developers/Title.mjs +2 -2
  6. package/build/components/Developers/Title.mjs.map +1 -1
  7. package/build/components/Distribution/styles.mjs +2 -2
  8. package/build/components/Distribution/styles.mjs.map +1 -1
  9. package/build/components/Engines/styles.mjs +2 -2
  10. package/build/components/Engines/styles.mjs.map +1 -1
  11. package/build/components/ErrorBoundary/ErrorBoundary.d.ts +1 -1
  12. package/build/components/Heading/Heading.mjs +2 -2
  13. package/build/components/Heading/Heading.mjs.map +1 -1
  14. package/build/components/Help/Help.mjs +3 -3
  15. package/build/components/Help/Help.mjs.map +1 -1
  16. package/build/components/Keywords/Keywords.mjs +2 -2
  17. package/build/components/Keywords/Keywords.mjs.map +1 -1
  18. package/build/components/Link/Link.mjs +2 -2
  19. package/build/components/Link/Link.mjs.map +1 -1
  20. package/build/components/LoginForm/Login.mjs +2 -2
  21. package/build/components/LoginForm/Login.mjs.map +1 -1
  22. package/build/components/NoItems/NoItems.mjs +2 -2
  23. package/build/components/NoItems/NoItems.mjs.map +1 -1
  24. package/build/components/Package/Package.mjs +2 -2
  25. package/build/components/Package/Package.mjs.map +1 -1
  26. package/build/components/Person/PersonTooltip.mjs +2 -2
  27. package/build/components/Person/PersonTooltip.mjs.map +1 -1
  28. package/build/components/Repository/Repository.mjs +2 -2
  29. package/build/components/Repository/Repository.mjs.map +1 -1
  30. package/build/components/Search/Search.js +17 -33
  31. package/build/components/Search/Search.js.map +1 -1
  32. package/build/components/Search/Search.mjs +16 -31
  33. package/build/components/Search/Search.mjs.map +1 -1
  34. package/build/components/Search/utils.d.ts +21 -0
  35. package/build/components/Search/utils.js +37 -0
  36. package/build/components/Search/utils.js.map +1 -1
  37. package/build/components/Search/utils.mjs +37 -1
  38. package/build/components/Search/utils.mjs.map +1 -1
  39. package/build/components/UpLinks/styles.mjs +2 -2
  40. package/build/components/UpLinks/styles.mjs.map +1 -1
  41. package/build/components/Versions/Versions.js +2 -3
  42. package/build/components/Versions/Versions.js.map +1 -1
  43. package/build/components/Versions/Versions.mjs +3 -3
  44. package/build/components/Versions/Versions.mjs.map +1 -1
  45. package/build/sections/Header/LanguageSwitch.mjs +2 -2
  46. package/build/sections/Header/LanguageSwitch.mjs.map +1 -1
  47. package/build/sections/Header/RegistryInfoContent/RegistryInfoContent.mjs +5 -5
  48. package/build/sections/Header/RegistryInfoContent/RegistryInfoContent.mjs.map +1 -1
  49. package/build/sections/Security/utils.js +1 -2
  50. package/build/sections/Security/utils.js.map +1 -1
  51. package/build/sections/Security/utils.mjs +1 -1
  52. package/build/sections/Security/utils.mjs.map +1 -1
  53. package/build/utils/token.js +4 -7
  54. package/build/utils/token.js.map +1 -1
  55. package/build/utils/token.mjs +2 -3
  56. package/build/utils/token.mjs.map +1 -1
  57. package/build/utils/utils.js +2 -4
  58. package/build/utils/utils.js.map +1 -1
  59. package/build/utils/utils.mjs +2 -3
  60. package/build/utils/utils.mjs.map +1 -1
  61. package/package.json +5 -4
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":[],"sources":["../../../src/sections/Security/utils.ts"],"sourcesContent":["import isEmpty from 'lodash/isEmpty';\n\nimport { Route } from '../../utils';\n\nexport interface SecurityUrlParams {\n readonly next: string;\n readonly user: string;\n}\n\nexport interface LocationLike {\n readonly search: string;\n}\n\nexport function getSecurityUrlParams(location: LocationLike): SecurityUrlParams {\n const queryParams = new URLSearchParams(location.search);\n\n // Get next parameter to match v1 URLs\n let next = queryParams.get('next') || '';\n if (next.length > 0 && (!next.startsWith(Route.LOGIN_API) || !next.match(/\\/[-0-9a-f]{36}$/))) {\n next = '';\n }\n\n // Ignore user parameter if it does not match expected format (prevent XSS attacks)\n let user = queryParams.get('user') || '';\n if (user.length > 0 && !user.match(/^[a-zA-Z0-9-_]{1,255}$/)) {\n user = '';\n }\n\n return { next, user };\n}\n\nexport interface TranslationFunction {\n (key: string, options?: Record<string, unknown>): string;\n}\n\nexport interface DispatchAction {\n (payload: { type: string; description: string }): void;\n}\n\nexport const validateCredentials = (\n username: string,\n password: string,\n t: TranslationFunction,\n dispatchAction: DispatchAction\n): boolean => {\n if (!username || !password || isEmpty(username) || isEmpty(password)) {\n dispatchAction({\n type: 'error',\n description: t('security.error.username-or-password-cant-be-empty'),\n });\n return false;\n }\n\n if (username.length < 2) {\n dispatchAction({\n type: 'error',\n description: t('security.error.username-min-length', { length: 2 }),\n });\n return false;\n }\n\n // Validate username contains only url-safe characters\n if (!username.match(/^[-a-zA-Z0-9_.!~*'()@]+$/)) {\n dispatchAction({\n type: 'error',\n description: t('security.error.username-must-be-url-safe'),\n });\n return false;\n }\n\n // Note: password rules should be checked in auth plugin\n return true;\n};\n"],"mappings":";;;;;AAaA,SAAgB,qBAAqB,UAA2C;CAC9E,MAAM,cAAc,IAAI,gBAAgB,SAAS,OAAO;CAGxD,IAAI,OAAO,YAAY,IAAI,OAAO,IAAI;AACtC,KAAI,KAAK,SAAS,MAAM,CAAC,KAAK,WAAW,eAAA,MAAM,UAAU,IAAI,CAAC,KAAK,MAAM,mBAAmB,EAC1F,QAAO;CAIT,IAAI,OAAO,YAAY,IAAI,OAAO,IAAI;AACtC,KAAI,KAAK,SAAS,KAAK,CAAC,KAAK,MAAM,yBAAyB,CAC1D,QAAO;AAGT,QAAO;EAAE;EAAM;EAAM"}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../../src/sections/Security/utils.ts"],"sourcesContent":["import { isEmpty } from 'lodash-es';\n\nimport { Route } from '../../utils';\n\nexport interface SecurityUrlParams {\n readonly next: string;\n readonly user: string;\n}\n\nexport interface LocationLike {\n readonly search: string;\n}\n\nexport function getSecurityUrlParams(location: LocationLike): SecurityUrlParams {\n const queryParams = new URLSearchParams(location.search);\n\n // Get next parameter to match v1 URLs\n let next = queryParams.get('next') || '';\n if (next.length > 0 && (!next.startsWith(Route.LOGIN_API) || !next.match(/\\/[-0-9a-f]{36}$/))) {\n next = '';\n }\n\n // Ignore user parameter if it does not match expected format (prevent XSS attacks)\n let user = queryParams.get('user') || '';\n if (user.length > 0 && !user.match(/^[a-zA-Z0-9-_]{1,255}$/)) {\n user = '';\n }\n\n return { next, user };\n}\n\nexport interface TranslationFunction {\n (key: string, options?: Record<string, unknown>): string;\n}\n\nexport interface DispatchAction {\n (payload: { type: string; description: string }): void;\n}\n\nexport const validateCredentials = (\n username: string,\n password: string,\n t: TranslationFunction,\n dispatchAction: DispatchAction\n): boolean => {\n if (!username || !password || isEmpty(username) || isEmpty(password)) {\n dispatchAction({\n type: 'error',\n description: t('security.error.username-or-password-cant-be-empty'),\n });\n return false;\n }\n\n if (username.length < 2) {\n dispatchAction({\n type: 'error',\n description: t('security.error.username-min-length', { length: 2 }),\n });\n return false;\n }\n\n // Validate username contains only url-safe characters\n if (!username.match(/^[-a-zA-Z0-9_.!~*'()@]+$/)) {\n dispatchAction({\n type: 'error',\n description: t('security.error.username-must-be-url-safe'),\n });\n return false;\n }\n\n // Note: password rules should be checked in auth plugin\n return true;\n};\n"],"mappings":";;;;AAaA,SAAgB,qBAAqB,UAA2C;CAC9E,MAAM,cAAc,IAAI,gBAAgB,SAAS,OAAO;CAGxD,IAAI,OAAO,YAAY,IAAI,OAAO,IAAI;AACtC,KAAI,KAAK,SAAS,MAAM,CAAC,KAAK,WAAW,eAAA,MAAM,UAAU,IAAI,CAAC,KAAK,MAAM,mBAAmB,EAC1F,QAAO;CAIT,IAAI,OAAO,YAAY,IAAI,OAAO,IAAI;AACtC,KAAI,KAAK,SAAS,KAAK,CAAC,KAAK,MAAM,yBAAyB,CAC1D,QAAO;AAGT,QAAO;EAAE;EAAM;EAAM"}
@@ -1,6 +1,6 @@
1
1
  import { Route } from "../../utils/routes.mjs";
2
2
  import "../../utils/index.mjs";
3
- import "lodash/isEmpty";
3
+ import "lodash-es";
4
4
  //#region src/sections/Security/utils.ts
5
5
  function getSecurityUrlParams(location) {
6
6
  const queryParams = new URLSearchParams(location.search);
@@ -1 +1 @@
1
- {"version":3,"file":"utils.mjs","names":[],"sources":["../../../src/sections/Security/utils.ts"],"sourcesContent":["import isEmpty from 'lodash/isEmpty';\n\nimport { Route } from '../../utils';\n\nexport interface SecurityUrlParams {\n readonly next: string;\n readonly user: string;\n}\n\nexport interface LocationLike {\n readonly search: string;\n}\n\nexport function getSecurityUrlParams(location: LocationLike): SecurityUrlParams {\n const queryParams = new URLSearchParams(location.search);\n\n // Get next parameter to match v1 URLs\n let next = queryParams.get('next') || '';\n if (next.length > 0 && (!next.startsWith(Route.LOGIN_API) || !next.match(/\\/[-0-9a-f]{36}$/))) {\n next = '';\n }\n\n // Ignore user parameter if it does not match expected format (prevent XSS attacks)\n let user = queryParams.get('user') || '';\n if (user.length > 0 && !user.match(/^[a-zA-Z0-9-_]{1,255}$/)) {\n user = '';\n }\n\n return { next, user };\n}\n\nexport interface TranslationFunction {\n (key: string, options?: Record<string, unknown>): string;\n}\n\nexport interface DispatchAction {\n (payload: { type: string; description: string }): void;\n}\n\nexport const validateCredentials = (\n username: string,\n password: string,\n t: TranslationFunction,\n dispatchAction: DispatchAction\n): boolean => {\n if (!username || !password || isEmpty(username) || isEmpty(password)) {\n dispatchAction({\n type: 'error',\n description: t('security.error.username-or-password-cant-be-empty'),\n });\n return false;\n }\n\n if (username.length < 2) {\n dispatchAction({\n type: 'error',\n description: t('security.error.username-min-length', { length: 2 }),\n });\n return false;\n }\n\n // Validate username contains only url-safe characters\n if (!username.match(/^[-a-zA-Z0-9_.!~*'()@]+$/)) {\n dispatchAction({\n type: 'error',\n description: t('security.error.username-must-be-url-safe'),\n });\n return false;\n }\n\n // Note: password rules should be checked in auth plugin\n return true;\n};\n"],"mappings":";;;;AAaA,SAAgB,qBAAqB,UAA2C;CAC9E,MAAM,cAAc,IAAI,gBAAgB,SAAS,OAAO;CAGxD,IAAI,OAAO,YAAY,IAAI,OAAO,IAAI;AACtC,KAAI,KAAK,SAAS,MAAM,CAAC,KAAK,WAAW,MAAM,UAAU,IAAI,CAAC,KAAK,MAAM,mBAAmB,EAC1F,QAAO;CAIT,IAAI,OAAO,YAAY,IAAI,OAAO,IAAI;AACtC,KAAI,KAAK,SAAS,KAAK,CAAC,KAAK,MAAM,yBAAyB,CAC1D,QAAO;AAGT,QAAO;EAAE;EAAM;EAAM"}
1
+ {"version":3,"file":"utils.mjs","names":[],"sources":["../../../src/sections/Security/utils.ts"],"sourcesContent":["import { isEmpty } from 'lodash-es';\n\nimport { Route } from '../../utils';\n\nexport interface SecurityUrlParams {\n readonly next: string;\n readonly user: string;\n}\n\nexport interface LocationLike {\n readonly search: string;\n}\n\nexport function getSecurityUrlParams(location: LocationLike): SecurityUrlParams {\n const queryParams = new URLSearchParams(location.search);\n\n // Get next parameter to match v1 URLs\n let next = queryParams.get('next') || '';\n if (next.length > 0 && (!next.startsWith(Route.LOGIN_API) || !next.match(/\\/[-0-9a-f]{36}$/))) {\n next = '';\n }\n\n // Ignore user parameter if it does not match expected format (prevent XSS attacks)\n let user = queryParams.get('user') || '';\n if (user.length > 0 && !user.match(/^[a-zA-Z0-9-_]{1,255}$/)) {\n user = '';\n }\n\n return { next, user };\n}\n\nexport interface TranslationFunction {\n (key: string, options?: Record<string, unknown>): string;\n}\n\nexport interface DispatchAction {\n (payload: { type: string; description: string }): void;\n}\n\nexport const validateCredentials = (\n username: string,\n password: string,\n t: TranslationFunction,\n dispatchAction: DispatchAction\n): boolean => {\n if (!username || !password || isEmpty(username) || isEmpty(password)) {\n dispatchAction({\n type: 'error',\n description: t('security.error.username-or-password-cant-be-empty'),\n });\n return false;\n }\n\n if (username.length < 2) {\n dispatchAction({\n type: 'error',\n description: t('security.error.username-min-length', { length: 2 }),\n });\n return false;\n }\n\n // Validate username contains only url-safe characters\n if (!username.match(/^[-a-zA-Z0-9_.!~*'()@]+$/)) {\n dispatchAction({\n type: 'error',\n description: t('security.error.username-must-be-url-safe'),\n });\n return false;\n }\n\n // Note: password rules should be checked in auth plugin\n return true;\n};\n"],"mappings":";;;;AAaA,SAAgB,qBAAqB,UAA2C;CAC9E,MAAM,cAAc,IAAI,gBAAgB,SAAS,OAAO;CAGxD,IAAI,OAAO,YAAY,IAAI,OAAO,IAAI;AACtC,KAAI,KAAK,SAAS,MAAM,CAAC,KAAK,WAAW,MAAM,UAAU,IAAI,CAAC,KAAK,MAAM,mBAAmB,EAC1F,QAAO;CAIT,IAAI,OAAO,YAAY,IAAI,OAAO,IAAI;AACtC,KAAI,KAAK,SAAS,KAAK,CAAC,KAAK,MAAM,yBAAyB,CAC1D,QAAO;AAGT,QAAO;EAAE;EAAM;EAAM"}
@@ -1,12 +1,9 @@
1
- const require_runtime = require("../_virtual/_rolldown/runtime.js");
2
- let lodash_isString = require("lodash/isString");
3
- lodash_isString = require_runtime.__toESM(lodash_isString);
1
+ require("../_virtual/_rolldown/runtime.js");
4
2
  let js_base64 = require("js-base64");
5
- let lodash_isNumber = require("lodash/isNumber");
6
- lodash_isNumber = require_runtime.__toESM(lodash_isNumber);
3
+ let lodash_es = require("lodash-es");
7
4
  //#region src/utils/token.ts
8
5
  function isTokenExpire(token) {
9
- if (!(0, lodash_isString.default)(token)) return true;
6
+ if (typeof token !== "string") return true;
10
7
  const [, payload] = token.split(".");
11
8
  if (!payload) return true;
12
9
  let exp;
@@ -16,7 +13,7 @@ function isTokenExpire(token) {
16
13
  console.error("Invalid token:", error, token);
17
14
  return true;
18
15
  }
19
- if (!exp || !(0, lodash_isNumber.default)(exp)) return true;
16
+ if (!exp || !(0, lodash_es.isNumber)(exp)) return true;
20
17
  const jsTimestamp = exp * 1e3 - 3e4;
21
18
  return Date.now() >= jsTimestamp;
22
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"token.js","names":[],"sources":["../../src/utils/token.ts"],"sourcesContent":["import { Base64 } from 'js-base64';\nimport isNumber from 'lodash/isNumber';\nimport isString from 'lodash/isString';\n\nexport function isTokenExpire(token: string | null): boolean {\n if (!isString(token)) {\n return true;\n }\n\n const [, payload] = token.split('.');\n\n if (!payload) {\n return true;\n }\n\n let exp: number;\n try {\n exp = JSON.parse(Base64.decode(payload)).exp;\n } catch (error: unknown) {\n console.error('Invalid token:', error, token);\n return true;\n }\n\n if (!exp || !isNumber(exp)) {\n return true;\n }\n // Report as expire before (real expire time - 30s)\n const jsTimestamp = exp * 1000 - 30000;\n const expired = Date.now() >= jsTimestamp;\n\n return expired;\n}\n"],"mappings":";;;;;;;AAIA,SAAgB,cAAc,OAA+B;AAC3D,KAAI,EAAA,GAAA,gBAAA,SAAU,MAAM,CAClB,QAAO;CAGT,MAAM,GAAG,WAAW,MAAM,MAAM,IAAI;AAEpC,KAAI,CAAC,QACH,QAAO;CAGT,IAAI;AACJ,KAAI;AACF,QAAM,KAAK,MAAM,UAAA,OAAO,OAAO,QAAQ,CAAC,CAAC;UAClC,OAAgB;AACvB,UAAQ,MAAM,kBAAkB,OAAO,MAAM;AAC7C,SAAO;;AAGT,KAAI,CAAC,OAAO,EAAA,GAAA,gBAAA,SAAU,IAAI,CACxB,QAAO;CAGT,MAAM,cAAc,MAAM,MAAO;AAGjC,QAFgB,KAAK,KAAK,IAAI"}
1
+ {"version":3,"file":"token.js","names":[],"sources":["../../src/utils/token.ts"],"sourcesContent":["import { Base64 } from 'js-base64';\nimport { isNumber } from 'lodash-es';\n\nexport function isTokenExpire(token: string | null): boolean {\n if (typeof token !== 'string') {\n return true;\n }\n\n const [, payload] = token.split('.');\n\n if (!payload) {\n return true;\n }\n\n let exp: number;\n try {\n exp = JSON.parse(Base64.decode(payload)).exp;\n } catch (error: unknown) {\n console.error('Invalid token:', error, token);\n return true;\n }\n\n if (!exp || !isNumber(exp)) {\n return true;\n }\n // Report as expire before (real expire time - 30s)\n const jsTimestamp = exp * 1000 - 30000;\n const expired = Date.now() >= jsTimestamp;\n\n return expired;\n}\n"],"mappings":";;;;AAGA,SAAgB,cAAc,OAA+B;AAC3D,KAAI,OAAO,UAAU,SACnB,QAAO;CAGT,MAAM,GAAG,WAAW,MAAM,MAAM,IAAI;AAEpC,KAAI,CAAC,QACH,QAAO;CAGT,IAAI;AACJ,KAAI;AACF,QAAM,KAAK,MAAM,UAAA,OAAO,OAAO,QAAQ,CAAC,CAAC;UAClC,OAAgB;AACvB,UAAQ,MAAM,kBAAkB,OAAO,MAAM;AAC7C,SAAO;;AAGT,KAAI,CAAC,OAAO,EAAA,GAAA,UAAA,UAAU,IAAI,CACxB,QAAO;CAGT,MAAM,cAAc,MAAM,MAAO;AAGjC,QAFgB,KAAK,KAAK,IAAI"}
@@ -1,9 +1,8 @@
1
- import isString from "lodash/isString";
2
1
  import { Base64 } from "js-base64";
3
- import isNumber from "lodash/isNumber";
2
+ import { isNumber } from "lodash-es";
4
3
  //#region src/utils/token.ts
5
4
  function isTokenExpire(token) {
6
- if (!isString(token)) return true;
5
+ if (typeof token !== "string") return true;
7
6
  const [, payload] = token.split(".");
8
7
  if (!payload) return true;
9
8
  let exp;
@@ -1 +1 @@
1
- {"version":3,"file":"token.mjs","names":[],"sources":["../../src/utils/token.ts"],"sourcesContent":["import { Base64 } from 'js-base64';\nimport isNumber from 'lodash/isNumber';\nimport isString from 'lodash/isString';\n\nexport function isTokenExpire(token: string | null): boolean {\n if (!isString(token)) {\n return true;\n }\n\n const [, payload] = token.split('.');\n\n if (!payload) {\n return true;\n }\n\n let exp: number;\n try {\n exp = JSON.parse(Base64.decode(payload)).exp;\n } catch (error: unknown) {\n console.error('Invalid token:', error, token);\n return true;\n }\n\n if (!exp || !isNumber(exp)) {\n return true;\n }\n // Report as expire before (real expire time - 30s)\n const jsTimestamp = exp * 1000 - 30000;\n const expired = Date.now() >= jsTimestamp;\n\n return expired;\n}\n"],"mappings":";;;;AAIA,SAAgB,cAAc,OAA+B;AAC3D,KAAI,CAAC,SAAS,MAAM,CAClB,QAAO;CAGT,MAAM,GAAG,WAAW,MAAM,MAAM,IAAI;AAEpC,KAAI,CAAC,QACH,QAAO;CAGT,IAAI;AACJ,KAAI;AACF,QAAM,KAAK,MAAM,OAAO,OAAO,QAAQ,CAAC,CAAC;UAClC,OAAgB;AACvB,UAAQ,MAAM,kBAAkB,OAAO,MAAM;AAC7C,SAAO;;AAGT,KAAI,CAAC,OAAO,CAAC,SAAS,IAAI,CACxB,QAAO;CAGT,MAAM,cAAc,MAAM,MAAO;AAGjC,QAFgB,KAAK,KAAK,IAAI"}
1
+ {"version":3,"file":"token.mjs","names":[],"sources":["../../src/utils/token.ts"],"sourcesContent":["import { Base64 } from 'js-base64';\nimport { isNumber } from 'lodash-es';\n\nexport function isTokenExpire(token: string | null): boolean {\n if (typeof token !== 'string') {\n return true;\n }\n\n const [, payload] = token.split('.');\n\n if (!payload) {\n return true;\n }\n\n let exp: number;\n try {\n exp = JSON.parse(Base64.decode(payload)).exp;\n } catch (error: unknown) {\n console.error('Invalid token:', error, token);\n return true;\n }\n\n if (!exp || !isNumber(exp)) {\n return true;\n }\n // Report as expire before (real expire time - 30s)\n const jsTimestamp = exp * 1000 - 30000;\n const expired = Date.now() >= jsTimestamp;\n\n return expired;\n}\n"],"mappings":";;;AAGA,SAAgB,cAAc,OAA+B;AAC3D,KAAI,OAAO,UAAU,SACnB,QAAO;CAGT,MAAM,GAAG,WAAW,MAAM,MAAM,IAAI;AAEpC,KAAI,CAAC,QACH,QAAO;CAGT,IAAI;AACJ,KAAI;AACF,QAAM,KAAK,MAAM,OAAO,OAAO,QAAQ,CAAC,CAAC;UAClC,OAAgB;AACvB,UAAQ,MAAM,kBAAkB,OAAO,MAAM;AAC7C,SAAO;;AAGT,KAAI,CAAC,OAAO,CAAC,SAAS,IAAI,CACxB,QAAO;CAGT,MAAM,cAAc,MAAM,MAAO;AAGjC,QAFgB,KAAK,KAAK,IAAI"}
@@ -7,8 +7,6 @@ let dayjs_plugin_relativeTime = require("dayjs/plugin/relativeTime");
7
7
  dayjs_plugin_relativeTime = require_runtime.__toESM(dayjs_plugin_relativeTime);
8
8
  let i18next = require("i18next");
9
9
  i18next = require_runtime.__toESM(i18next);
10
- let lodash_isString = require("lodash/isString");
11
- lodash_isString = require_runtime.__toESM(lodash_isString);
12
10
  //#region src/utils/utils.ts
13
11
  var utils_exports = /* @__PURE__ */ require_runtime.__exportAll({
14
12
  TIMEFORMAT: () => TIMEFORMAT,
@@ -30,7 +28,7 @@ dayjs.default.extend(dayjs_plugin_localizedFormat.default);
30
28
  * @see https://docs.npmjs.com/files/package.json#license
31
29
  */
32
30
  function formatLicense(license) {
33
- if ((0, lodash_isString.default)(license)) return license;
31
+ if (typeof license === "string") return license;
34
32
  if (license && typeof license === "object" && "type" in license && typeof license.type === "string") return license.type;
35
33
  }
36
34
  /**
@@ -38,7 +36,7 @@ function formatLicense(license) {
38
36
  * @see https://docs.npmjs.com/files/package.json#repository
39
37
  */
40
38
  function formatRepository(repository) {
41
- if ((0, lodash_isString.default)(repository)) return repository;
39
+ if (typeof repository === "string") return repository;
42
40
  if (repository && typeof repository === "object" && "url" in repository && typeof repository.url === "string") return repository.url;
43
41
  return null;
44
42
  }
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":[],"sources":["../../src/utils/utils.ts"],"sourcesContent":["import dayjs from 'dayjs';\nimport localizedFormat from 'dayjs/plugin/localizedFormat';\nimport relativeTime from 'dayjs/plugin/relativeTime';\nimport i18next from 'i18next';\nimport isString from 'lodash/isString';\n\nimport type { UpLinks } from '@verdaccio/types';\n\nimport type { Time } from '../types/packageMeta';\n\nexport const TIMEFORMAT = 'L LTS';\n\ndayjs.extend(relativeTime);\ndayjs.extend(localizedFormat);\n\n/**\n * Formats license field for webui.\n * @see https://docs.npmjs.com/files/package.json#license\n */\nexport function formatLicense(license: string | { type?: string } | unknown): string | undefined {\n if (isString(license)) {\n return license;\n }\n\n if (\n license &&\n typeof license === 'object' &&\n 'type' in license &&\n typeof license.type === 'string'\n ) {\n return license.type;\n }\n\n return undefined;\n}\n\nexport interface Repository {\n readonly type: string;\n readonly url: string;\n}\n\n/**\n * Formats repository field for webui.\n * @see https://docs.npmjs.com/files/package.json#repository\n */\nexport function formatRepository(repository: string | { url?: string } | unknown): string | null {\n if (isString(repository)) {\n return repository;\n }\n\n if (\n repository &&\n typeof repository === 'object' &&\n 'url' in repository &&\n typeof repository.url === 'string'\n ) {\n return repository.url;\n }\n\n return null;\n}\n\nexport function formatDate(lastUpdate: string | number): string {\n return dayjs(new Date(lastUpdate)).format(TIMEFORMAT);\n}\n\nexport function formatDateDistance(lastUpdate: Date | string | number): string {\n return dayjs(new Date(lastUpdate)).fromNow();\n}\n\n/**\n * For <LastSync /> component\n * @param {array} uplinks\n */\nexport function getLastUpdatedPackageTime(uplinks: UpLinks = {}): string {\n let lastUpdate = 0;\n Object.keys(uplinks).forEach(function computeUplink(upLinkName): void {\n const status = uplinks[upLinkName];\n if (status.fetched > lastUpdate) {\n lastUpdate = status.fetched;\n }\n });\n\n return lastUpdate ? formatDate(lastUpdate) : '';\n}\n\n/**\n * For <LastSync /> component\n * @param {Object} time\n * @returns {Array} last 3 releases\n */\nexport function getRecentReleases(time: Time = {}): Time[] {\n const recent = Object.keys(time).map((version) => ({\n version,\n time: formatDate(time[version]),\n }));\n\n return recent.slice(recent.length - 3, recent.length).reverse();\n}\n\nexport function getAuthorName(authorName?: string): string {\n if (!authorName) {\n return i18next.t('author-unknown');\n }\n\n if (authorName.toLowerCase() === 'anonymous') {\n return i18next.t('author-anonymous');\n }\n\n return authorName;\n}\n\nexport function getUplink(upLinkName: string, packageName: string): string | null {\n // TODO: make this a config like \"uplinks: npmjs: web: https://www.npmjs.com/package/\"\n switch (upLinkName) {\n case 'npmjs':\n return `https://www.npmjs.com/package/${packageName}`;\n }\n return null;\n}\n\nexport function fileSizeSI(\n a: number,\n b?: typeof Math,\n c?: (p: number) => number,\n d?: number,\n e?: number\n): string {\n b = Math;\n c = b.log;\n d = 1e3;\n e = (c(a) / c(d)) | 0;\n const size = a / b.pow(d, e);\n // no decimals for Bytes\n if (e === 0) {\n return Math.floor(size) + ' Bytes';\n } else {\n return size.toFixed(1) + ' ' + 'kMGTPEZY'[--e] + 'B';\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAUA,IAAa,aAAa;AAE1B,MAAA,QAAM,OAAO,0BAAA,QAAa;AAC1B,MAAA,QAAM,OAAO,6BAAA,QAAgB;;;;;AAM7B,SAAgB,cAAc,SAAmE;AAC/F,MAAA,GAAA,gBAAA,SAAa,QAAQ,CACnB,QAAO;AAGT,KACE,WACA,OAAO,YAAY,YACnB,UAAU,WACV,OAAO,QAAQ,SAAS,SAExB,QAAO,QAAQ;;;;;;AAenB,SAAgB,iBAAiB,YAAgE;AAC/F,MAAA,GAAA,gBAAA,SAAa,WAAW,CACtB,QAAO;AAGT,KACE,cACA,OAAO,eAAe,YACtB,SAAS,cACT,OAAO,WAAW,QAAQ,SAE1B,QAAO,WAAW;AAGpB,QAAO;;AAGT,SAAgB,WAAW,YAAqC;AAC9D,SAAA,GAAA,MAAA,SAAa,IAAI,KAAK,WAAW,CAAC,CAAC,OAAO,WAAW;;AAGvD,SAAgB,mBAAmB,YAA4C;AAC7E,SAAA,GAAA,MAAA,SAAa,IAAI,KAAK,WAAW,CAAC,CAAC,SAAS;;;;;;AAO9C,SAAgB,0BAA0B,UAAmB,EAAE,EAAU;CACvE,IAAI,aAAa;AACjB,QAAO,KAAK,QAAQ,CAAC,QAAQ,SAAS,cAAc,YAAkB;EACpE,MAAM,SAAS,QAAQ;AACvB,MAAI,OAAO,UAAU,WACnB,cAAa,OAAO;GAEtB;AAEF,QAAO,aAAa,WAAW,WAAW,GAAG;;;;;;;AAQ/C,SAAgB,kBAAkB,OAAa,EAAE,EAAU;CACzD,MAAM,SAAS,OAAO,KAAK,KAAK,CAAC,KAAK,aAAa;EACjD;EACA,MAAM,WAAW,KAAK,SAAS;EAChC,EAAE;AAEH,QAAO,OAAO,MAAM,OAAO,SAAS,GAAG,OAAO,OAAO,CAAC,SAAS;;AAGjE,SAAgB,cAAc,YAA6B;AACzD,KAAI,CAAC,WACH,QAAO,QAAA,QAAQ,EAAE,iBAAiB;AAGpC,KAAI,WAAW,aAAa,KAAK,YAC/B,QAAO,QAAA,QAAQ,EAAE,mBAAmB;AAGtC,QAAO;;AAGT,SAAgB,UAAU,YAAoB,aAAoC;AAEhF,SAAQ,YAAR;EACE,KAAK,QACH,QAAO,iCAAiC;;AAE5C,QAAO;;AAGT,SAAgB,WACd,GACA,GACA,GACA,GACA,GACQ;AACR,KAAI;AACJ,KAAI,EAAE;AACN,KAAI;AACJ,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,GAAI;CACpB,MAAM,OAAO,IAAI,EAAE,IAAI,GAAG,EAAE;AAE5B,KAAI,MAAM,EACR,QAAO,KAAK,MAAM,KAAK,GAAG;KAE1B,QAAO,KAAK,QAAQ,EAAE,GAAG,MAAM,WAAW,EAAE,KAAK"}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../src/utils/utils.ts"],"sourcesContent":["import dayjs from 'dayjs';\nimport localizedFormat from 'dayjs/plugin/localizedFormat';\nimport relativeTime from 'dayjs/plugin/relativeTime';\nimport i18next from 'i18next';\n\nimport type { UpLinks } from '@verdaccio/types';\n\nimport type { Time } from '../types/packageMeta';\n\nexport const TIMEFORMAT = 'L LTS';\n\ndayjs.extend(relativeTime);\ndayjs.extend(localizedFormat);\n\n/**\n * Formats license field for webui.\n * @see https://docs.npmjs.com/files/package.json#license\n */\nexport function formatLicense(license: string | { type?: string } | unknown): string | undefined {\n if (typeof license === 'string') {\n return license;\n }\n\n if (\n license &&\n typeof license === 'object' &&\n 'type' in license &&\n typeof license.type === 'string'\n ) {\n return license.type;\n }\n\n return undefined;\n}\n\nexport interface Repository {\n readonly type: string;\n readonly url: string;\n}\n\n/**\n * Formats repository field for webui.\n * @see https://docs.npmjs.com/files/package.json#repository\n */\nexport function formatRepository(repository: string | { url?: string } | unknown): string | null {\n if (typeof repository === 'string') {\n return repository;\n }\n\n if (\n repository &&\n typeof repository === 'object' &&\n 'url' in repository &&\n typeof repository.url === 'string'\n ) {\n return repository.url;\n }\n\n return null;\n}\n\nexport function formatDate(lastUpdate: string | number): string {\n return dayjs(new Date(lastUpdate)).format(TIMEFORMAT);\n}\n\nexport function formatDateDistance(lastUpdate: Date | string | number): string {\n return dayjs(new Date(lastUpdate)).fromNow();\n}\n\n/**\n * For <LastSync /> component\n * @param {array} uplinks\n */\nexport function getLastUpdatedPackageTime(uplinks: UpLinks = {}): string {\n let lastUpdate = 0;\n Object.keys(uplinks).forEach(function computeUplink(upLinkName): void {\n const status = uplinks[upLinkName];\n if (status.fetched > lastUpdate) {\n lastUpdate = status.fetched;\n }\n });\n\n return lastUpdate ? formatDate(lastUpdate) : '';\n}\n\n/**\n * For <LastSync /> component\n * @param {Object} time\n * @returns {Array} last 3 releases\n */\nexport function getRecentReleases(time: Time = {}): Time[] {\n const recent = Object.keys(time).map((version) => ({\n version,\n time: formatDate(time[version]),\n }));\n\n return recent.slice(recent.length - 3, recent.length).reverse();\n}\n\nexport function getAuthorName(authorName?: string): string {\n if (!authorName) {\n return i18next.t('author-unknown');\n }\n\n if (authorName.toLowerCase() === 'anonymous') {\n return i18next.t('author-anonymous');\n }\n\n return authorName;\n}\n\nexport function getUplink(upLinkName: string, packageName: string): string | null {\n // TODO: make this a config like \"uplinks: npmjs: web: https://www.npmjs.com/package/\"\n switch (upLinkName) {\n case 'npmjs':\n return `https://www.npmjs.com/package/${packageName}`;\n }\n return null;\n}\n\nexport function fileSizeSI(\n a: number,\n b?: typeof Math,\n c?: (p: number) => number,\n d?: number,\n e?: number\n): string {\n b = Math;\n c = b.log;\n d = 1e3;\n e = (c(a) / c(d)) | 0;\n const size = a / b.pow(d, e);\n // no decimals for Bytes\n if (e === 0) {\n return Math.floor(size) + ' Bytes';\n } else {\n return size.toFixed(1) + ' ' + 'kMGTPEZY'[--e] + 'B';\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AASA,IAAa,aAAa;AAE1B,MAAA,QAAM,OAAO,0BAAA,QAAa;AAC1B,MAAA,QAAM,OAAO,6BAAA,QAAgB;;;;;AAM7B,SAAgB,cAAc,SAAmE;AAC/F,KAAI,OAAO,YAAY,SACrB,QAAO;AAGT,KACE,WACA,OAAO,YAAY,YACnB,UAAU,WACV,OAAO,QAAQ,SAAS,SAExB,QAAO,QAAQ;;;;;;AAenB,SAAgB,iBAAiB,YAAgE;AAC/F,KAAI,OAAO,eAAe,SACxB,QAAO;AAGT,KACE,cACA,OAAO,eAAe,YACtB,SAAS,cACT,OAAO,WAAW,QAAQ,SAE1B,QAAO,WAAW;AAGpB,QAAO;;AAGT,SAAgB,WAAW,YAAqC;AAC9D,SAAA,GAAA,MAAA,SAAa,IAAI,KAAK,WAAW,CAAC,CAAC,OAAO,WAAW;;AAGvD,SAAgB,mBAAmB,YAA4C;AAC7E,SAAA,GAAA,MAAA,SAAa,IAAI,KAAK,WAAW,CAAC,CAAC,SAAS;;;;;;AAO9C,SAAgB,0BAA0B,UAAmB,EAAE,EAAU;CACvE,IAAI,aAAa;AACjB,QAAO,KAAK,QAAQ,CAAC,QAAQ,SAAS,cAAc,YAAkB;EACpE,MAAM,SAAS,QAAQ;AACvB,MAAI,OAAO,UAAU,WACnB,cAAa,OAAO;GAEtB;AAEF,QAAO,aAAa,WAAW,WAAW,GAAG;;;;;;;AAQ/C,SAAgB,kBAAkB,OAAa,EAAE,EAAU;CACzD,MAAM,SAAS,OAAO,KAAK,KAAK,CAAC,KAAK,aAAa;EACjD;EACA,MAAM,WAAW,KAAK,SAAS;EAChC,EAAE;AAEH,QAAO,OAAO,MAAM,OAAO,SAAS,GAAG,OAAO,OAAO,CAAC,SAAS;;AAGjE,SAAgB,cAAc,YAA6B;AACzD,KAAI,CAAC,WACH,QAAO,QAAA,QAAQ,EAAE,iBAAiB;AAGpC,KAAI,WAAW,aAAa,KAAK,YAC/B,QAAO,QAAA,QAAQ,EAAE,mBAAmB;AAGtC,QAAO;;AAGT,SAAgB,UAAU,YAAoB,aAAoC;AAEhF,SAAQ,YAAR;EACE,KAAK,QACH,QAAO,iCAAiC;;AAE5C,QAAO;;AAGT,SAAgB,WACd,GACA,GACA,GACA,GACA,GACQ;AACR,KAAI;AACJ,KAAI,EAAE;AACN,KAAI;AACJ,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,GAAI;CACpB,MAAM,OAAO,IAAI,EAAE,IAAI,GAAG,EAAE;AAE5B,KAAI,MAAM,EACR,QAAO,KAAK,MAAM,KAAK,GAAG;KAE1B,QAAO,KAAK,QAAQ,EAAE,GAAG,MAAM,WAAW,EAAE,KAAK"}
@@ -3,7 +3,6 @@ import dayjs from "dayjs";
3
3
  import localizedFormat from "dayjs/plugin/localizedFormat";
4
4
  import relativeTime from "dayjs/plugin/relativeTime";
5
5
  import i18next from "i18next";
6
- import isString from "lodash/isString";
7
6
  //#region src/utils/utils.ts
8
7
  var utils_exports = /* @__PURE__ */ __exportAll({
9
8
  TIMEFORMAT: () => TIMEFORMAT,
@@ -25,7 +24,7 @@ dayjs.extend(localizedFormat);
25
24
  * @see https://docs.npmjs.com/files/package.json#license
26
25
  */
27
26
  function formatLicense(license) {
28
- if (isString(license)) return license;
27
+ if (typeof license === "string") return license;
29
28
  if (license && typeof license === "object" && "type" in license && typeof license.type === "string") return license.type;
30
29
  }
31
30
  /**
@@ -33,7 +32,7 @@ function formatLicense(license) {
33
32
  * @see https://docs.npmjs.com/files/package.json#repository
34
33
  */
35
34
  function formatRepository(repository) {
36
- if (isString(repository)) return repository;
35
+ if (typeof repository === "string") return repository;
37
36
  if (repository && typeof repository === "object" && "url" in repository && typeof repository.url === "string") return repository.url;
38
37
  return null;
39
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"utils.mjs","names":[],"sources":["../../src/utils/utils.ts"],"sourcesContent":["import dayjs from 'dayjs';\nimport localizedFormat from 'dayjs/plugin/localizedFormat';\nimport relativeTime from 'dayjs/plugin/relativeTime';\nimport i18next from 'i18next';\nimport isString from 'lodash/isString';\n\nimport type { UpLinks } from '@verdaccio/types';\n\nimport type { Time } from '../types/packageMeta';\n\nexport const TIMEFORMAT = 'L LTS';\n\ndayjs.extend(relativeTime);\ndayjs.extend(localizedFormat);\n\n/**\n * Formats license field for webui.\n * @see https://docs.npmjs.com/files/package.json#license\n */\nexport function formatLicense(license: string | { type?: string } | unknown): string | undefined {\n if (isString(license)) {\n return license;\n }\n\n if (\n license &&\n typeof license === 'object' &&\n 'type' in license &&\n typeof license.type === 'string'\n ) {\n return license.type;\n }\n\n return undefined;\n}\n\nexport interface Repository {\n readonly type: string;\n readonly url: string;\n}\n\n/**\n * Formats repository field for webui.\n * @see https://docs.npmjs.com/files/package.json#repository\n */\nexport function formatRepository(repository: string | { url?: string } | unknown): string | null {\n if (isString(repository)) {\n return repository;\n }\n\n if (\n repository &&\n typeof repository === 'object' &&\n 'url' in repository &&\n typeof repository.url === 'string'\n ) {\n return repository.url;\n }\n\n return null;\n}\n\nexport function formatDate(lastUpdate: string | number): string {\n return dayjs(new Date(lastUpdate)).format(TIMEFORMAT);\n}\n\nexport function formatDateDistance(lastUpdate: Date | string | number): string {\n return dayjs(new Date(lastUpdate)).fromNow();\n}\n\n/**\n * For <LastSync /> component\n * @param {array} uplinks\n */\nexport function getLastUpdatedPackageTime(uplinks: UpLinks = {}): string {\n let lastUpdate = 0;\n Object.keys(uplinks).forEach(function computeUplink(upLinkName): void {\n const status = uplinks[upLinkName];\n if (status.fetched > lastUpdate) {\n lastUpdate = status.fetched;\n }\n });\n\n return lastUpdate ? formatDate(lastUpdate) : '';\n}\n\n/**\n * For <LastSync /> component\n * @param {Object} time\n * @returns {Array} last 3 releases\n */\nexport function getRecentReleases(time: Time = {}): Time[] {\n const recent = Object.keys(time).map((version) => ({\n version,\n time: formatDate(time[version]),\n }));\n\n return recent.slice(recent.length - 3, recent.length).reverse();\n}\n\nexport function getAuthorName(authorName?: string): string {\n if (!authorName) {\n return i18next.t('author-unknown');\n }\n\n if (authorName.toLowerCase() === 'anonymous') {\n return i18next.t('author-anonymous');\n }\n\n return authorName;\n}\n\nexport function getUplink(upLinkName: string, packageName: string): string | null {\n // TODO: make this a config like \"uplinks: npmjs: web: https://www.npmjs.com/package/\"\n switch (upLinkName) {\n case 'npmjs':\n return `https://www.npmjs.com/package/${packageName}`;\n }\n return null;\n}\n\nexport function fileSizeSI(\n a: number,\n b?: typeof Math,\n c?: (p: number) => number,\n d?: number,\n e?: number\n): string {\n b = Math;\n c = b.log;\n d = 1e3;\n e = (c(a) / c(d)) | 0;\n const size = a / b.pow(d, e);\n // no decimals for Bytes\n if (e === 0) {\n return Math.floor(size) + ' Bytes';\n } else {\n return size.toFixed(1) + ' ' + 'kMGTPEZY'[--e] + 'B';\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAUA,IAAa,aAAa;AAE1B,MAAM,OAAO,aAAa;AAC1B,MAAM,OAAO,gBAAgB;;;;;AAM7B,SAAgB,cAAc,SAAmE;AAC/F,KAAI,SAAS,QAAQ,CACnB,QAAO;AAGT,KACE,WACA,OAAO,YAAY,YACnB,UAAU,WACV,OAAO,QAAQ,SAAS,SAExB,QAAO,QAAQ;;;;;;AAenB,SAAgB,iBAAiB,YAAgE;AAC/F,KAAI,SAAS,WAAW,CACtB,QAAO;AAGT,KACE,cACA,OAAO,eAAe,YACtB,SAAS,cACT,OAAO,WAAW,QAAQ,SAE1B,QAAO,WAAW;AAGpB,QAAO;;AAGT,SAAgB,WAAW,YAAqC;AAC9D,QAAO,MAAM,IAAI,KAAK,WAAW,CAAC,CAAC,OAAO,WAAW;;AAGvD,SAAgB,mBAAmB,YAA4C;AAC7E,QAAO,MAAM,IAAI,KAAK,WAAW,CAAC,CAAC,SAAS;;;;;;AAO9C,SAAgB,0BAA0B,UAAmB,EAAE,EAAU;CACvE,IAAI,aAAa;AACjB,QAAO,KAAK,QAAQ,CAAC,QAAQ,SAAS,cAAc,YAAkB;EACpE,MAAM,SAAS,QAAQ;AACvB,MAAI,OAAO,UAAU,WACnB,cAAa,OAAO;GAEtB;AAEF,QAAO,aAAa,WAAW,WAAW,GAAG;;;;;;;AAQ/C,SAAgB,kBAAkB,OAAa,EAAE,EAAU;CACzD,MAAM,SAAS,OAAO,KAAK,KAAK,CAAC,KAAK,aAAa;EACjD;EACA,MAAM,WAAW,KAAK,SAAS;EAChC,EAAE;AAEH,QAAO,OAAO,MAAM,OAAO,SAAS,GAAG,OAAO,OAAO,CAAC,SAAS;;AAGjE,SAAgB,cAAc,YAA6B;AACzD,KAAI,CAAC,WACH,QAAO,QAAQ,EAAE,iBAAiB;AAGpC,KAAI,WAAW,aAAa,KAAK,YAC/B,QAAO,QAAQ,EAAE,mBAAmB;AAGtC,QAAO;;AAGT,SAAgB,UAAU,YAAoB,aAAoC;AAEhF,SAAQ,YAAR;EACE,KAAK,QACH,QAAO,iCAAiC;;AAE5C,QAAO;;AAGT,SAAgB,WACd,GACA,GACA,GACA,GACA,GACQ;AACR,KAAI;AACJ,KAAI,EAAE;AACN,KAAI;AACJ,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,GAAI;CACpB,MAAM,OAAO,IAAI,EAAE,IAAI,GAAG,EAAE;AAE5B,KAAI,MAAM,EACR,QAAO,KAAK,MAAM,KAAK,GAAG;KAE1B,QAAO,KAAK,QAAQ,EAAE,GAAG,MAAM,WAAW,EAAE,KAAK"}
1
+ {"version":3,"file":"utils.mjs","names":[],"sources":["../../src/utils/utils.ts"],"sourcesContent":["import dayjs from 'dayjs';\nimport localizedFormat from 'dayjs/plugin/localizedFormat';\nimport relativeTime from 'dayjs/plugin/relativeTime';\nimport i18next from 'i18next';\n\nimport type { UpLinks } from '@verdaccio/types';\n\nimport type { Time } from '../types/packageMeta';\n\nexport const TIMEFORMAT = 'L LTS';\n\ndayjs.extend(relativeTime);\ndayjs.extend(localizedFormat);\n\n/**\n * Formats license field for webui.\n * @see https://docs.npmjs.com/files/package.json#license\n */\nexport function formatLicense(license: string | { type?: string } | unknown): string | undefined {\n if (typeof license === 'string') {\n return license;\n }\n\n if (\n license &&\n typeof license === 'object' &&\n 'type' in license &&\n typeof license.type === 'string'\n ) {\n return license.type;\n }\n\n return undefined;\n}\n\nexport interface Repository {\n readonly type: string;\n readonly url: string;\n}\n\n/**\n * Formats repository field for webui.\n * @see https://docs.npmjs.com/files/package.json#repository\n */\nexport function formatRepository(repository: string | { url?: string } | unknown): string | null {\n if (typeof repository === 'string') {\n return repository;\n }\n\n if (\n repository &&\n typeof repository === 'object' &&\n 'url' in repository &&\n typeof repository.url === 'string'\n ) {\n return repository.url;\n }\n\n return null;\n}\n\nexport function formatDate(lastUpdate: string | number): string {\n return dayjs(new Date(lastUpdate)).format(TIMEFORMAT);\n}\n\nexport function formatDateDistance(lastUpdate: Date | string | number): string {\n return dayjs(new Date(lastUpdate)).fromNow();\n}\n\n/**\n * For <LastSync /> component\n * @param {array} uplinks\n */\nexport function getLastUpdatedPackageTime(uplinks: UpLinks = {}): string {\n let lastUpdate = 0;\n Object.keys(uplinks).forEach(function computeUplink(upLinkName): void {\n const status = uplinks[upLinkName];\n if (status.fetched > lastUpdate) {\n lastUpdate = status.fetched;\n }\n });\n\n return lastUpdate ? formatDate(lastUpdate) : '';\n}\n\n/**\n * For <LastSync /> component\n * @param {Object} time\n * @returns {Array} last 3 releases\n */\nexport function getRecentReleases(time: Time = {}): Time[] {\n const recent = Object.keys(time).map((version) => ({\n version,\n time: formatDate(time[version]),\n }));\n\n return recent.slice(recent.length - 3, recent.length).reverse();\n}\n\nexport function getAuthorName(authorName?: string): string {\n if (!authorName) {\n return i18next.t('author-unknown');\n }\n\n if (authorName.toLowerCase() === 'anonymous') {\n return i18next.t('author-anonymous');\n }\n\n return authorName;\n}\n\nexport function getUplink(upLinkName: string, packageName: string): string | null {\n // TODO: make this a config like \"uplinks: npmjs: web: https://www.npmjs.com/package/\"\n switch (upLinkName) {\n case 'npmjs':\n return `https://www.npmjs.com/package/${packageName}`;\n }\n return null;\n}\n\nexport function fileSizeSI(\n a: number,\n b?: typeof Math,\n c?: (p: number) => number,\n d?: number,\n e?: number\n): string {\n b = Math;\n c = b.log;\n d = 1e3;\n e = (c(a) / c(d)) | 0;\n const size = a / b.pow(d, e);\n // no decimals for Bytes\n if (e === 0) {\n return Math.floor(size) + ' Bytes';\n } else {\n return size.toFixed(1) + ' ' + 'kMGTPEZY'[--e] + 'B';\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AASA,IAAa,aAAa;AAE1B,MAAM,OAAO,aAAa;AAC1B,MAAM,OAAO,gBAAgB;;;;;AAM7B,SAAgB,cAAc,SAAmE;AAC/F,KAAI,OAAO,YAAY,SACrB,QAAO;AAGT,KACE,WACA,OAAO,YAAY,YACnB,UAAU,WACV,OAAO,QAAQ,SAAS,SAExB,QAAO,QAAQ;;;;;;AAenB,SAAgB,iBAAiB,YAAgE;AAC/F,KAAI,OAAO,eAAe,SACxB,QAAO;AAGT,KACE,cACA,OAAO,eAAe,YACtB,SAAS,cACT,OAAO,WAAW,QAAQ,SAE1B,QAAO,WAAW;AAGpB,QAAO;;AAGT,SAAgB,WAAW,YAAqC;AAC9D,QAAO,MAAM,IAAI,KAAK,WAAW,CAAC,CAAC,OAAO,WAAW;;AAGvD,SAAgB,mBAAmB,YAA4C;AAC7E,QAAO,MAAM,IAAI,KAAK,WAAW,CAAC,CAAC,SAAS;;;;;;AAO9C,SAAgB,0BAA0B,UAAmB,EAAE,EAAU;CACvE,IAAI,aAAa;AACjB,QAAO,KAAK,QAAQ,CAAC,QAAQ,SAAS,cAAc,YAAkB;EACpE,MAAM,SAAS,QAAQ;AACvB,MAAI,OAAO,UAAU,WACnB,cAAa,OAAO;GAEtB;AAEF,QAAO,aAAa,WAAW,WAAW,GAAG;;;;;;;AAQ/C,SAAgB,kBAAkB,OAAa,EAAE,EAAU;CACzD,MAAM,SAAS,OAAO,KAAK,KAAK,CAAC,KAAK,aAAa;EACjD;EACA,MAAM,WAAW,KAAK,SAAS;EAChC,EAAE;AAEH,QAAO,OAAO,MAAM,OAAO,SAAS,GAAG,OAAO,OAAO,CAAC,SAAS;;AAGjE,SAAgB,cAAc,YAA6B;AACzD,KAAI,CAAC,WACH,QAAO,QAAQ,EAAE,iBAAiB;AAGpC,KAAI,WAAW,aAAa,KAAK,YAC/B,QAAO,QAAQ,EAAE,mBAAmB;AAGtC,QAAO;;AAGT,SAAgB,UAAU,YAAoB,aAAoC;AAEhF,SAAQ,YAAR;EACE,KAAK,QACH,QAAO,iCAAiC;;AAE5C,QAAO;;AAGT,SAAgB,WACd,GACA,GACA,GACA,GACA,GACQ;AACR,KAAI;AACJ,KAAI,EAAE;AACN,KAAI;AACJ,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,GAAI;CACpB,MAAM,OAAO,IAAI,EAAE,IAAI,GAAG,EAAE;AAE5B,KAAI,MAAM,EACR,QAAO,KAAK,MAAM,KAAK,GAAG;KAE1B,QAAO,KAAK,QAAQ,EAAE,GAAG,MAAM,WAAW,EAAE,KAAK"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verdaccio/ui-components",
3
- "version": "5.0.0-next-9.6",
3
+ "version": "5.0.0-next-9.8",
4
4
  "description": "Verdaccio UI Components",
5
5
  "author": "Juan Picado <juanpicado19@gmail.com>",
6
6
  "license": "MIT",
@@ -36,7 +36,7 @@
36
36
  "i18next": "25.8.18",
37
37
  "js-base64": "3.7.8",
38
38
  "localstorage-memory": "1.0.3",
39
- "lodash": "4.17.23",
39
+ "lodash-es": "4.17.23",
40
40
  "marked": "17.0.4",
41
41
  "marked-highlight": "2.2.3",
42
42
  "normalize.css": "8.0.1",
@@ -59,10 +59,10 @@
59
59
  "@testing-library/dom": "10.4.1",
60
60
  "@testing-library/jest-dom": "6.9.1",
61
61
  "@testing-library/react": "16.3.2",
62
+ "@types/lodash-es": "4.17.12",
62
63
  "@types/node": "24.10.13",
63
- "@verdaccio/types": "14.0.0-next-9.4",
64
+ "@verdaccio/types": "14.0.0-next-9.5",
64
65
  "@vitejs/plugin-react": "6.0.1",
65
- "vite": "^8.0.0",
66
66
  "eslint-plugin-storybook": "10.2.17",
67
67
  "eslint-plugin-verdaccio": "10.0.0",
68
68
  "jsdom": "28.1.0",
@@ -71,6 +71,7 @@
71
71
  "msw-storybook-addon": "2.0.6",
72
72
  "mutationobserver-shim": "0.3.7",
73
73
  "storybook": "10.2.17",
74
+ "vite": "^8.0.0",
74
75
  "vitest": "4.1.0",
75
76
  "whatwg-fetch": "3.6.20"
76
77
  },