|
| 1 | +import "./Versions.css"; |
1 | 2 | import { |
2 | | - getPublicEnvVariables, |
3 | | - getSessionTools, |
4 | | -} from "cyberstorm/security/publicEnvVariables"; |
5 | | -import { rowSemverCompare } from "cyberstorm/utils/semverCompare"; |
6 | | -import { Suspense } from "react"; |
7 | | -import { Await, type LoaderFunctionArgs } from "react-router"; |
8 | | -import { useLoaderData } from "react-router"; |
9 | | - |
10 | | -import { |
11 | | - Heading, |
12 | | - NewLink, |
| 3 | + NewTableSort, |
13 | 4 | NewTable, |
14 | 5 | type NewTableLabels, |
15 | | - NewTableSort, |
| 6 | + Heading, |
16 | 7 | SkeletonBox, |
| 8 | + NewLink, |
17 | 9 | } from "@thunderstore/cyberstorm"; |
18 | | -import { DapperTs } from "@thunderstore/dapper-ts"; |
19 | | - |
20 | | -import "./Versions.css"; |
| 10 | +import { Await, type LoaderFunctionArgs } from "react-router"; |
| 11 | +import { useLoaderData } from "react-router"; |
| 12 | +import { Suspense } from "react"; |
21 | 13 | import { DownloadLink, InstallLink, ModManagerBanner } from "./common"; |
| 14 | +import { rowSemverCompare } from "cyberstorm/utils/semverCompare"; |
| 15 | +import { handleLoaderError } from "cyberstorm/utils/errors/handleLoaderError"; |
| 16 | +import { createNotFoundMapping } from "cyberstorm/utils/errors/loaderMappings"; |
| 17 | +import { throwUserFacingPayloadResponse } from "cyberstorm/utils/errors/userFacingErrorResponse"; |
| 18 | +import { |
| 19 | + NimbusAwaitErrorElement, |
| 20 | + NimbusDefaultRouteErrorBoundary, |
| 21 | +} from "cyberstorm/utils/errors/NimbusErrorBoundary"; |
| 22 | +import { getLoaderTools } from "cyberstorm/utils/getLoaderTools"; |
| 23 | + |
| 24 | +export const packageVersionsErrorMappings = [ |
| 25 | + createNotFoundMapping( |
| 26 | + "Package not found.", |
| 27 | + "We could not find the requested package." |
| 28 | + ), |
| 29 | +]; |
22 | 30 |
|
23 | 31 | export async function loader({ params }: LoaderFunctionArgs) { |
24 | 32 | if (params.communityId && params.namespaceId && params.packageId) { |
25 | | - const publicEnvVariables = getPublicEnvVariables(["VITE_API_URL"]); |
26 | | - const dapper = new DapperTs(() => { |
| 33 | + const { dapper } = getLoaderTools(); |
| 34 | + try { |
| 35 | + const versions = await dapper.getPackageVersions( |
| 36 | + params.namespaceId, |
| 37 | + params.packageId |
| 38 | + ); |
| 39 | + |
27 | 40 | return { |
28 | | - apiHost: publicEnvVariables.VITE_API_URL, |
29 | | - sessionId: undefined, |
| 41 | + communityId: params.communityId, |
| 42 | + namespaceId: params.namespaceId, |
| 43 | + packageId: params.packageId, |
| 44 | + versions, |
30 | 45 | }; |
31 | | - }); |
32 | | - return { |
33 | | - communityId: params.communityId, |
34 | | - namespaceId: params.namespaceId, |
35 | | - packageId: params.packageId, |
36 | | - versions: dapper.getPackageVersions(params.namespaceId, params.packageId), |
37 | | - }; |
| 46 | + } catch (error) { |
| 47 | + handleLoaderError(error, { mappings: packageVersionsErrorMappings }); |
| 48 | + } |
38 | 49 | } |
39 | | - return { |
40 | | - status: "error", |
41 | | - message: "Failed to load versions", |
42 | | - versions: [], |
43 | | - }; |
| 50 | + throwUserFacingPayloadResponse({ |
| 51 | + headline: "Package not found.", |
| 52 | + description: "We could not find the requested package.", |
| 53 | + category: "not_found", |
| 54 | + status: 404, |
| 55 | + }); |
44 | 56 | } |
45 | 57 |
|
46 | | -export async function clientLoader({ params }: LoaderFunctionArgs) { |
| 58 | +export function clientLoader({ params }: LoaderFunctionArgs) { |
47 | 59 | if (params.communityId && params.namespaceId && params.packageId) { |
48 | | - const tools = getSessionTools(); |
49 | | - const dapper = new DapperTs(() => { |
50 | | - return { |
51 | | - apiHost: tools?.getConfig().apiHost, |
52 | | - sessionId: tools?.getConfig().sessionId, |
53 | | - }; |
54 | | - }); |
| 60 | + const { dapper } = getLoaderTools(); |
| 61 | + const versions = dapper.getPackageVersions( |
| 62 | + params.namespaceId, |
| 63 | + params.packageId |
| 64 | + ); |
| 65 | + |
55 | 66 | return { |
56 | 67 | communityId: params.communityId, |
57 | 68 | namespaceId: params.namespaceId, |
58 | 69 | packageId: params.packageId, |
59 | | - versions: dapper.getPackageVersions(params.namespaceId, params.packageId), |
| 70 | + versions, |
60 | 71 | }; |
61 | 72 | } |
62 | | - return { |
63 | | - status: "error", |
64 | | - message: "Failed to load versions", |
65 | | - versions: [], |
66 | | - }; |
| 73 | + throwUserFacingPayloadResponse({ |
| 74 | + headline: "Package not found.", |
| 75 | + description: "We could not find the requested package.", |
| 76 | + category: "not_found", |
| 77 | + status: 404, |
| 78 | + }); |
67 | 79 | } |
68 | 80 |
|
69 | 81 | export default function Versions() { |
70 | | - const { communityId, namespaceId, packageId, status, message, versions } = |
71 | | - useLoaderData<typeof loader | typeof clientLoader>(); |
72 | | - |
73 | | - if (status === "error") { |
74 | | - return <div>{message}</div>; |
75 | | - } |
| 82 | + const { communityId, namespaceId, packageId, versions } = useLoaderData< |
| 83 | + typeof loader | typeof clientLoader |
| 84 | + >(); |
76 | 85 |
|
77 | 86 | return ( |
78 | 87 | <Suspense fallback={<SkeletonBox className="package-versions__skeleton" />}> |
79 | | - <Await resolve={versions}> |
| 88 | + <Await resolve={versions} errorElement={<NimbusAwaitErrorElement />}> |
80 | 89 | {(resolvedValue) => ( |
81 | 90 | <div className="package-versions"> |
82 | 91 | <ModManagerBanner /> |
@@ -135,6 +144,10 @@ export default function Versions() { |
135 | 144 | ); |
136 | 145 | } |
137 | 146 |
|
| 147 | +export function ErrorBoundary() { |
| 148 | + return <NimbusDefaultRouteErrorBoundary />; |
| 149 | +} |
| 150 | + |
138 | 151 | export const columns: NewTableLabels = [ |
139 | 152 | { |
140 | 153 | value: "Version", |
|
0 commit comments