@verdaccio/ui-components 5.0.0-next-9.20 → 5.0.0-next-9.21

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 (274) hide show
  1. package/build/api/use-data-mutation.js +1 -4
  2. package/build/api/use-data-mutation.js.map +1 -1
  3. package/build/api/use-data-mutation.mjs +1 -4
  4. package/build/api/use-data-mutation.mjs.map +1 -1
  5. package/build/api/use-data.d.ts +1 -0
  6. package/build/api/use-data.js +3 -2
  7. package/build/api/use-data.js.map +1 -1
  8. package/build/api/use-data.mjs +3 -3
  9. package/build/api/use-data.mjs.map +1 -1
  10. package/build/components/ActionBar/ActionBar.js +4 -2
  11. package/build/components/ActionBar/ActionBar.js.map +1 -1
  12. package/build/components/ActionBar/ActionBar.mjs +4 -2
  13. package/build/components/ActionBar/ActionBar.mjs.map +1 -1
  14. package/build/components/ActionBar/ActionBarAction.js +1 -1
  15. package/build/components/ActionBar/ActionBarAction.mjs +1 -1
  16. package/build/components/Author/Author.js +1 -1
  17. package/build/components/Author/Author.mjs +1 -1
  18. package/build/components/CopyClipboard/CopyToClipBoard.js +5 -0
  19. package/build/components/CopyClipboard/CopyToClipBoard.js.map +1 -1
  20. package/build/components/CopyClipboard/CopyToClipBoard.mjs +5 -0
  21. package/build/components/CopyClipboard/CopyToClipBoard.mjs.map +1 -1
  22. package/build/components/CopyClipboard/utils.js +14 -1
  23. package/build/components/CopyClipboard/utils.js.map +1 -1
  24. package/build/components/CopyClipboard/utils.mjs +14 -1
  25. package/build/components/CopyClipboard/utils.mjs.map +1 -1
  26. package/build/components/Dependencies/Dependencies.js +2 -1
  27. package/build/components/Dependencies/Dependencies.js.map +1 -1
  28. package/build/components/Dependencies/Dependencies.mjs +2 -1
  29. package/build/components/Dependencies/Dependencies.mjs.map +1 -1
  30. package/build/components/Dependencies/DependencyBlock.js +1 -1
  31. package/build/components/Dependencies/DependencyBlock.mjs +1 -1
  32. package/build/components/Developers/Title.js +1 -1
  33. package/build/components/Developers/Title.mjs +1 -1
  34. package/build/components/Developers/get-unique-developer-values.js +2 -1
  35. package/build/components/Developers/get-unique-developer-values.js.map +1 -1
  36. package/build/components/Developers/get-unique-developer-values.mjs +2 -1
  37. package/build/components/Developers/get-unique-developer-values.mjs.map +1 -1
  38. package/build/components/Distribution/Dist.js +3 -3
  39. package/build/components/Distribution/Dist.js.map +1 -1
  40. package/build/components/Distribution/Dist.mjs +3 -3
  41. package/build/components/Distribution/Dist.mjs.map +1 -1
  42. package/build/components/Engines/Engines.js +1 -1
  43. package/build/components/Engines/Engines.mjs +1 -1
  44. package/build/components/Forbidden/Forbidden.js +1 -1
  45. package/build/components/Forbidden/Forbidden.mjs +1 -1
  46. package/build/components/FundButton/FundButton.js +4 -3
  47. package/build/components/FundButton/FundButton.js.map +1 -1
  48. package/build/components/FundButton/FundButton.mjs +4 -3
  49. package/build/components/FundButton/FundButton.mjs.map +1 -1
  50. package/build/components/GenericError/GenericError.d.ts +3 -0
  51. package/build/components/GenericError/GenericError.js +60 -0
  52. package/build/components/GenericError/GenericError.js.map +1 -0
  53. package/build/components/GenericError/GenericError.mjs +54 -0
  54. package/build/components/GenericError/GenericError.mjs.map +1 -0
  55. package/build/components/GenericError/index.d.ts +1 -0
  56. package/build/components/GenericError/index.js +2 -0
  57. package/build/components/GenericError/index.mjs +2 -0
  58. package/build/components/Help/Help.js +1 -1
  59. package/build/components/Help/Help.mjs +1 -1
  60. package/build/components/Install/Install.js +1 -1
  61. package/build/components/Install/Install.mjs +1 -1
  62. package/build/components/Install/InstallListItem.js +2 -2
  63. package/build/components/Install/InstallListItem.js.map +1 -1
  64. package/build/components/Install/InstallListItem.mjs +2 -2
  65. package/build/components/Install/InstallListItem.mjs.map +1 -1
  66. package/build/components/Keywords/KeywordListItems.js +1 -1
  67. package/build/components/Keywords/KeywordListItems.js.map +1 -1
  68. package/build/components/Keywords/KeywordListItems.mjs +1 -1
  69. package/build/components/Keywords/KeywordListItems.mjs.map +1 -1
  70. package/build/components/Keywords/Keywords.js +2 -2
  71. package/build/components/Keywords/Keywords.js.map +1 -1
  72. package/build/components/Keywords/Keywords.mjs +2 -2
  73. package/build/components/Keywords/Keywords.mjs.map +1 -1
  74. package/build/components/LoginDialog/LoginDialogCloseButton.js +1 -1
  75. package/build/components/LoginDialog/LoginDialogCloseButton.mjs +1 -1
  76. package/build/components/LoginDialog/LoginDialogForm.js +2 -1
  77. package/build/components/LoginDialog/LoginDialogForm.js.map +1 -1
  78. package/build/components/LoginDialog/LoginDialogForm.mjs +2 -1
  79. package/build/components/LoginDialog/LoginDialogForm.mjs.map +1 -1
  80. package/build/components/LoginForm/Login.d.ts +1 -0
  81. package/build/components/LoginForm/Login.js +6 -4
  82. package/build/components/LoginForm/Login.js.map +1 -1
  83. package/build/components/LoginForm/Login.mjs +9 -7
  84. package/build/components/LoginForm/Login.mjs.map +1 -1
  85. package/build/components/LoginForm/PasswordField.js +4 -6
  86. package/build/components/LoginForm/PasswordField.js.map +1 -1
  87. package/build/components/LoginForm/PasswordField.mjs +4 -6
  88. package/build/components/LoginForm/PasswordField.mjs.map +1 -1
  89. package/build/components/LoginForm/UsernameField.js +4 -6
  90. package/build/components/LoginForm/UsernameField.js.map +1 -1
  91. package/build/components/LoginForm/UsernameField.mjs +4 -6
  92. package/build/components/LoginForm/UsernameField.mjs.map +1 -1
  93. package/build/components/LoginForm/styles.js +1 -1
  94. package/build/components/LoginForm/styles.mjs +1 -1
  95. package/build/components/LoginForm/useLoginForm.js +13 -3
  96. package/build/components/LoginForm/useLoginForm.js.map +1 -1
  97. package/build/components/LoginForm/useLoginForm.mjs +14 -4
  98. package/build/components/LoginForm/useLoginForm.mjs.map +1 -1
  99. package/build/components/NoItems/NoItems.js +2 -2
  100. package/build/components/NoItems/NoItems.mjs +1 -1
  101. package/build/components/NotFound/NotFound.js +1 -1
  102. package/build/components/NotFound/NotFound.mjs +1 -1
  103. package/build/components/Package/Package.d.ts +1 -1
  104. package/build/components/Package/Package.js +28 -29
  105. package/build/components/Package/Package.js.map +1 -1
  106. package/build/components/Package/Package.mjs +29 -30
  107. package/build/components/Package/Package.mjs.map +1 -1
  108. package/build/components/Person/Person.js +1 -1
  109. package/build/components/Person/Person.js.map +1 -1
  110. package/build/components/Person/Person.mjs +1 -1
  111. package/build/components/Person/Person.mjs.map +1 -1
  112. package/build/components/RawViewer/RawViewer.js +1 -1
  113. package/build/components/RawViewer/RawViewer.mjs +1 -1
  114. package/build/components/RegistryInfoDialog/RegistryInfoDialog.js +1 -1
  115. package/build/components/RegistryInfoDialog/RegistryInfoDialog.mjs +1 -1
  116. package/build/components/Repository/Repository.js +5 -8
  117. package/build/components/Repository/Repository.js.map +1 -1
  118. package/build/components/Repository/Repository.mjs +5 -8
  119. package/build/components/Repository/Repository.mjs.map +1 -1
  120. package/build/components/Search/AutoComplete/AutoComplete.d.ts +1 -0
  121. package/build/components/Search/AutoComplete/AutoComplete.js +4 -4
  122. package/build/components/Search/AutoComplete/AutoComplete.js.map +1 -1
  123. package/build/components/Search/AutoComplete/AutoComplete.mjs +4 -4
  124. package/build/components/Search/AutoComplete/AutoComplete.mjs.map +1 -1
  125. package/build/components/Search/Search.js +12 -4
  126. package/build/components/Search/Search.js.map +1 -1
  127. package/build/components/Search/Search.mjs +13 -5
  128. package/build/components/Search/Search.mjs.map +1 -1
  129. package/build/components/Search/SearchItem.js +1 -1
  130. package/build/components/Search/SearchItem.mjs +1 -1
  131. package/build/components/SettingsMenu/SettingsMenu.js +1 -1
  132. package/build/components/SettingsMenu/SettingsMenu.mjs +1 -1
  133. package/build/components/SideBarTitle/SideBarTitle.js +2 -2
  134. package/build/components/SideBarTitle/SideBarTitle.js.map +1 -1
  135. package/build/components/SideBarTitle/SideBarTitle.mjs +2 -2
  136. package/build/components/SideBarTitle/SideBarTitle.mjs.map +1 -1
  137. package/build/components/UpLinks/UpLinks.js +1 -1
  138. package/build/components/UpLinks/UpLinks.mjs +1 -1
  139. package/build/components/Versions/HistoryList.js +2 -2
  140. package/build/components/Versions/HistoryList.js.map +1 -1
  141. package/build/components/Versions/HistoryList.mjs +2 -2
  142. package/build/components/Versions/HistoryList.mjs.map +1 -1
  143. package/build/components/Versions/Versions.js +22 -21
  144. package/build/components/Versions/Versions.js.map +1 -1
  145. package/build/components/Versions/Versions.mjs +22 -21
  146. package/build/components/Versions/Versions.mjs.map +1 -1
  147. package/build/index.d.ts +1 -0
  148. package/build/index.js +4 -0
  149. package/build/index.mjs +4 -2
  150. package/build/pages/Version/Version.js +4 -1
  151. package/build/pages/Version/Version.js.map +1 -1
  152. package/build/pages/Version/Version.mjs +4 -1
  153. package/build/pages/Version/Version.mjs.map +1 -1
  154. package/build/providers/AuthProvider/AuthProvider.js +9 -7
  155. package/build/providers/AuthProvider/AuthProvider.js.map +1 -1
  156. package/build/providers/AuthProvider/AuthProvider.mjs +10 -8
  157. package/build/providers/AuthProvider/AuthProvider.mjs.map +1 -1
  158. package/build/providers/AuthProvider/utils.d.ts +12 -0
  159. package/build/providers/AuthProvider/utils.js +22 -0
  160. package/build/providers/AuthProvider/utils.js.map +1 -1
  161. package/build/providers/AuthProvider/utils.mjs +21 -2
  162. package/build/providers/AuthProvider/utils.mjs.map +1 -1
  163. package/build/providers/DownloadProvider/DownloadProvider.d.ts +1 -0
  164. package/build/providers/DownloadProvider/DownloadProvider.js +27 -4
  165. package/build/providers/DownloadProvider/DownloadProvider.js.map +1 -1
  166. package/build/providers/DownloadProvider/DownloadProvider.mjs +27 -6
  167. package/build/providers/DownloadProvider/DownloadProvider.mjs.map +1 -1
  168. package/build/providers/ManifestsProvider/ManifestsProvider.js +1 -1
  169. package/build/providers/ManifestsProvider/ManifestsProvider.js.map +1 -1
  170. package/build/providers/ManifestsProvider/ManifestsProvider.mjs +1 -1
  171. package/build/providers/ManifestsProvider/ManifestsProvider.mjs.map +1 -1
  172. package/build/providers/SearchProvider/SearchProvider.d.ts +1 -0
  173. package/build/providers/SearchProvider/SearchProvider.js +8 -6
  174. package/build/providers/SearchProvider/SearchProvider.js.map +1 -1
  175. package/build/providers/SearchProvider/SearchProvider.mjs +8 -6
  176. package/build/providers/SearchProvider/SearchProvider.mjs.map +1 -1
  177. package/build/providers/TranslatorProvider/TranslatorProvider.js +5 -3
  178. package/build/providers/TranslatorProvider/TranslatorProvider.js.map +1 -1
  179. package/build/providers/TranslatorProvider/TranslatorProvider.mjs +5 -3
  180. package/build/providers/TranslatorProvider/TranslatorProvider.mjs.map +1 -1
  181. package/build/providers/VersionProvider/VersionProvider.js +3 -3
  182. package/build/providers/VersionProvider/VersionProvider.js.map +1 -1
  183. package/build/providers/VersionProvider/VersionProvider.mjs +3 -3
  184. package/build/providers/VersionProvider/VersionProvider.mjs.map +1 -1
  185. package/build/sections/Detail/Tabs.js +1 -1
  186. package/build/sections/Detail/Tabs.mjs +1 -1
  187. package/build/sections/Footer/Footer.js +1 -1
  188. package/build/sections/Footer/Footer.mjs +1 -1
  189. package/build/sections/Header/Header.d.ts +0 -1
  190. package/build/sections/Header/Header.js +16 -14
  191. package/build/sections/Header/Header.js.map +1 -1
  192. package/build/sections/Header/Header.mjs +17 -15
  193. package/build/sections/Header/Header.mjs.map +1 -1
  194. package/build/sections/Header/HeaderGreetings.js +1 -1
  195. package/build/sections/Header/HeaderGreetings.mjs +1 -1
  196. package/build/sections/Header/HeaderMenu.js +1 -1
  197. package/build/sections/Header/HeaderMenu.mjs +1 -1
  198. package/build/sections/Header/HeaderRight.js +1 -1
  199. package/build/sections/Header/HeaderRight.mjs +1 -1
  200. package/build/sections/Header/HeaderSettingsDialog.js +1 -1
  201. package/build/sections/Header/HeaderSettingsDialog.mjs +1 -1
  202. package/build/sections/Header/LanguageSwitch.js +1 -1
  203. package/build/sections/Header/LanguageSwitch.mjs +1 -1
  204. package/build/sections/Header/RegistryInfoContent/RegistryInfoContent.js +1 -1
  205. package/build/sections/Header/RegistryInfoContent/RegistryInfoContent.mjs +1 -1
  206. package/build/sections/Home/Home.js +4 -3
  207. package/build/sections/Home/Home.js.map +1 -1
  208. package/build/sections/Home/Home.mjs +5 -4
  209. package/build/sections/Home/Home.mjs.map +1 -1
  210. package/build/sections/Security/AddUser.js +33 -18
  211. package/build/sections/Security/AddUser.js.map +1 -1
  212. package/build/sections/Security/AddUser.mjs +37 -22
  213. package/build/sections/Security/AddUser.mjs.map +1 -1
  214. package/build/sections/Security/ChangePassword.js +17 -15
  215. package/build/sections/Security/ChangePassword.js.map +1 -1
  216. package/build/sections/Security/ChangePassword.mjs +19 -17
  217. package/build/sections/Security/ChangePassword.mjs.map +1 -1
  218. package/build/sections/Security/Login.js +51 -35
  219. package/build/sections/Security/Login.js.map +1 -1
  220. package/build/sections/Security/Login.mjs +54 -38
  221. package/build/sections/Security/Login.mjs.map +1 -1
  222. package/build/sections/Security/Success.js +28 -24
  223. package/build/sections/Security/Success.js.map +1 -1
  224. package/build/sections/Security/Success.mjs +29 -25
  225. package/build/sections/Security/Success.mjs.map +1 -1
  226. package/build/sections/Stage/StageActions.js +1 -1
  227. package/build/sections/Stage/StageActions.mjs +1 -1
  228. package/build/sections/Stage/StageDetail.js +1 -1
  229. package/build/sections/Stage/StageDetail.mjs +1 -1
  230. package/build/sections/Stage/StageList.js +15 -2
  231. package/build/sections/Stage/StageList.js.map +1 -1
  232. package/build/sections/Stage/StageList.mjs +15 -2
  233. package/build/sections/Stage/StageList.mjs.map +1 -1
  234. package/build/store/api.js +7 -4
  235. package/build/store/api.js.map +1 -1
  236. package/build/store/api.mjs +7 -4
  237. package/build/store/api.mjs.map +1 -1
  238. package/build/types/packageMeta.d.ts +3 -2
  239. package/build/utils/cli-utils.js +2 -2
  240. package/build/utils/cli-utils.js.map +1 -1
  241. package/build/utils/cli-utils.mjs +2 -2
  242. package/build/utils/cli-utils.mjs.map +1 -1
  243. package/build/utils/index.js +1 -0
  244. package/build/utils/index.mjs +2 -2
  245. package/build/utils/routes.d.ts +1 -0
  246. package/build/utils/routes.js +1 -0
  247. package/build/utils/routes.js.map +1 -1
  248. package/build/utils/routes.mjs +1 -0
  249. package/build/utils/routes.mjs.map +1 -1
  250. package/build/utils/schemas.d.ts +1 -0
  251. package/build/utils/schemas.js +4 -4
  252. package/build/utils/schemas.js.map +1 -1
  253. package/build/utils/schemas.mjs +4 -4
  254. package/build/utils/schemas.mjs.map +1 -1
  255. package/build/utils/session-id.d.ts +8 -0
  256. package/build/utils/session-id.js +26 -0
  257. package/build/utils/session-id.js.map +1 -0
  258. package/build/utils/session-id.mjs +26 -0
  259. package/build/utils/session-id.mjs.map +1 -0
  260. package/build/utils/token.d.ts +1 -0
  261. package/build/utils/token.js +12 -8
  262. package/build/utils/token.js.map +1 -1
  263. package/build/utils/token.mjs +12 -9
  264. package/build/utils/token.mjs.map +1 -1
  265. package/build/utils/url.js +1 -1
  266. package/build/utils/url.js.map +1 -1
  267. package/build/utils/url.mjs +1 -1
  268. package/build/utils/url.mjs.map +1 -1
  269. package/build/utils/utils.d.ts +10 -0
  270. package/build/utils/utils.js +26 -0
  271. package/build/utils/utils.js.map +1 -1
  272. package/build/utils/utils.mjs +25 -1
  273. package/build/utils/utils.mjs.map +1 -1
  274. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"Versions.js","names":[],"sources":["../../../src/components/Versions/Versions.tsx"],"sourcesContent":["import styled from '@emotion/styled';\nimport Alert from '@mui/material/Alert';\nimport Box from '@mui/material/Box';\nimport Card from '@mui/material/Card';\nimport CardContent from '@mui/material/CardContent';\nimport TextField from '@mui/material/TextField';\nimport Typography from '@mui/material/Typography';\nimport { debounce } from 'lodash-es';\nimport React, { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport semver from 'semver';\n\nimport type { Theme } from '../../Theme';\nimport { useConfig } from '../../providers';\nimport VersionsHistoryList from './HistoryList';\nimport VersionsTagList from './TagList';\n\nexport type Props = { packageMeta: any; packageName: string };\n\nexport const StyledText = styled(Typography)<{ theme?: Theme }>((props) => ({\n fontWeight: props.theme && props.theme.fontWeight.bold,\n textTransform: 'capitalize',\n}));\n\nconst Versions: React.FC<Props> = ({ packageMeta, packageName }) => {\n const { t } = useTranslation();\n const { configOptions } = useConfig();\n const { versions = {}, time = {}, ['dist-tags']: distTags = {} } = packageMeta;\n\n const [packageVersions, setPackageVersions] = useState(versions);\n if (!packageMeta || Object.keys(packageMeta).length === 0) {\n return null;\n }\n const hideDeprecatedVersions = configOptions.hideDeprecatedVersions;\n const hasDistTags = distTags && Object.keys(distTags).length > 0 && packageName;\n const hasVersionHistory =\n packageVersions && Object.keys(packageVersions).length > 0 && packageName;\n\n const filterVersions = (textSearch) => {\n const filteredVersions = Object.keys(versions).reduce((acc, version) => {\n if (textSearch !== '') {\n if (typeof versions[version] !== 'undefined') {\n if (semver.satisfies(version, textSearch, { includePrerelease: true, loose: true })) {\n acc[version] = versions[version];\n }\n }\n } else {\n acc[version] = versions[version];\n }\n return acc;\n }, {});\n\n setPackageVersions(filteredVersions);\n };\n\n return (\n <Card sx={{ mb: 2 }}>\n <CardContent>\n <Box data-testid=\"versions\" sx={{ m: 2 }}>\n {hasDistTags ? (\n <>\n <StyledText variant=\"subtitle1\">\n {t('versions.current-tags')}\n <span>{` (${Object.keys(distTags).length})`}</span>\n </StyledText>\n <VersionsTagList packageName={packageName} tags={distTags} time={time} />\n </>\n ) : null}\n <>\n <StyledText variant=\"subtitle1\">\n {t('versions.version-history')}\n <span>{` (${Object.keys(packageVersions).length})`}</span>\n </StyledText>\n <TextField\n helperText={t('versions.search.placeholder')}\n onChange={debounce((e) => {\n filterVersions(e.target.value);\n }, 200)}\n size=\"small\"\n variant=\"standard\"\n sx={{ width: '50%' }}\n />\n </>\n {hasVersionHistory ? (\n <>\n {hideDeprecatedVersions === true && (\n // @ts-ignore - Alert does accept children despite the type error\n <Alert severity=\"info\" sx={{ marginTop: 1, marginBottom: 1 }}>\n {t('versions.hide-deprecated')}\n </Alert>\n )}\n <VersionsHistoryList\n packageName={packageName}\n time={time}\n versions={packageVersions}\n />\n </>\n ) : null}\n </Box>\n </CardContent>\n </Card>\n );\n};\n\nexport default Versions;\n"],"mappings":"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"}
1
+ {"version":3,"file":"Versions.js","names":[],"sources":["../../../src/components/Versions/Versions.tsx"],"sourcesContent":["import styled from '@emotion/styled';\nimport Alert from '@mui/material/Alert';\nimport Box from '@mui/material/Box';\nimport Card from '@mui/material/Card';\nimport CardContent from '@mui/material/CardContent';\nimport TextField from '@mui/material/TextField';\nimport Typography from '@mui/material/Typography';\nimport { debounce } from 'lodash-es';\nimport React, { useEffect, useMemo, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport semver from 'semver';\n\nimport type { Theme } from '../../Theme';\nimport { useConfig } from '../../providers';\nimport VersionsHistoryList from './HistoryList';\nimport VersionsTagList from './TagList';\n\nexport type Props = { packageMeta: any; packageName: string };\n\nexport const StyledText = styled(Typography)<{ theme?: Theme }>((props) => ({\n fontWeight: props.theme && props.theme.fontWeight.bold,\n textTransform: 'capitalize',\n}));\n\nconst Versions: React.FC<Props> = ({ packageMeta, packageName }) => {\n const { t } = useTranslation();\n const { configOptions } = useConfig();\n const { versions = {}, time = {}, ['dist-tags']: distTags = {} } = packageMeta ?? {};\n\n const [textSearch, setTextSearch] = useState('');\n // the detail routes reuse this mounted component across packages: reset the\n // filter so the previous package's text does not apply to the next one\n useEffect(() => {\n setTextSearch('');\n }, [packageName]);\n const packageVersions = useMemo(() => {\n if (textSearch === '') {\n return versions;\n }\n return Object.keys(versions).reduce((acc, version) => {\n if (typeof versions[version] !== 'undefined') {\n if (semver.satisfies(version, textSearch, { includePrerelease: true, loose: true })) {\n acc[version] = versions[version];\n }\n }\n return acc;\n }, {});\n }, [versions, textSearch]);\n\n if (!packageMeta || Object.keys(packageMeta).length === 0) {\n return null;\n }\n const hideDeprecatedVersions = configOptions.hideDeprecatedVersions;\n const hasDistTags = distTags && Object.keys(distTags).length > 0 && packageName;\n const hasVersionHistory =\n packageVersions && Object.keys(packageVersions).length > 0 && packageName;\n\n return (\n <Card sx={{ mb: 2 }}>\n <CardContent>\n <Box data-testid=\"versions\" sx={{ m: 2 }}>\n {hasDistTags ? (\n <>\n <StyledText variant=\"subtitle1\">\n {t('versions.current-tags')}\n <span>{` (${Object.keys(distTags).length})`}</span>\n </StyledText>\n <VersionsTagList packageName={packageName} tags={distTags} time={time} />\n </>\n ) : null}\n <>\n <StyledText variant=\"subtitle1\">\n {t('versions.version-history')}\n <span>{` (${Object.keys(packageVersions).length})`}</span>\n </StyledText>\n <TextField\n // uncontrolled input: remount on navigation to clear its text\n key={packageName}\n helperText={t('versions.search.placeholder')}\n onChange={debounce((e) => {\n setTextSearch(e.target.value);\n }, 200)}\n size=\"small\"\n variant=\"standard\"\n sx={{ width: '50%' }}\n />\n </>\n {hasVersionHistory ? (\n <>\n {hideDeprecatedVersions === true && (\n // @ts-ignore - Alert does accept children despite the type error\n <Alert severity=\"info\" sx={{ marginTop: 1, marginBottom: 1 }}>\n {t('versions.hide-deprecated')}\n </Alert>\n )}\n <VersionsHistoryList\n packageName={packageName}\n time={time}\n versions={packageVersions}\n />\n </>\n ) : null}\n </Box>\n </CardContent>\n </Card>\n );\n};\n\nexport default Versions;\n"],"mappings":"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"}
@@ -3,15 +3,15 @@ import "../../providers/index.mjs";
3
3
  import VersionsHistoryList from "./HistoryList.mjs";
4
4
  import VersionsTagList from "./TagList.mjs";
5
5
  import styled from "@emotion/styled";
6
- import { useState } from "react";
6
+ import { useEffect, useMemo, useState } from "react";
7
+ import { useTranslation } from "react-i18next";
7
8
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
9
  import Box from "@mui/material/Box";
9
10
  import { debounce } from "lodash-es";
10
- import { useTranslation } from "react-i18next";
11
+ import Alert from "@mui/material/Alert";
11
12
  import Typography from "@mui/material/Typography";
12
13
  import Card from "@mui/material/Card";
13
14
  import CardContent from "@mui/material/CardContent";
14
- import Alert from "@mui/material/Alert";
15
15
  import TextField from "@mui/material/TextField";
16
16
  import semver from "semver";
17
17
  //#region src/components/Versions/Versions.tsx
@@ -22,26 +22,27 @@ var StyledText = styled(Typography)((props) => ({
22
22
  var Versions = ({ packageMeta, packageName }) => {
23
23
  const { t } = useTranslation();
24
24
  const { configOptions } = useConfig();
25
- const { versions = {}, time = {}, ["dist-tags"]: distTags = {} } = packageMeta;
26
- const [packageVersions, setPackageVersions] = useState(versions);
25
+ const { versions = {}, time = {}, ["dist-tags"]: distTags = {} } = packageMeta ?? {};
26
+ const [textSearch, setTextSearch] = useState("");
27
+ useEffect(() => {
28
+ setTextSearch("");
29
+ }, [packageName]);
30
+ const packageVersions = useMemo(() => {
31
+ if (textSearch === "") return versions;
32
+ return Object.keys(versions).reduce((acc, version) => {
33
+ if (typeof versions[version] !== "undefined") {
34
+ if (semver.satisfies(version, textSearch, {
35
+ includePrerelease: true,
36
+ loose: true
37
+ })) acc[version] = versions[version];
38
+ }
39
+ return acc;
40
+ }, {});
41
+ }, [versions, textSearch]);
27
42
  if (!packageMeta || Object.keys(packageMeta).length === 0) return null;
28
43
  const hideDeprecatedVersions = configOptions.hideDeprecatedVersions;
29
44
  const hasDistTags = distTags && Object.keys(distTags).length > 0 && packageName;
30
45
  const hasVersionHistory = packageVersions && Object.keys(packageVersions).length > 0 && packageName;
31
- const filterVersions = (textSearch) => {
32
- const filteredVersions = Object.keys(versions).reduce((acc, version) => {
33
- if (textSearch !== "") {
34
- if (typeof versions[version] !== "undefined") {
35
- if (semver.satisfies(version, textSearch, {
36
- includePrerelease: true,
37
- loose: true
38
- })) acc[version] = versions[version];
39
- }
40
- } else acc[version] = versions[version];
41
- return acc;
42
- }, {});
43
- setPackageVersions(filteredVersions);
44
- };
45
46
  return /* @__PURE__ */ jsx(Card, {
46
47
  sx: { mb: 2 },
47
48
  children: /* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsxs(Box, {
@@ -62,12 +63,12 @@ var Versions = ({ packageMeta, packageName }) => {
62
63
  }), /* @__PURE__ */ jsx(TextField, {
63
64
  helperText: t("versions.search.placeholder"),
64
65
  onChange: debounce((e) => {
65
- filterVersions(e.target.value);
66
+ setTextSearch(e.target.value);
66
67
  }, 200),
67
68
  size: "small",
68
69
  variant: "standard",
69
70
  sx: { width: "50%" }
70
- })] }),
71
+ }, packageName)] }),
71
72
  hasVersionHistory ? /* @__PURE__ */ jsxs(Fragment$1, { children: [hideDeprecatedVersions === true && /* @__PURE__ */ jsx(Alert, {
72
73
  severity: "info",
73
74
  sx: {
@@ -1 +1 @@
1
- {"version":3,"file":"Versions.mjs","names":[],"sources":["../../../src/components/Versions/Versions.tsx"],"sourcesContent":["import styled from '@emotion/styled';\nimport Alert from '@mui/material/Alert';\nimport Box from '@mui/material/Box';\nimport Card from '@mui/material/Card';\nimport CardContent from '@mui/material/CardContent';\nimport TextField from '@mui/material/TextField';\nimport Typography from '@mui/material/Typography';\nimport { debounce } from 'lodash-es';\nimport React, { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport semver from 'semver';\n\nimport type { Theme } from '../../Theme';\nimport { useConfig } from '../../providers';\nimport VersionsHistoryList from './HistoryList';\nimport VersionsTagList from './TagList';\n\nexport type Props = { packageMeta: any; packageName: string };\n\nexport const StyledText = styled(Typography)<{ theme?: Theme }>((props) => ({\n fontWeight: props.theme && props.theme.fontWeight.bold,\n textTransform: 'capitalize',\n}));\n\nconst Versions: React.FC<Props> = ({ packageMeta, packageName }) => {\n const { t } = useTranslation();\n const { configOptions } = useConfig();\n const { versions = {}, time = {}, ['dist-tags']: distTags = {} } = packageMeta;\n\n const [packageVersions, setPackageVersions] = useState(versions);\n if (!packageMeta || Object.keys(packageMeta).length === 0) {\n return null;\n }\n const hideDeprecatedVersions = configOptions.hideDeprecatedVersions;\n const hasDistTags = distTags && Object.keys(distTags).length > 0 && packageName;\n const hasVersionHistory =\n packageVersions && Object.keys(packageVersions).length > 0 && packageName;\n\n const filterVersions = (textSearch) => {\n const filteredVersions = Object.keys(versions).reduce((acc, version) => {\n if (textSearch !== '') {\n if (typeof versions[version] !== 'undefined') {\n if (semver.satisfies(version, textSearch, { includePrerelease: true, loose: true })) {\n acc[version] = versions[version];\n }\n }\n } else {\n acc[version] = versions[version];\n }\n return acc;\n }, {});\n\n setPackageVersions(filteredVersions);\n };\n\n return (\n <Card sx={{ mb: 2 }}>\n <CardContent>\n <Box data-testid=\"versions\" sx={{ m: 2 }}>\n {hasDistTags ? (\n <>\n <StyledText variant=\"subtitle1\">\n {t('versions.current-tags')}\n <span>{` (${Object.keys(distTags).length})`}</span>\n </StyledText>\n <VersionsTagList packageName={packageName} tags={distTags} time={time} />\n </>\n ) : null}\n <>\n <StyledText variant=\"subtitle1\">\n {t('versions.version-history')}\n <span>{` (${Object.keys(packageVersions).length})`}</span>\n </StyledText>\n <TextField\n helperText={t('versions.search.placeholder')}\n onChange={debounce((e) => {\n filterVersions(e.target.value);\n }, 200)}\n size=\"small\"\n variant=\"standard\"\n sx={{ width: '50%' }}\n />\n </>\n {hasVersionHistory ? (\n <>\n {hideDeprecatedVersions === true && (\n // @ts-ignore - Alert does accept children despite the type error\n <Alert severity=\"info\" sx={{ marginTop: 1, marginBottom: 1 }}>\n {t('versions.hide-deprecated')}\n </Alert>\n )}\n <VersionsHistoryList\n packageName={packageName}\n time={time}\n versions={packageVersions}\n />\n </>\n ) : null}\n </Box>\n </CardContent>\n </Card>\n );\n};\n\nexport default Versions;\n"],"mappings":";;;;;;;;;;;;;;;;;AAmBA,IAAa,aAAa,OAAO,UAAU,CAAC,EAAqB,WAAW;CAC1E,YAAY,MAAM,SAAS,MAAM,MAAM,WAAW;CAClD,eAAe;AACjB,EAAE;AAEF,IAAM,YAA6B,EAAE,aAAa,kBAAkB;CAClE,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,EAAE,kBAAkB,UAAU;CACpC,MAAM,EAAE,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,cAAc,WAAW,CAAC,MAAM;CAEnE,MAAM,CAAC,iBAAiB,sBAAsB,SAAS,QAAQ;CAC/D,IAAI,CAAC,eAAe,OAAO,KAAK,WAAW,CAAC,CAAC,WAAW,GACtD,OAAO;CAET,MAAM,yBAAyB,cAAc;CAC7C,MAAM,cAAc,YAAY,OAAO,KAAK,QAAQ,CAAC,CAAC,SAAS,KAAK;CACpE,MAAM,oBACJ,mBAAmB,OAAO,KAAK,eAAe,CAAC,CAAC,SAAS,KAAK;CAEhE,MAAM,kBAAkB,eAAe;EACrC,MAAM,mBAAmB,OAAO,KAAK,QAAQ,CAAC,CAAC,QAAQ,KAAK,YAAY;GACtE,IAAI,eAAe,IACb;QAAA,OAAO,SAAS,aAAa,aAC3B;SAAA,OAAO,UAAU,SAAS,YAAY;MAAE,mBAAmB;MAAM,OAAO;KAAK,CAAC,GAChF,IAAI,WAAW,SAAS;IAAA;GAC1B,OAGF,IAAI,WAAW,SAAS;GAE1B,OAAO;EACT,GAAG,CAAC,CAAC;EAEL,mBAAmB,gBAAgB;CACrC;CAEA,OACE,oBAAC,MAAD;EAAM,IAAI,EAAE,IAAI,EAAE;EAChB,UAAA,oBAAC,aAAD,EAAA,UACE,qBAAC,KAAD;GAAK,eAAY;GAAW,IAAI,EAAE,GAAG,EAAE;GAAvC,UAAA;IACG,cACC,qBAAA,YAAA,EAAA,UAAA,CACE,qBAAC,YAAD;KAAY,SAAQ;KAApB,UAAA,CACG,EAAE,uBAAuB,GAC1B,oBAAC,QAAD,EAAA,UAAO,KAAK,OAAO,KAAK,QAAQ,CAAC,CAAC,OAAO,GAAS,CAAA,CACxC;IACZ,CAAA,GAAA,oBAAC,iBAAD;KAA8B;KAAa,MAAM;KAAgB;IAAO,CAAA,CACxE,EAAA,CAAA,IACA;IACJ,qBAAA,YAAA,EAAA,UAAA,CACE,qBAAC,YAAD;KAAY,SAAQ;KAApB,UAAA,CACG,EAAE,0BAA0B,GAC7B,oBAAC,QAAD,EAAA,UAAO,KAAK,OAAO,KAAK,eAAe,CAAC,CAAC,OAAO,GAAS,CAAA,CAC/C;IACZ,CAAA,GAAA,oBAAC,WAAD;KACE,YAAY,EAAE,6BAA6B;KAC3C,UAAU,UAAU,MAAM;MACxB,eAAe,EAAE,OAAO,KAAK;KAC/B,GAAG,GAAG;KACN,MAAK;KACL,SAAQ;KACR,IAAI,EAAE,OAAO,MAAM;IACpB,CAAA,CACD,EAAA,CAAA;IACD,oBACC,qBAAA,YAAA,EAAA,UAAA,CACG,2BAA2B,QAE1B,oBAAC,OAAD;KAAO,UAAS;KAAO,IAAI;MAAE,WAAW;MAAG,cAAc;KAAE;KACxD,UAAA,EAAE,0BAA0B;IACxB,CAAA,GAET,oBAAC,qBAAD;KACe;KACP;KACN,UAAU;IACX,CAAA,CACD,EAAA,CAAA,IACA;GACD;EACM,CAAA,EAAA,CAAA;CACT,CAAA;AAEV"}
1
+ {"version":3,"file":"Versions.mjs","names":[],"sources":["../../../src/components/Versions/Versions.tsx"],"sourcesContent":["import styled from '@emotion/styled';\nimport Alert from '@mui/material/Alert';\nimport Box from '@mui/material/Box';\nimport Card from '@mui/material/Card';\nimport CardContent from '@mui/material/CardContent';\nimport TextField from '@mui/material/TextField';\nimport Typography from '@mui/material/Typography';\nimport { debounce } from 'lodash-es';\nimport React, { useEffect, useMemo, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport semver from 'semver';\n\nimport type { Theme } from '../../Theme';\nimport { useConfig } from '../../providers';\nimport VersionsHistoryList from './HistoryList';\nimport VersionsTagList from './TagList';\n\nexport type Props = { packageMeta: any; packageName: string };\n\nexport const StyledText = styled(Typography)<{ theme?: Theme }>((props) => ({\n fontWeight: props.theme && props.theme.fontWeight.bold,\n textTransform: 'capitalize',\n}));\n\nconst Versions: React.FC<Props> = ({ packageMeta, packageName }) => {\n const { t } = useTranslation();\n const { configOptions } = useConfig();\n const { versions = {}, time = {}, ['dist-tags']: distTags = {} } = packageMeta ?? {};\n\n const [textSearch, setTextSearch] = useState('');\n // the detail routes reuse this mounted component across packages: reset the\n // filter so the previous package's text does not apply to the next one\n useEffect(() => {\n setTextSearch('');\n }, [packageName]);\n const packageVersions = useMemo(() => {\n if (textSearch === '') {\n return versions;\n }\n return Object.keys(versions).reduce((acc, version) => {\n if (typeof versions[version] !== 'undefined') {\n if (semver.satisfies(version, textSearch, { includePrerelease: true, loose: true })) {\n acc[version] = versions[version];\n }\n }\n return acc;\n }, {});\n }, [versions, textSearch]);\n\n if (!packageMeta || Object.keys(packageMeta).length === 0) {\n return null;\n }\n const hideDeprecatedVersions = configOptions.hideDeprecatedVersions;\n const hasDistTags = distTags && Object.keys(distTags).length > 0 && packageName;\n const hasVersionHistory =\n packageVersions && Object.keys(packageVersions).length > 0 && packageName;\n\n return (\n <Card sx={{ mb: 2 }}>\n <CardContent>\n <Box data-testid=\"versions\" sx={{ m: 2 }}>\n {hasDistTags ? (\n <>\n <StyledText variant=\"subtitle1\">\n {t('versions.current-tags')}\n <span>{` (${Object.keys(distTags).length})`}</span>\n </StyledText>\n <VersionsTagList packageName={packageName} tags={distTags} time={time} />\n </>\n ) : null}\n <>\n <StyledText variant=\"subtitle1\">\n {t('versions.version-history')}\n <span>{` (${Object.keys(packageVersions).length})`}</span>\n </StyledText>\n <TextField\n // uncontrolled input: remount on navigation to clear its text\n key={packageName}\n helperText={t('versions.search.placeholder')}\n onChange={debounce((e) => {\n setTextSearch(e.target.value);\n }, 200)}\n size=\"small\"\n variant=\"standard\"\n sx={{ width: '50%' }}\n />\n </>\n {hasVersionHistory ? (\n <>\n {hideDeprecatedVersions === true && (\n // @ts-ignore - Alert does accept children despite the type error\n <Alert severity=\"info\" sx={{ marginTop: 1, marginBottom: 1 }}>\n {t('versions.hide-deprecated')}\n </Alert>\n )}\n <VersionsHistoryList\n packageName={packageName}\n time={time}\n versions={packageVersions}\n />\n </>\n ) : null}\n </Box>\n </CardContent>\n </Card>\n );\n};\n\nexport default Versions;\n"],"mappings":";;;;;;;;;;;;;;;;;AAmBA,IAAa,aAAa,OAAO,UAAU,CAAC,EAAqB,WAAW;CAC1E,YAAY,MAAM,SAAS,MAAM,MAAM,WAAW;CAClD,eAAe;AACjB,EAAE;AAEF,IAAM,YAA6B,EAAE,aAAa,kBAAkB;CAClE,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,EAAE,kBAAkB,UAAU;CACpC,MAAM,EAAE,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,cAAc,WAAW,CAAC,MAAM,eAAe,CAAC;CAEnF,MAAM,CAAC,YAAY,iBAAiB,SAAS,EAAE;CAG/C,gBAAgB;EACd,cAAc,EAAE;CAClB,GAAG,CAAC,WAAW,CAAC;CAChB,MAAM,kBAAkB,cAAc;EACpC,IAAI,eAAe,IACjB,OAAO;EAET,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,QAAQ,KAAK,YAAY;GACpD,IAAI,OAAO,SAAS,aAAa,aAC3B;QAAA,OAAO,UAAU,SAAS,YAAY;KAAE,mBAAmB;KAAM,OAAO;IAAK,CAAC,GAChF,IAAI,WAAW,SAAS;GAAA;GAG5B,OAAO;EACT,GAAG,CAAC,CAAC;CACP,GAAG,CAAC,UAAU,UAAU,CAAC;CAEzB,IAAI,CAAC,eAAe,OAAO,KAAK,WAAW,CAAC,CAAC,WAAW,GACtD,OAAO;CAET,MAAM,yBAAyB,cAAc;CAC7C,MAAM,cAAc,YAAY,OAAO,KAAK,QAAQ,CAAC,CAAC,SAAS,KAAK;CACpE,MAAM,oBACJ,mBAAmB,OAAO,KAAK,eAAe,CAAC,CAAC,SAAS,KAAK;CAEhE,OACE,oBAAC,MAAD;EAAM,IAAI,EAAE,IAAI,EAAE;EAChB,UAAA,oBAAC,aAAD,EAAA,UACE,qBAAC,KAAD;GAAK,eAAY;GAAW,IAAI,EAAE,GAAG,EAAE;GAAvC,UAAA;IACG,cACC,qBAAA,YAAA,EAAA,UAAA,CACE,qBAAC,YAAD;KAAY,SAAQ;KAApB,UAAA,CACG,EAAE,uBAAuB,GAC1B,oBAAC,QAAD,EAAA,UAAO,KAAK,OAAO,KAAK,QAAQ,CAAC,CAAC,OAAO,GAAS,CAAA,CACxC;IACZ,CAAA,GAAA,oBAAC,iBAAD;KAA8B;KAAa,MAAM;KAAgB;IAAO,CAAA,CACxE,EAAA,CAAA,IACA;IACJ,qBAAA,YAAA,EAAA,UAAA,CACE,qBAAC,YAAD;KAAY,SAAQ;KAApB,UAAA,CACG,EAAE,0BAA0B,GAC7B,oBAAC,QAAD,EAAA,UAAO,KAAK,OAAO,KAAK,eAAe,CAAC,CAAC,OAAO,GAAS,CAAA,CAC/C;IACZ,CAAA,GAAA,oBAAC,WAAD;KAGE,YAAY,EAAE,6BAA6B;KAC3C,UAAU,UAAU,MAAM;MACxB,cAAc,EAAE,OAAO,KAAK;KAC9B,GAAG,GAAG;KACN,MAAK;KACL,SAAQ;KACR,IAAI,EAAE,OAAO,MAAM;IACpB,GARM,WAQN,CACD,EAAA,CAAA;IACD,oBACC,qBAAA,YAAA,EAAA,UAAA,CACG,2BAA2B,QAE1B,oBAAC,OAAD;KAAO,UAAS;KAAO,IAAI;MAAE,WAAW;MAAG,cAAc;KAAE;KACxD,UAAA,EAAE,0BAA0B;IACxB,CAAA,GAET,oBAAC,qBAAD;KACe;KACP;KACN,UAAU;IACX,CAAA,CACD,EAAA,CAAA,IACA;GACD;EACM,CAAA,EAAA,CAAA;CACT,CAAA;AAEV"}
package/build/index.d.ts CHANGED
@@ -24,6 +24,7 @@ export { default as Label } from './components/Label';
24
24
  export { default as Logo } from './components/Logo';
25
25
  export { default as MenuItem } from './components/MenuItem';
26
26
  export { default as NotFound } from './components/NotFound';
27
+ export { default as GenericError } from './components/GenericError';
27
28
  export { default as Forbidden } from './components/Forbidden';
28
29
  export { default as LoginDialog } from './components/LoginDialog';
29
30
  export { default as Search } from './components/Search';
package/build/index.js CHANGED
@@ -72,6 +72,8 @@ const require_MenuItem = require("./components/MenuItem/MenuItem.js");
72
72
  require("./components/MenuItem/index.js");
73
73
  const require_NotFound = require("./components/NotFound/NotFound.js");
74
74
  require("./components/NotFound/index.js");
75
+ const require_GenericError = require("./components/GenericError/GenericError.js");
76
+ require("./components/GenericError/index.js");
75
77
  const require_Forbidden = require("./components/Forbidden/Forbidden.js");
76
78
  require("./components/Forbidden/index.js");
77
79
  const require_LoginDialog = require("./components/LoginDialog/LoginDialog.js");
@@ -135,6 +137,7 @@ exports.ErrorBoundary = require_ErrorBoundary.default;
135
137
  exports.Footer = require_Footer.default;
136
138
  exports.Forbidden = require_Forbidden.Forbidden;
137
139
  exports.FundButton = require_FundButton.default;
140
+ exports.GenericError = require_GenericError.default;
138
141
  exports.Header = require_Header.default;
139
142
  exports.HeaderInfoDialog = require_HeaderInfoDialog.default;
140
143
  exports.Heading = require_Heading.default;
@@ -197,6 +200,7 @@ exports.getCLISetRegistry = require_cli_utils.getCLISetRegistry;
197
200
  exports.getTheme = require_theme.getTheme;
198
201
  exports.isTokenExpire = require_token.isTokenExpire;
199
202
  exports.loadable = require_loadable.default;
203
+ exports.tokenExpireInMs = require_token.tokenExpireInMs;
200
204
  Object.defineProperty(exports, "url", {
201
205
  enumerable: true,
202
206
  get: function() {
package/build/index.mjs CHANGED
@@ -7,7 +7,7 @@ import { utils_exports } from "./utils/utils.mjs";
7
7
  import { getCLIChangePassword, getCLISBerryYamlRegistry, getCLISetConfigRegistry, getCLISetRegistry } from "./utils/cli-utils.mjs";
8
8
  import loadable_default from "./utils/loadable.mjs";
9
9
  import { Route } from "./utils/routes.mjs";
10
- import { isTokenExpire } from "./utils/token.mjs";
10
+ import { isTokenExpire, tokenExpireInMs } from "./utils/token.mjs";
11
11
  import "./utils/index.mjs";
12
12
  import RawViewer from "./components/RawViewer/RawViewer.mjs";
13
13
  import "./components/RawViewer/index.mjs";
@@ -68,6 +68,8 @@ import MenuItem from "./components/MenuItem/MenuItem.mjs";
68
68
  import "./components/MenuItem/index.mjs";
69
69
  import NotFound from "./components/NotFound/NotFound.mjs";
70
70
  import "./components/NotFound/index.mjs";
71
+ import GenericError from "./components/GenericError/GenericError.mjs";
72
+ import "./components/GenericError/index.mjs";
71
73
  import { Forbidden } from "./components/Forbidden/Forbidden.mjs";
72
74
  import "./components/Forbidden/index.mjs";
73
75
  import LoginDialog from "./components/LoginDialog/LoginDialog.mjs";
@@ -111,4 +113,4 @@ import { ThemeProvider, useCustomTheme } from "./Theme/ThemeProvider.mjs";
111
113
  import StyleBaseline from "./Theme/StyleBaseline.mjs";
112
114
  import "./Theme/index.mjs";
113
115
  import "./store/index.mjs";
114
- export { ActionBar, AddUser, AppConfigurationProvider, AppRoute, AuthContext, AuthProvider, Author, ChangePassword, CopyToClipBoard as CopyClipboard, Dependencies, Deprecated, DetailContainer as Detail, Developers, Dist as Distribution, DownloadProvider, Engine as Engines, ErrorBoundary, Footer, Forbidden, FundButton, Header, HeaderInfoDialog, Heading, Help, Home, Icons_exports as Icons, Install, Keywords, Label, Link, LinkExternal, Loading, Login, LoginDialog, Logo, ManifestsProvider, MenuItem, NotFound, Package, PackageList, PersistenceSettingProvider, Person, RawViewer, Readme, Route, Search, SearchContext, SearchProvider, DetailSidebar as SideBar, DetailSidebarTitle as SideBarTitle, StyleBaseline, Success, ThemeProvider, TranslatorProvider, UpLinks, VersionLayout, VersionProvider, Versions, api_default as api, breakPoints, colors_exports as colors, copyToClipBoardUtility, customizedTheme, fontSize, fontWeight, getCLIChangePassword, getCLISBerryYamlRegistry, getCLISetConfigRegistry, getCLISetRegistry, getTheme, isTokenExpire, loadable_default as loadable, url_exports as url, useAuth, useConfig, useCustomTheme, useDownload, useLanguage, useLocalStorage, useManifests, useOnClickOutside, useSearch, useSettings, useVersion, utils_exports as utils };
116
+ export { ActionBar, AddUser, AppConfigurationProvider, AppRoute, AuthContext, AuthProvider, Author, ChangePassword, CopyToClipBoard as CopyClipboard, Dependencies, Deprecated, DetailContainer as Detail, Developers, Dist as Distribution, DownloadProvider, Engine as Engines, ErrorBoundary, Footer, Forbidden, FundButton, GenericError, Header, HeaderInfoDialog, Heading, Help, Home, Icons_exports as Icons, Install, Keywords, Label, Link, LinkExternal, Loading, Login, LoginDialog, Logo, ManifestsProvider, MenuItem, NotFound, Package, PackageList, PersistenceSettingProvider, Person, RawViewer, Readme, Route, Search, SearchContext, SearchProvider, DetailSidebar as SideBar, DetailSidebarTitle as SideBarTitle, StyleBaseline, Success, ThemeProvider, TranslatorProvider, UpLinks, VersionLayout, VersionProvider, Versions, api_default as api, breakPoints, colors_exports as colors, copyToClipBoardUtility, customizedTheme, fontSize, fontWeight, getCLIChangePassword, getCLISBerryYamlRegistry, getCLISetConfigRegistry, getCLISetRegistry, getTheme, isTokenExpire, loadable_default as loadable, tokenExpireInMs, url_exports as url, useAuth, useConfig, useCustomTheme, useDownload, useLanguage, useLocalStorage, useManifests, useOnClickOutside, useSearch, useSettings, useVersion, utils_exports as utils };
@@ -1,6 +1,8 @@
1
1
  const require_runtime = require("../../_virtual/_rolldown/runtime.js");
2
2
  const require_VersionProvider = require("../../providers/VersionProvider/VersionProvider.js");
3
3
  const require_NotFound = require("../../components/NotFound/NotFound.js");
4
+ const require_GenericError = require("../../components/GenericError/GenericError.js");
5
+ require("../../components/GenericError/index.js");
4
6
  const require_Forbidden = require("../../components/Forbidden/Forbidden.js");
5
7
  require("../../components/Forbidden/index.js");
6
8
  const require_Loading = require("../../components/Loading/Loading.js");
@@ -11,11 +13,12 @@ react = require_runtime.__toESM(react);
11
13
  let react_jsx_runtime = require("react/jsx-runtime");
12
14
  //#region src/pages/Version/Version.tsx
13
15
  var Version = () => {
14
- const { hasNotBeenFound, isForbidden, isUnAuthorized, isLoading } = require_VersionProvider.useVersion();
16
+ const { hasNotBeenFound, isForbidden, isUnAuthorized, isError, isLoading, packageMeta } = require_VersionProvider.useVersion();
15
17
  if (isLoading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Loading.default, {});
16
18
  if (isUnAuthorized) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Forbidden.Forbidden, {});
17
19
  if (isForbidden) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Forbidden.Forbidden, {});
18
20
  if (hasNotBeenFound) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_NotFound.default, {});
21
+ if (isError || !packageMeta) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_GenericError.default, {});
19
22
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Version.default, {});
20
23
  };
21
24
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"Version.js","names":[],"sources":["../../../src/pages/Version/Version.tsx"],"sourcesContent":["import React from 'react';\n\nimport Forbidden from '../../components/Forbidden';\nimport { Loading, NotFound, VersionLayout, useVersion } from '../../index';\n\nconst Version: React.FC = () => {\n const { hasNotBeenFound, isForbidden, isUnAuthorized, isLoading } = useVersion();\n\n if (isLoading) {\n return <Loading />;\n }\n\n if (isUnAuthorized) {\n return <Forbidden />;\n }\n\n if (isForbidden) {\n return <Forbidden />;\n }\n\n if (hasNotBeenFound) {\n return <NotFound />;\n }\n\n return <VersionLayout />;\n};\n\nexport default Version;\n"],"mappings":";;;;;;;;;;;;AAKA,IAAM,gBAA0B;CAC9B,MAAM,EAAE,iBAAiB,aAAa,gBAAgB,cAAc,wBAAA,WAAW;CAE/E,IAAI,WACF,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,gBAAA,SAAD,CAAU,CAAA;CAGnB,IAAI,gBACF,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,kBAAA,WAAD,CAAY,CAAA;CAGrB,IAAI,aACF,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,kBAAA,WAAD,CAAY,CAAA;CAGrB,IAAI,iBACF,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,iBAAA,SAAD,CAAW,CAAA;CAGpB,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,gBAAA,SAAD,CAAgB,CAAA;AACzB"}
1
+ {"version":3,"file":"Version.js","names":[],"sources":["../../../src/pages/Version/Version.tsx"],"sourcesContent":["import React from 'react';\n\nimport Forbidden from '../../components/Forbidden';\nimport GenericError from '../../components/GenericError';\nimport { Loading, NotFound, VersionLayout, useVersion } from '../../index';\n\nconst Version: React.FC = () => {\n const { hasNotBeenFound, isForbidden, isUnAuthorized, isError, isLoading, packageMeta } =\n useVersion();\n\n if (isLoading) {\n return <Loading />;\n }\n\n if (isUnAuthorized) {\n return <Forbidden />;\n }\n\n if (isForbidden) {\n return <Forbidden />;\n }\n\n if (hasNotBeenFound) {\n return <NotFound />;\n }\n\n // 5xx, network failures or a manifest that never arrived: rendering the\n // layout without packageMeta crashes the tab components\n if (isError || !packageMeta) {\n return <GenericError />;\n }\n\n return <VersionLayout />;\n};\n\nexport default Version;\n"],"mappings":";;;;;;;;;;;;;;AAMA,IAAM,gBAA0B;CAC9B,MAAM,EAAE,iBAAiB,aAAa,gBAAgB,SAAS,WAAW,gBACxE,wBAAA,WAAW;CAEb,IAAI,WACF,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,gBAAA,SAAD,CAAU,CAAA;CAGnB,IAAI,gBACF,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,kBAAA,WAAD,CAAY,CAAA;CAGrB,IAAI,aACF,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,kBAAA,WAAD,CAAY,CAAA;CAGrB,IAAI,iBACF,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,iBAAA,SAAD,CAAW,CAAA;CAKpB,IAAI,WAAW,CAAC,aACd,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,qBAAA,SAAD,CAAe,CAAA;CAGxB,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,gBAAA,SAAD,CAAgB,CAAA;AACzB"}
@@ -1,5 +1,7 @@
1
1
  import { useVersion } from "../../providers/VersionProvider/VersionProvider.mjs";
2
2
  import NotFound from "../../components/NotFound/NotFound.mjs";
3
+ import GenericError from "../../components/GenericError/GenericError.mjs";
4
+ import "../../components/GenericError/index.mjs";
3
5
  import { Forbidden } from "../../components/Forbidden/Forbidden.mjs";
4
6
  import "../../components/Forbidden/index.mjs";
5
7
  import Loading from "../../components/Loading/Loading.mjs";
@@ -9,11 +11,12 @@ import "react";
9
11
  import { jsx } from "react/jsx-runtime";
10
12
  //#region src/pages/Version/Version.tsx
11
13
  var Version = () => {
12
- const { hasNotBeenFound, isForbidden, isUnAuthorized, isLoading } = useVersion();
14
+ const { hasNotBeenFound, isForbidden, isUnAuthorized, isError, isLoading, packageMeta } = useVersion();
13
15
  if (isLoading) return /* @__PURE__ */ jsx(Loading, {});
14
16
  if (isUnAuthorized) return /* @__PURE__ */ jsx(Forbidden, {});
15
17
  if (isForbidden) return /* @__PURE__ */ jsx(Forbidden, {});
16
18
  if (hasNotBeenFound) return /* @__PURE__ */ jsx(NotFound, {});
19
+ if (isError || !packageMeta) return /* @__PURE__ */ jsx(GenericError, {});
17
20
  return /* @__PURE__ */ jsx(VersionLayout, {});
18
21
  };
19
22
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"Version.mjs","names":[],"sources":["../../../src/pages/Version/Version.tsx"],"sourcesContent":["import React from 'react';\n\nimport Forbidden from '../../components/Forbidden';\nimport { Loading, NotFound, VersionLayout, useVersion } from '../../index';\n\nconst Version: React.FC = () => {\n const { hasNotBeenFound, isForbidden, isUnAuthorized, isLoading } = useVersion();\n\n if (isLoading) {\n return <Loading />;\n }\n\n if (isUnAuthorized) {\n return <Forbidden />;\n }\n\n if (isForbidden) {\n return <Forbidden />;\n }\n\n if (hasNotBeenFound) {\n return <NotFound />;\n }\n\n return <VersionLayout />;\n};\n\nexport default Version;\n"],"mappings":";;;;;;;;;;AAKA,IAAM,gBAA0B;CAC9B,MAAM,EAAE,iBAAiB,aAAa,gBAAgB,cAAc,WAAW;CAE/E,IAAI,WACF,OAAO,oBAAC,SAAD,CAAU,CAAA;CAGnB,IAAI,gBACF,OAAO,oBAAC,WAAD,CAAY,CAAA;CAGrB,IAAI,aACF,OAAO,oBAAC,WAAD,CAAY,CAAA;CAGrB,IAAI,iBACF,OAAO,oBAAC,UAAD,CAAW,CAAA;CAGpB,OAAO,oBAAC,eAAD,CAAgB,CAAA;AACzB"}
1
+ {"version":3,"file":"Version.mjs","names":[],"sources":["../../../src/pages/Version/Version.tsx"],"sourcesContent":["import React from 'react';\n\nimport Forbidden from '../../components/Forbidden';\nimport GenericError from '../../components/GenericError';\nimport { Loading, NotFound, VersionLayout, useVersion } from '../../index';\n\nconst Version: React.FC = () => {\n const { hasNotBeenFound, isForbidden, isUnAuthorized, isError, isLoading, packageMeta } =\n useVersion();\n\n if (isLoading) {\n return <Loading />;\n }\n\n if (isUnAuthorized) {\n return <Forbidden />;\n }\n\n if (isForbidden) {\n return <Forbidden />;\n }\n\n if (hasNotBeenFound) {\n return <NotFound />;\n }\n\n // 5xx, network failures or a manifest that never arrived: rendering the\n // layout without packageMeta crashes the tab components\n if (isError || !packageMeta) {\n return <GenericError />;\n }\n\n return <VersionLayout />;\n};\n\nexport default Version;\n"],"mappings":";;;;;;;;;;;;AAMA,IAAM,gBAA0B;CAC9B,MAAM,EAAE,iBAAiB,aAAa,gBAAgB,SAAS,WAAW,gBACxE,WAAW;CAEb,IAAI,WACF,OAAO,oBAAC,SAAD,CAAU,CAAA;CAGnB,IAAI,gBACF,OAAO,oBAAC,WAAD,CAAY,CAAA;CAGrB,IAAI,aACF,OAAO,oBAAC,WAAD,CAAY,CAAA;CAGrB,IAAI,iBACF,OAAO,oBAAC,UAAD,CAAW,CAAA;CAKpB,IAAI,WAAW,CAAC,aACd,OAAO,oBAAC,cAAD,CAAe,CAAA;CAGxB,OAAO,oBAAC,eAAD,CAAgB,CAAA;AACzB"}
@@ -22,20 +22,22 @@ var AuthContext = (0, react.createContext)({
22
22
  var configuration = require_configuration.getConfiguration();
23
23
  var basePath = require_utils.stripTrailingSlash(configuration.base);
24
24
  var AuthProvider = ({ children }) => {
25
- const [userState, setUserState] = react.default.useState(require_utils$1.getDefaultUserState());
25
+ const [userState, setUserState] = react.default.useState(require_utils$1.getDefaultUserState);
26
+ react.default.useEffect(() => {
27
+ require_utils$1.clearExpiredAuth();
28
+ }, []);
26
29
  const { trigger } = require_use_data_mutation.useDataMutation(basePath, require_routes.APIRoute.LOGIN, "POST");
27
30
  const { mutate } = (0, swr.useSWRConfig)();
28
31
  const handleLogin = async (body) => {
29
32
  const result = await trigger(body);
30
- if (result && result.username && result.token) {
31
- require_storage.saveAuth(result.username, result.token);
32
- setUserState(result);
33
- mutate(`${basePath}${require_routes.APIRoute.PACKAGES}`);
34
- }
33
+ if (!result || !result.username || !result.token) throw new Error("login response is missing the token");
34
+ require_storage.saveAuth(result.username, result.token);
35
+ setUserState(result);
36
+ mutate(`${basePath}${require_routes.APIRoute.PACKAGES}`);
35
37
  };
36
38
  const logOutUser = () => {
37
- setUserState(require_utils$1.getDefaultUserState());
38
39
  require_storage.clearAuth();
40
+ setUserState(require_utils$1.getDefaultUserState());
39
41
  window.location?.reload();
40
42
  };
41
43
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AuthContext, {
@@ -1 +1 @@
1
- {"version":3,"file":"AuthProvider.js","names":[],"sources":["../../../src/providers/AuthProvider/AuthProvider.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport React, { createContext, use } from 'react';\nimport { useSWRConfig } from 'swr';\n\nimport { useDataMutation } from '../../api/use-data-mutation';\nimport { getConfiguration } from '../../configuration';\nimport { APIRoute } from '../../store/routes';\nimport { clearAuth, saveAuth } from '../../store/storage';\nimport { stripTrailingSlash } from '../../store/utils';\nimport type { LoginBody } from './types';\nimport { getDefaultUserState } from './utils';\n\ninterface AuthContextProps {\n handleLogin: (body: { username: string; password: string }) => Promise<any>;\n setUserState: React.Dispatch<React.SetStateAction<LoginBody>>;\n logOutUser: () => void;\n userState: LoginBody;\n}\n\nexport const AuthContext = createContext<Partial<AuthContextProps>>({\n userState: { token: null, username: null },\n setUserState: () => {},\n handleLogin: async () => {},\n logOutUser: () => {},\n});\n\nconst configuration = getConfiguration();\nconst basePath = stripTrailingSlash(configuration.base);\n\nconst AuthProvider: React.FC<{ children: ReactElement }> = ({ children }) => {\n const [userState, setUserState] = React.useState<LoginBody>(getDefaultUserState());\n const { trigger } = useDataMutation<LoginBody>(basePath, APIRoute.LOGIN, 'POST');\n const { mutate } = useSWRConfig();\n\n const handleLogin = async (body: { username: string; password: string }) => {\n const result = await trigger(body);\n if (result && result.username && result.token) {\n saveAuth(result.username, result.token);\n setUserState(result as LoginBody);\n // Revalidate the packages list so it reflects authenticated access\n mutate(`${basePath}${APIRoute.PACKAGES}`);\n }\n };\n\n const logOutUser = () => {\n setUserState(getDefaultUserState());\n clearAuth();\n window.location?.reload();\n };\n\n return (\n <AuthContext\n value={{\n handleLogin,\n userState,\n logOutUser,\n setUserState,\n }}\n >\n {children}\n </AuthContext>\n );\n};\n\nexport { AuthProvider };\n\nexport const useAuth = () => use(AuthContext);\n"],"mappings":";;;;;;;;;;;;AAmBA,IAAa,eAAA,GAAc,MAAA,cAAA,CAAyC;CAClE,WAAW;EAAE,OAAO;EAAM,UAAU;CAAK;CACzC,oBAAoB,CAAC;CACrB,aAAa,YAAY,CAAC;CAC1B,kBAAkB,CAAC;AACrB,CAAC;AAED,IAAM,gBAAgB,sBAAA,iBAAiB;AACvC,IAAM,WAAW,cAAA,mBAAmB,cAAc,IAAI;AAEtD,IAAM,gBAAsD,EAAE,eAAe;CAC3E,MAAM,CAAC,WAAW,gBAAgB,MAAA,QAAM,SAAoB,gBAAA,oBAAoB,CAAC;CACjF,MAAM,EAAE,YAAY,0BAAA,gBAA2B,UAAU,eAAA,SAAS,OAAO,MAAM;CAC/E,MAAM,EAAE,YAAA,GAAW,IAAA,aAAA,CAAa;CAEhC,MAAM,cAAc,OAAO,SAAiD;EAC1E,MAAM,SAAS,MAAM,QAAQ,IAAI;EACjC,IAAI,UAAU,OAAO,YAAY,OAAO,OAAO;GAC7C,gBAAA,SAAS,OAAO,UAAU,OAAO,KAAK;GACtC,aAAa,MAAmB;GAEhC,OAAO,GAAG,WAAW,eAAA,SAAS,UAAU;EAC1C;CACF;CAEA,MAAM,mBAAmB;EACvB,aAAa,gBAAA,oBAAoB,CAAC;EAClC,gBAAA,UAAU;EACV,OAAO,UAAU,OAAO;CAC1B;CAEA,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;EACE,OAAO;GACL;GACA;GACA;GACA;EACF;EAEC;CACU,CAAA;AAEjB;AAIA,IAAa,iBAAA,GAAgB,MAAA,IAAA,CAAI,WAAW"}
1
+ {"version":3,"file":"AuthProvider.js","names":[],"sources":["../../../src/providers/AuthProvider/AuthProvider.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport React, { createContext, use } from 'react';\nimport { useSWRConfig } from 'swr';\n\nimport { useDataMutation } from '../../api/use-data-mutation';\nimport { getConfiguration } from '../../configuration';\nimport { APIRoute } from '../../store/routes';\nimport { clearAuth, saveAuth } from '../../store/storage';\nimport { stripTrailingSlash } from '../../store/utils';\nimport type { LoginBody } from './types';\nimport { clearExpiredAuth, getDefaultUserState } from './utils';\n\ninterface AuthContextProps {\n handleLogin: (body: { username: string; password: string }) => Promise<any>;\n setUserState: React.Dispatch<React.SetStateAction<LoginBody>>;\n logOutUser: () => void;\n userState: LoginBody;\n}\n\nexport const AuthContext = createContext<Partial<AuthContextProps>>({\n userState: { token: null, username: null },\n setUserState: () => {},\n handleLogin: async () => {},\n logOutUser: () => {},\n});\n\nconst configuration = getConfiguration();\nconst basePath = stripTrailingSlash(configuration.base);\n\nconst AuthProvider: React.FC<{ children: ReactElement }> = ({ children }) => {\n // lazy initializer: reading storage and decoding the JWT on every render is wasted work\n const [userState, setUserState] = React.useState<LoginBody>(getDefaultUserState);\n\n React.useEffect(() => {\n clearExpiredAuth();\n }, []);\n const { trigger } = useDataMutation<LoginBody>(basePath, APIRoute.LOGIN, 'POST');\n const { mutate } = useSWRConfig();\n\n const handleLogin = async (body: { username: string; password: string }) => {\n const result = await trigger(body);\n if (!result || !result.username || !result.token) {\n // a 2xx with an unexpected body (proxy or auth plugin returning html)\n // must not pass as a successful login\n throw new Error('login response is missing the token');\n }\n saveAuth(result.username, result.token);\n setUserState(result as LoginBody);\n // Revalidate the packages list so it reflects authenticated access\n mutate(`${basePath}${APIRoute.PACKAGES}`);\n };\n\n const logOutUser = () => {\n // clear storage first: getDefaultUserState reads it, and the token is\n // still valid at this point, so the old order re-hydrated the session\n clearAuth();\n setUserState(getDefaultUserState());\n window.location?.reload();\n };\n\n return (\n <AuthContext\n value={{\n handleLogin,\n userState,\n logOutUser,\n setUserState,\n }}\n >\n {children}\n </AuthContext>\n );\n};\n\nexport { AuthProvider };\n\nexport const useAuth = () => use(AuthContext);\n"],"mappings":";;;;;;;;;;;;AAmBA,IAAa,eAAA,GAAc,MAAA,cAAA,CAAyC;CAClE,WAAW;EAAE,OAAO;EAAM,UAAU;CAAK;CACzC,oBAAoB,CAAC;CACrB,aAAa,YAAY,CAAC;CAC1B,kBAAkB,CAAC;AACrB,CAAC;AAED,IAAM,gBAAgB,sBAAA,iBAAiB;AACvC,IAAM,WAAW,cAAA,mBAAmB,cAAc,IAAI;AAEtD,IAAM,gBAAsD,EAAE,eAAe;CAE3E,MAAM,CAAC,WAAW,gBAAgB,MAAA,QAAM,SAAoB,gBAAA,mBAAmB;CAE/E,MAAA,QAAM,gBAAgB;EACpB,gBAAA,iBAAiB;CACnB,GAAG,CAAC,CAAC;CACL,MAAM,EAAE,YAAY,0BAAA,gBAA2B,UAAU,eAAA,SAAS,OAAO,MAAM;CAC/E,MAAM,EAAE,YAAA,GAAW,IAAA,aAAA,CAAa;CAEhC,MAAM,cAAc,OAAO,SAAiD;EAC1E,MAAM,SAAS,MAAM,QAAQ,IAAI;EACjC,IAAI,CAAC,UAAU,CAAC,OAAO,YAAY,CAAC,OAAO,OAGzC,MAAM,IAAI,MAAM,qCAAqC;EAEvD,gBAAA,SAAS,OAAO,UAAU,OAAO,KAAK;EACtC,aAAa,MAAmB;EAEhC,OAAO,GAAG,WAAW,eAAA,SAAS,UAAU;CAC1C;CAEA,MAAM,mBAAmB;EAGvB,gBAAA,UAAU;EACV,aAAa,gBAAA,oBAAoB,CAAC;EAClC,OAAO,UAAU,OAAO;CAC1B;CAEA,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;EACE,OAAO;GACL;GACA;GACA;GACA;EACF;EAEC;CACU,CAAA;AAEjB;AAIA,IAAa,iBAAA,GAAgB,MAAA,IAAA,CAAI,WAAW"}
@@ -3,7 +3,7 @@ import { getConfiguration } from "../../configuration.mjs";
3
3
  import { APIRoute } from "../../store/routes.mjs";
4
4
  import { stripTrailingSlash } from "../../store/utils.mjs";
5
5
  import { useDataMutation } from "../../api/use-data-mutation.mjs";
6
- import { getDefaultUserState } from "./utils.mjs";
6
+ import { clearExpiredAuth, getDefaultUserState } from "./utils.mjs";
7
7
  import React, { createContext, use } from "react";
8
8
  import { jsx } from "react/jsx-runtime";
9
9
  import { useSWRConfig } from "swr";
@@ -20,20 +20,22 @@ var AuthContext = createContext({
20
20
  var configuration = getConfiguration();
21
21
  var basePath = stripTrailingSlash(configuration.base);
22
22
  var AuthProvider = ({ children }) => {
23
- const [userState, setUserState] = React.useState(getDefaultUserState());
23
+ const [userState, setUserState] = React.useState(getDefaultUserState);
24
+ React.useEffect(() => {
25
+ clearExpiredAuth();
26
+ }, []);
24
27
  const { trigger } = useDataMutation(basePath, APIRoute.LOGIN, "POST");
25
28
  const { mutate } = useSWRConfig();
26
29
  const handleLogin = async (body) => {
27
30
  const result = await trigger(body);
28
- if (result && result.username && result.token) {
29
- saveAuth(result.username, result.token);
30
- setUserState(result);
31
- mutate(`${basePath}${APIRoute.PACKAGES}`);
32
- }
31
+ if (!result || !result.username || !result.token) throw new Error("login response is missing the token");
32
+ saveAuth(result.username, result.token);
33
+ setUserState(result);
34
+ mutate(`${basePath}${APIRoute.PACKAGES}`);
33
35
  };
34
36
  const logOutUser = () => {
35
- setUserState(getDefaultUserState());
36
37
  clearAuth();
38
+ setUserState(getDefaultUserState());
37
39
  window.location?.reload();
38
40
  };
39
41
  return /* @__PURE__ */ jsx(AuthContext, {
@@ -1 +1 @@
1
- {"version":3,"file":"AuthProvider.mjs","names":[],"sources":["../../../src/providers/AuthProvider/AuthProvider.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport React, { createContext, use } from 'react';\nimport { useSWRConfig } from 'swr';\n\nimport { useDataMutation } from '../../api/use-data-mutation';\nimport { getConfiguration } from '../../configuration';\nimport { APIRoute } from '../../store/routes';\nimport { clearAuth, saveAuth } from '../../store/storage';\nimport { stripTrailingSlash } from '../../store/utils';\nimport type { LoginBody } from './types';\nimport { getDefaultUserState } from './utils';\n\ninterface AuthContextProps {\n handleLogin: (body: { username: string; password: string }) => Promise<any>;\n setUserState: React.Dispatch<React.SetStateAction<LoginBody>>;\n logOutUser: () => void;\n userState: LoginBody;\n}\n\nexport const AuthContext = createContext<Partial<AuthContextProps>>({\n userState: { token: null, username: null },\n setUserState: () => {},\n handleLogin: async () => {},\n logOutUser: () => {},\n});\n\nconst configuration = getConfiguration();\nconst basePath = stripTrailingSlash(configuration.base);\n\nconst AuthProvider: React.FC<{ children: ReactElement }> = ({ children }) => {\n const [userState, setUserState] = React.useState<LoginBody>(getDefaultUserState());\n const { trigger } = useDataMutation<LoginBody>(basePath, APIRoute.LOGIN, 'POST');\n const { mutate } = useSWRConfig();\n\n const handleLogin = async (body: { username: string; password: string }) => {\n const result = await trigger(body);\n if (result && result.username && result.token) {\n saveAuth(result.username, result.token);\n setUserState(result as LoginBody);\n // Revalidate the packages list so it reflects authenticated access\n mutate(`${basePath}${APIRoute.PACKAGES}`);\n }\n };\n\n const logOutUser = () => {\n setUserState(getDefaultUserState());\n clearAuth();\n window.location?.reload();\n };\n\n return (\n <AuthContext\n value={{\n handleLogin,\n userState,\n logOutUser,\n setUserState,\n }}\n >\n {children}\n </AuthContext>\n );\n};\n\nexport { AuthProvider };\n\nexport const useAuth = () => use(AuthContext);\n"],"mappings":";;;;;;;;;;AAmBA,IAAa,cAAc,cAAyC;CAClE,WAAW;EAAE,OAAO;EAAM,UAAU;CAAK;CACzC,oBAAoB,CAAC;CACrB,aAAa,YAAY,CAAC;CAC1B,kBAAkB,CAAC;AACrB,CAAC;AAED,IAAM,gBAAgB,iBAAiB;AACvC,IAAM,WAAW,mBAAmB,cAAc,IAAI;AAEtD,IAAM,gBAAsD,EAAE,eAAe;CAC3E,MAAM,CAAC,WAAW,gBAAgB,MAAM,SAAoB,oBAAoB,CAAC;CACjF,MAAM,EAAE,YAAY,gBAA2B,UAAU,SAAS,OAAO,MAAM;CAC/E,MAAM,EAAE,WAAW,aAAa;CAEhC,MAAM,cAAc,OAAO,SAAiD;EAC1E,MAAM,SAAS,MAAM,QAAQ,IAAI;EACjC,IAAI,UAAU,OAAO,YAAY,OAAO,OAAO;GAC7C,SAAS,OAAO,UAAU,OAAO,KAAK;GACtC,aAAa,MAAmB;GAEhC,OAAO,GAAG,WAAW,SAAS,UAAU;EAC1C;CACF;CAEA,MAAM,mBAAmB;EACvB,aAAa,oBAAoB,CAAC;EAClC,UAAU;EACV,OAAO,UAAU,OAAO;CAC1B;CAEA,OACE,oBAAC,aAAD;EACE,OAAO;GACL;GACA;GACA;GACA;EACF;EAEC;CACU,CAAA;AAEjB;AAIA,IAAa,gBAAgB,IAAI,WAAW"}
1
+ {"version":3,"file":"AuthProvider.mjs","names":[],"sources":["../../../src/providers/AuthProvider/AuthProvider.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport React, { createContext, use } from 'react';\nimport { useSWRConfig } from 'swr';\n\nimport { useDataMutation } from '../../api/use-data-mutation';\nimport { getConfiguration } from '../../configuration';\nimport { APIRoute } from '../../store/routes';\nimport { clearAuth, saveAuth } from '../../store/storage';\nimport { stripTrailingSlash } from '../../store/utils';\nimport type { LoginBody } from './types';\nimport { clearExpiredAuth, getDefaultUserState } from './utils';\n\ninterface AuthContextProps {\n handleLogin: (body: { username: string; password: string }) => Promise<any>;\n setUserState: React.Dispatch<React.SetStateAction<LoginBody>>;\n logOutUser: () => void;\n userState: LoginBody;\n}\n\nexport const AuthContext = createContext<Partial<AuthContextProps>>({\n userState: { token: null, username: null },\n setUserState: () => {},\n handleLogin: async () => {},\n logOutUser: () => {},\n});\n\nconst configuration = getConfiguration();\nconst basePath = stripTrailingSlash(configuration.base);\n\nconst AuthProvider: React.FC<{ children: ReactElement }> = ({ children }) => {\n // lazy initializer: reading storage and decoding the JWT on every render is wasted work\n const [userState, setUserState] = React.useState<LoginBody>(getDefaultUserState);\n\n React.useEffect(() => {\n clearExpiredAuth();\n }, []);\n const { trigger } = useDataMutation<LoginBody>(basePath, APIRoute.LOGIN, 'POST');\n const { mutate } = useSWRConfig();\n\n const handleLogin = async (body: { username: string; password: string }) => {\n const result = await trigger(body);\n if (!result || !result.username || !result.token) {\n // a 2xx with an unexpected body (proxy or auth plugin returning html)\n // must not pass as a successful login\n throw new Error('login response is missing the token');\n }\n saveAuth(result.username, result.token);\n setUserState(result as LoginBody);\n // Revalidate the packages list so it reflects authenticated access\n mutate(`${basePath}${APIRoute.PACKAGES}`);\n };\n\n const logOutUser = () => {\n // clear storage first: getDefaultUserState reads it, and the token is\n // still valid at this point, so the old order re-hydrated the session\n clearAuth();\n setUserState(getDefaultUserState());\n window.location?.reload();\n };\n\n return (\n <AuthContext\n value={{\n handleLogin,\n userState,\n logOutUser,\n setUserState,\n }}\n >\n {children}\n </AuthContext>\n );\n};\n\nexport { AuthProvider };\n\nexport const useAuth = () => use(AuthContext);\n"],"mappings":";;;;;;;;;;AAmBA,IAAa,cAAc,cAAyC;CAClE,WAAW;EAAE,OAAO;EAAM,UAAU;CAAK;CACzC,oBAAoB,CAAC;CACrB,aAAa,YAAY,CAAC;CAC1B,kBAAkB,CAAC;AACrB,CAAC;AAED,IAAM,gBAAgB,iBAAiB;AACvC,IAAM,WAAW,mBAAmB,cAAc,IAAI;AAEtD,IAAM,gBAAsD,EAAE,eAAe;CAE3E,MAAM,CAAC,WAAW,gBAAgB,MAAM,SAAoB,mBAAmB;CAE/E,MAAM,gBAAgB;EACpB,iBAAiB;CACnB,GAAG,CAAC,CAAC;CACL,MAAM,EAAE,YAAY,gBAA2B,UAAU,SAAS,OAAO,MAAM;CAC/E,MAAM,EAAE,WAAW,aAAa;CAEhC,MAAM,cAAc,OAAO,SAAiD;EAC1E,MAAM,SAAS,MAAM,QAAQ,IAAI;EACjC,IAAI,CAAC,UAAU,CAAC,OAAO,YAAY,CAAC,OAAO,OAGzC,MAAM,IAAI,MAAM,qCAAqC;EAEvD,SAAS,OAAO,UAAU,OAAO,KAAK;EACtC,aAAa,MAAmB;EAEhC,OAAO,GAAG,WAAW,SAAS,UAAU;CAC1C;CAEA,MAAM,mBAAmB;EAGvB,UAAU;EACV,aAAa,oBAAoB,CAAC;EAClC,OAAO,UAAU,OAAO;CAC1B;CAEA,OACE,oBAAC,aAAD;EACE,OAAO;GACL;GACA;GACA;GACA;EACF;EAEC;CACU,CAAA;AAEjB;AAIA,IAAa,gBAAgB,IAAI,WAAW"}
@@ -1,3 +1,15 @@
1
1
  import type { LoginBody } from './types';
2
2
  export declare function getDefaultUserState(): LoginBody;
3
+ /**
4
+ * Drop an expired token from storage on boot: the api client attaches whatever
5
+ * is stored, and the server treats an expired bearer as anonymous while the
6
+ * header still claims the user is logged in.
7
+ */
8
+ export declare function clearExpiredAuth(): void;
9
+ export declare const AUTH_ERROR_FALLBACK = "Authentication failed";
3
10
  export declare function normalizeAuthError(err: any): Error;
11
+ /**
12
+ * Message to display for a failed auth request: the server's own message when
13
+ * there is one, otherwise the (already translated) fallback text.
14
+ */
15
+ export declare function authErrorMessage(err: any, translatedFallback: string): string;
@@ -12,11 +12,33 @@ function getDefaultUserState() {
12
12
  username
13
13
  };
14
14
  }
15
+ /**
16
+ * Drop an expired token from storage on boot: the api client attaches whatever
17
+ * is stored, and the server treats an expired bearer as anonymous while the
18
+ * header still claims the user is logged in.
19
+ */
20
+ function clearExpiredAuth() {
21
+ const { token } = require_storage.getAuth();
22
+ if (token && require_token.isTokenExpire(token)) require_storage.clearAuth();
23
+ }
24
+ var AUTH_ERROR_FALLBACK = "Authentication failed";
15
25
  function normalizeAuthError(err) {
16
26
  const message = err?.info?.message || err?.response?.data?.message || err?.message || "Authentication failed";
17
27
  return new Error(message);
18
28
  }
29
+ /**
30
+ * Message to display for a failed auth request: the server's own message when
31
+ * there is one, otherwise the (already translated) fallback text.
32
+ */
33
+ function authErrorMessage(err, translatedFallback) {
34
+ if (typeof err?.code !== "number") return translatedFallback;
35
+ const { message } = normalizeAuthError(err);
36
+ return message && message !== "Authentication failed" ? message : translatedFallback;
37
+ }
19
38
  //#endregion
39
+ exports.AUTH_ERROR_FALLBACK = AUTH_ERROR_FALLBACK;
40
+ exports.authErrorMessage = authErrorMessage;
41
+ exports.clearExpiredAuth = clearExpiredAuth;
20
42
  exports.getDefaultUserState = getDefaultUserState;
21
43
  exports.normalizeAuthError = normalizeAuthError;
22
44
 
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":[],"sources":["../../../src/providers/AuthProvider/utils.ts"],"sourcesContent":["import { getAuth } from '../../store/storage';\nimport { isTokenExpire } from '../../utils';\nimport type { LoginBody } from './types';\n\nexport function getDefaultUserState(): LoginBody {\n const { token, username } = getAuth();\n return isTokenExpire(token) ? { token: null, username: null } : { token, username };\n}\n\nexport function normalizeAuthError(err: any): Error {\n const message =\n err?.info?.message || err?.response?.data?.message || err?.message || 'Authentication failed';\n\n return new Error(message);\n}\n"],"mappings":";;;;AAIA,SAAgB,sBAAiC;CAC/C,MAAM,EAAE,OAAO,aAAa,gBAAA,QAAQ;CACpC,OAAO,cAAA,cAAc,KAAK,IAAI;EAAE,OAAO;EAAM,UAAU;CAAK,IAAI;EAAE;EAAO;CAAS;AACpF;AAEA,SAAgB,mBAAmB,KAAiB;CAClD,MAAM,UACJ,KAAK,MAAM,WAAW,KAAK,UAAU,MAAM,WAAW,KAAK,WAAW;CAExE,OAAO,IAAI,MAAM,OAAO;AAC1B"}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../../src/providers/AuthProvider/utils.ts"],"sourcesContent":["import { clearAuth, getAuth } from '../../store/storage';\nimport { isTokenExpire } from '../../utils';\nimport type { LoginBody } from './types';\n\nexport function getDefaultUserState(): LoginBody {\n const { token, username } = getAuth();\n return isTokenExpire(token) ? { token: null, username: null } : { token, username };\n}\n\n/**\n * Drop an expired token from storage on boot: the api client attaches whatever\n * is stored, and the server treats an expired bearer as anonymous while the\n * header still claims the user is logged in.\n */\nexport function clearExpiredAuth(): void {\n const { token } = getAuth();\n if (token && isTokenExpire(token)) {\n clearAuth();\n }\n}\n\nexport const AUTH_ERROR_FALLBACK = 'Authentication failed';\n\nexport function normalizeAuthError(err: any): Error {\n const message =\n err?.info?.message || err?.response?.data?.message || err?.message || AUTH_ERROR_FALLBACK;\n\n return new Error(message);\n}\n\n/**\n * Message to display for a failed auth request: the server's own message when\n * there is one, otherwise the (already translated) fallback text.\n */\nexport function authErrorMessage(err: any, translatedFallback: string): string {\n // errors without an HTTP code (network failures, unexpected exceptions) carry\n // technical messages like \"Failed to fetch\" — not something to show the user\n if (typeof err?.code !== 'number') {\n return translatedFallback;\n }\n const { message } = normalizeAuthError(err);\n return message && message !== AUTH_ERROR_FALLBACK ? message : translatedFallback;\n}\n"],"mappings":";;;;AAIA,SAAgB,sBAAiC;CAC/C,MAAM,EAAE,OAAO,aAAa,gBAAA,QAAQ;CACpC,OAAO,cAAA,cAAc,KAAK,IAAI;EAAE,OAAO;EAAM,UAAU;CAAK,IAAI;EAAE;EAAO;CAAS;AACpF;;;;;;AAOA,SAAgB,mBAAyB;CACvC,MAAM,EAAE,UAAU,gBAAA,QAAQ;CAC1B,IAAI,SAAS,cAAA,cAAc,KAAK,GAC9B,gBAAA,UAAU;AAEd;AAEA,IAAa,sBAAsB;AAEnC,SAAgB,mBAAmB,KAAiB;CAClD,MAAM,UACJ,KAAK,MAAM,WAAW,KAAK,UAAU,MAAM,WAAW,KAAK,WAAA;CAE7D,OAAO,IAAI,MAAM,OAAO;AAC1B;;;;;AAMA,SAAgB,iBAAiB,KAAU,oBAAoC;CAG7E,IAAI,OAAO,KAAK,SAAS,UACvB,OAAO;CAET,MAAM,EAAE,YAAY,mBAAmB,GAAG;CAC1C,OAAO,WAAW,YAAA,0BAAkC,UAAU;AAChE"}
@@ -1,6 +1,6 @@
1
1
  import { isTokenExpire } from "../../utils/token.mjs";
2
2
  import "../../utils/index.mjs";
3
- import { getAuth } from "../../store/storage.mjs";
3
+ import { clearAuth, getAuth } from "../../store/storage.mjs";
4
4
  //#region src/providers/AuthProvider/utils.ts
5
5
  function getDefaultUserState() {
6
6
  const { token, username } = getAuth();
@@ -12,11 +12,30 @@ function getDefaultUserState() {
12
12
  username
13
13
  };
14
14
  }
15
+ /**
16
+ * Drop an expired token from storage on boot: the api client attaches whatever
17
+ * is stored, and the server treats an expired bearer as anonymous while the
18
+ * header still claims the user is logged in.
19
+ */
20
+ function clearExpiredAuth() {
21
+ const { token } = getAuth();
22
+ if (token && isTokenExpire(token)) clearAuth();
23
+ }
24
+ var AUTH_ERROR_FALLBACK = "Authentication failed";
15
25
  function normalizeAuthError(err) {
16
26
  const message = err?.info?.message || err?.response?.data?.message || err?.message || "Authentication failed";
17
27
  return new Error(message);
18
28
  }
29
+ /**
30
+ * Message to display for a failed auth request: the server's own message when
31
+ * there is one, otherwise the (already translated) fallback text.
32
+ */
33
+ function authErrorMessage(err, translatedFallback) {
34
+ if (typeof err?.code !== "number") return translatedFallback;
35
+ const { message } = normalizeAuthError(err);
36
+ return message && message !== "Authentication failed" ? message : translatedFallback;
37
+ }
19
38
  //#endregion
20
- export { getDefaultUserState, normalizeAuthError };
39
+ export { AUTH_ERROR_FALLBACK, authErrorMessage, clearExpiredAuth, getDefaultUserState, normalizeAuthError };
21
40
 
22
41
  //# sourceMappingURL=utils.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.mjs","names":[],"sources":["../../../src/providers/AuthProvider/utils.ts"],"sourcesContent":["import { getAuth } from '../../store/storage';\nimport { isTokenExpire } from '../../utils';\nimport type { LoginBody } from './types';\n\nexport function getDefaultUserState(): LoginBody {\n const { token, username } = getAuth();\n return isTokenExpire(token) ? { token: null, username: null } : { token, username };\n}\n\nexport function normalizeAuthError(err: any): Error {\n const message =\n err?.info?.message || err?.response?.data?.message || err?.message || 'Authentication failed';\n\n return new Error(message);\n}\n"],"mappings":";;;;AAIA,SAAgB,sBAAiC;CAC/C,MAAM,EAAE,OAAO,aAAa,QAAQ;CACpC,OAAO,cAAc,KAAK,IAAI;EAAE,OAAO;EAAM,UAAU;CAAK,IAAI;EAAE;EAAO;CAAS;AACpF;AAEA,SAAgB,mBAAmB,KAAiB;CAClD,MAAM,UACJ,KAAK,MAAM,WAAW,KAAK,UAAU,MAAM,WAAW,KAAK,WAAW;CAExE,OAAO,IAAI,MAAM,OAAO;AAC1B"}
1
+ {"version":3,"file":"utils.mjs","names":[],"sources":["../../../src/providers/AuthProvider/utils.ts"],"sourcesContent":["import { clearAuth, getAuth } from '../../store/storage';\nimport { isTokenExpire } from '../../utils';\nimport type { LoginBody } from './types';\n\nexport function getDefaultUserState(): LoginBody {\n const { token, username } = getAuth();\n return isTokenExpire(token) ? { token: null, username: null } : { token, username };\n}\n\n/**\n * Drop an expired token from storage on boot: the api client attaches whatever\n * is stored, and the server treats an expired bearer as anonymous while the\n * header still claims the user is logged in.\n */\nexport function clearExpiredAuth(): void {\n const { token } = getAuth();\n if (token && isTokenExpire(token)) {\n clearAuth();\n }\n}\n\nexport const AUTH_ERROR_FALLBACK = 'Authentication failed';\n\nexport function normalizeAuthError(err: any): Error {\n const message =\n err?.info?.message || err?.response?.data?.message || err?.message || AUTH_ERROR_FALLBACK;\n\n return new Error(message);\n}\n\n/**\n * Message to display for a failed auth request: the server's own message when\n * there is one, otherwise the (already translated) fallback text.\n */\nexport function authErrorMessage(err: any, translatedFallback: string): string {\n // errors without an HTTP code (network failures, unexpected exceptions) carry\n // technical messages like \"Failed to fetch\" — not something to show the user\n if (typeof err?.code !== 'number') {\n return translatedFallback;\n }\n const { message } = normalizeAuthError(err);\n return message && message !== AUTH_ERROR_FALLBACK ? message : translatedFallback;\n}\n"],"mappings":";;;;AAIA,SAAgB,sBAAiC;CAC/C,MAAM,EAAE,OAAO,aAAa,QAAQ;CACpC,OAAO,cAAc,KAAK,IAAI;EAAE,OAAO;EAAM,UAAU;CAAK,IAAI;EAAE;EAAO;CAAS;AACpF;;;;;;AAOA,SAAgB,mBAAyB;CACvC,MAAM,EAAE,UAAU,QAAQ;CAC1B,IAAI,SAAS,cAAc,KAAK,GAC9B,UAAU;AAEd;AAEA,IAAa,sBAAsB;AAEnC,SAAgB,mBAAmB,KAAiB;CAClD,MAAM,UACJ,KAAK,MAAM,WAAW,KAAK,UAAU,MAAM,WAAW,KAAK,WAAA;CAE7D,OAAO,IAAI,MAAM,OAAO;AAC1B;;;;;AAMA,SAAgB,iBAAiB,KAAU,oBAAoC;CAG7E,IAAI,OAAO,KAAK,SAAS,UACvB,OAAO;CAET,MAAM,EAAE,YAAY,mBAAmB,GAAG;CAC1C,OAAO,WAAW,YAAA,0BAAkC,UAAU;AAChE"}
@@ -5,6 +5,7 @@ export interface DownloadContextProps {
5
5
  link: string;
6
6
  }) => Promise<void>;
7
7
  isDownloading: boolean;
8
+ hasDownloadError: boolean;
8
9
  }
9
10
  export declare const DownloadContext: React.Context<DownloadContextProps | undefined>;
10
11
  export declare const DownloadProvider: React.FC<{
@@ -3,27 +3,50 @@ const require_url = require("../../utils/url.js");
3
3
  const require_use_data_mutation = require("../../api/use-data-mutation.js");
4
4
  let react = require("react");
5
5
  react = require_runtime.__toESM(react);
6
+ let react_i18next = require("react-i18next");
6
7
  let react_jsx_runtime = require("react/jsx-runtime");
8
+ let _mui_material_Alert = require("@mui/material/Alert");
9
+ _mui_material_Alert = require_runtime.__toESM(_mui_material_Alert);
10
+ let _mui_material_Snackbar = require("@mui/material/Snackbar");
11
+ _mui_material_Snackbar = require_runtime.__toESM(_mui_material_Snackbar);
7
12
  //#region src/providers/DownloadProvider/DownloadProvider.tsx
8
13
  var DownloadContext = (0, react.createContext)(void 0);
9
14
  var DownloadProvider = ({ children }) => {
15
+ const { t } = (0, react_i18next.useTranslation)();
10
16
  const { download, isDownloading } = require_use_data_mutation.useTarballDownload();
17
+ const [hasDownloadError, setHasDownloadError] = (0, react.useState)(false);
11
18
  const downloadTarball = (0, react.useCallback)(async ({ link }) => {
12
19
  try {
20
+ setHasDownloadError(false);
13
21
  const fileStream = await download({ link });
14
- if (!fileStream) return;
22
+ if (!fileStream) {
23
+ setHasDownloadError(true);
24
+ return;
25
+ }
15
26
  const fileName = require_url.extractFileName(link);
16
27
  require_url.downloadFile(fileStream, fileName);
17
28
  } catch (error) {
18
29
  console.error("Error during tarball download:", error);
30
+ setHasDownloadError(true);
19
31
  }
20
32
  }, [download]);
21
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DownloadContext.Provider, {
33
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(DownloadContext.Provider, {
22
34
  value: {
23
35
  downloadTarball,
24
- isDownloading
36
+ isDownloading,
37
+ hasDownloadError
25
38
  },
26
- children
39
+ children: [children, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Snackbar.default, {
40
+ autoHideDuration: 6e3,
41
+ onClose: () => setHasDownloadError(false),
42
+ open: hasDownloadError,
43
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Alert.default, {
44
+ onClose: () => setHasDownloadError(false),
45
+ severity: "error",
46
+ variant: "filled",
47
+ children: t("error.download-tarball")
48
+ })
49
+ })]
27
50
  });
28
51
  };
29
52
  var useDownload = () => {
@@ -1 +1 @@
1
- {"version":3,"file":"DownloadProvider.js","names":[],"sources":["../../../src/providers/DownloadProvider/DownloadProvider.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport React, { createContext, useCallback, useContext } from 'react';\n\nimport { useTarballDownload } from '../../api/use-data-mutation';\nimport { downloadFile, extractFileName } from '../../utils/url';\n\nexport interface DownloadContextProps {\n downloadTarball: (args: { link: string }) => Promise<void>;\n isDownloading: boolean;\n}\n\nexport const DownloadContext = createContext<DownloadContextProps | undefined>(undefined);\n\nexport const DownloadProvider: React.FC<{ children: ReactNode }> = ({ children }) => {\n const { download, isDownloading } = useTarballDownload();\n\n const downloadTarball = useCallback(\n async ({ link }: { link: string }) => {\n try {\n const fileStream = await download({ link });\n if (!fileStream) return;\n\n const fileName = extractFileName(link);\n downloadFile(fileStream, fileName);\n } catch (error) {\n console.error('Error during tarball download:', error);\n }\n },\n [download]\n );\n\n return (\n <DownloadContext.Provider value={{ downloadTarball, isDownloading }}>\n {children}\n </DownloadContext.Provider>\n );\n};\n\nexport const useDownload = () => {\n const context = useContext(DownloadContext);\n if (!context) {\n throw new Error('useDownload must be used within a DownloadProvider');\n }\n return context;\n};\n"],"mappings":";;;;;;;AAWA,IAAa,mBAAA,GAAkB,MAAA,cAAA,CAAgD,KAAA,CAAS;AAExF,IAAa,oBAAuD,EAAE,eAAe;CACnF,MAAM,EAAE,UAAU,kBAAkB,0BAAA,mBAAmB;CAEvD,MAAM,mBAAA,GAAkB,MAAA,YAAA,CACtB,OAAO,EAAE,WAA6B;EACpC,IAAI;GACF,MAAM,aAAa,MAAM,SAAS,EAAE,KAAK,CAAC;GAC1C,IAAI,CAAC,YAAY;GAEjB,MAAM,WAAW,YAAA,gBAAgB,IAAI;GACrC,YAAA,aAAa,YAAY,QAAQ;EACnC,SAAS,OAAO;GACd,QAAQ,MAAM,kCAAkC,KAAK;EACvD;CACF,GACA,CAAC,QAAQ,CACX;CAEA,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,gBAAgB,UAAjB;EAA0B,OAAO;GAAE;GAAiB;EAAc;EAC/D;CACuB,CAAA;AAE9B;AAEA,IAAa,oBAAoB;CAC/B,MAAM,WAAA,GAAU,MAAA,WAAA,CAAW,eAAe;CAC1C,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,oDAAoD;CAEtE,OAAO;AACT"}
1
+ {"version":3,"file":"DownloadProvider.js","names":[],"sources":["../../../src/providers/DownloadProvider/DownloadProvider.tsx"],"sourcesContent":["import Alert from '@mui/material/Alert';\nimport Snackbar from '@mui/material/Snackbar';\nimport type { ReactNode } from 'react';\nimport React, { createContext, useCallback, useContext, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { useTarballDownload } from '../../api/use-data-mutation';\nimport { downloadFile, extractFileName } from '../../utils/url';\n\nexport interface DownloadContextProps {\n downloadTarball: (args: { link: string }) => Promise<void>;\n isDownloading: boolean;\n hasDownloadError: boolean;\n}\n\nexport const DownloadContext = createContext<DownloadContextProps | undefined>(undefined);\n\nexport const DownloadProvider: React.FC<{ children: ReactNode }> = ({ children }) => {\n const { t } = useTranslation();\n const { download, isDownloading } = useTarballDownload();\n const [hasDownloadError, setHasDownloadError] = useState(false);\n\n const downloadTarball = useCallback(\n async ({ link }: { link: string }) => {\n try {\n setHasDownloadError(false);\n const fileStream = await download({ link });\n if (!fileStream) {\n // clicking download and having nothing happen sends the user\n // retrying blindly; an empty response is an error too\n setHasDownloadError(true);\n return;\n }\n\n const fileName = extractFileName(link);\n downloadFile(fileStream, fileName);\n } catch (error) {\n console.error('Error during tarball download:', error);\n setHasDownloadError(true);\n }\n },\n [download]\n );\n\n return (\n <DownloadContext.Provider value={{ downloadTarball, isDownloading, hasDownloadError }}>\n {children}\n <Snackbar\n autoHideDuration={6000}\n onClose={() => setHasDownloadError(false)}\n open={hasDownloadError}\n >\n {/* @ts-ignore - Alert does accept children despite the type error */}\n <Alert onClose={() => setHasDownloadError(false)} severity=\"error\" variant=\"filled\">\n {t('error.download-tarball')}\n </Alert>\n </Snackbar>\n </DownloadContext.Provider>\n );\n};\n\nexport const useDownload = () => {\n const context = useContext(DownloadContext);\n if (!context) {\n throw new Error('useDownload must be used within a DownloadProvider');\n }\n return context;\n};\n"],"mappings":";;;;;;;;;;;;AAeA,IAAa,mBAAA,GAAkB,MAAA,cAAA,CAAgD,KAAA,CAAS;AAExF,IAAa,oBAAuD,EAAE,eAAe;CACnF,MAAM,EAAE,OAAA,GAAM,cAAA,eAAA,CAAe;CAC7B,MAAM,EAAE,UAAU,kBAAkB,0BAAA,mBAAmB;CACvD,MAAM,CAAC,kBAAkB,wBAAA,GAAuB,MAAA,SAAA,CAAS,KAAK;CAE9D,MAAM,mBAAA,GAAkB,MAAA,YAAA,CACtB,OAAO,EAAE,WAA6B;EACpC,IAAI;GACF,oBAAoB,KAAK;GACzB,MAAM,aAAa,MAAM,SAAS,EAAE,KAAK,CAAC;GAC1C,IAAI,CAAC,YAAY;IAGf,oBAAoB,IAAI;IACxB;GACF;GAEA,MAAM,WAAW,YAAA,gBAAgB,IAAI;GACrC,YAAA,aAAa,YAAY,QAAQ;EACnC,SAAS,OAAO;GACd,QAAQ,MAAM,kCAAkC,KAAK;GACrD,oBAAoB,IAAI;EAC1B;CACF,GACA,CAAC,QAAQ,CACX;CAEA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,gBAAgB,UAAjB;EAA0B,OAAO;GAAE;GAAiB;GAAe;EAAiB;EAApF,UAAA,CACG,UACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,uBAAA,SAAD;GACE,kBAAkB;GAClB,eAAe,oBAAoB,KAAK;GACxC,MAAM;GAGN,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,oBAAA,SAAD;IAAO,eAAe,oBAAoB,KAAK;IAAG,UAAS;IAAQ,SAAQ;IACxE,UAAA,EAAE,wBAAwB;GACtB,CAAA;EACC,CAAA,CACc;;AAE9B;AAEA,IAAa,oBAAoB;CAC/B,MAAM,WAAA,GAAU,MAAA,WAAA,CAAW,eAAe;CAC1C,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,oDAAoD;CAEtE,OAAO;AACT"}