11import { faClock , faDownload } from "@fortawesome/free-solid-svg-icons" ;
22import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" ;
33import {
4- getPublicEnvVariables ,
5- getSessionTools ,
6- } from "cyberstorm/security/publicEnvVariables" ;
4+ NimbusAwaitErrorElement ,
5+ NimbusDefaultRouteErrorBoundary ,
6+ } from "cyberstorm/utils/errors/NimbusErrorBoundary" ;
7+ import { handleLoaderError } from "cyberstorm/utils/errors/handleLoaderError" ;
8+ import { createNotFoundMapping } from "cyberstorm/utils/errors/loaderMappings" ;
9+ import { throwUserFacingPayloadResponse } from "cyberstorm/utils/errors/userFacingErrorResponse" ;
10+ import { getLoaderTools } from "cyberstorm/utils/getLoaderTools" ;
711import { Suspense } from "react" ;
8- import { Await , type LoaderFunctionArgs , useOutletContext } from "react-router" ;
9- import { useLoaderData } from "react-router" ;
12+ import {
13+ Await ,
14+ type LoaderFunctionArgs ,
15+ useLoaderData ,
16+ useOutletContext ,
17+ } from "react-router" ;
1018import ago from "s-ago" ;
11- import { type OutletContextShape } from "~/root" ;
19+ import { CodeBoxHTML } from "~/commonComponents/CodeBoxHTML/CodeBoxHTML" ;
20+ import type { OutletContextShape } from "~/root" ;
1221
1322import {
14- NewAlert as Alert ,
1523 Heading ,
24+ NewAlert ,
1625 NewButton ,
1726 NewIcon ,
1827 SkeletonBox ,
1928 TooltipWrapper ,
2029} from "@thunderstore/cyberstorm" ;
21- import { DapperTs , getPackageSource } from "@thunderstore/dapper-ts" ;
22- import { isApiError } from "@thunderstore/thunderstore-api" ;
2330
24- import { CodeBoxHTML } from "../../../commonComponents/CodeBoxHTML/CodeBoxHTML" ;
2531import "./Source.css" ;
2632
2733type PackageListingOutletContext = OutletContextShape & {
2834 packageDownloadUrl ?: string ;
2935} ;
3036
31- type ResultType = {
32- status : string | null ;
33- message ?: string ;
34- source ?:
35- | Awaited < ReturnType < typeof getPackageSource > >
36- | ReturnType < typeof getPackageSource > ;
37- } ;
38-
3937export async function loader ( { params } : LoaderFunctionArgs ) {
4038 if ( params . namespaceId && params . packageId ) {
41- const publicEnvVariables = getPublicEnvVariables ( [ "VITE_API_URL" ] ) ;
42- const dapper = new DapperTs ( ( ) => {
43- return {
44- apiHost : publicEnvVariables . VITE_API_URL ,
45- sessionId : undefined ,
46- } ;
47- } ) ;
48- let result : ResultType = {
49- status : null ,
50- source : undefined ,
51- message : undefined ,
52- } ;
39+ const { dapper } = getLoaderTools ( ) ;
5340 try {
5441 const source = await dapper . getPackageSource (
5542 params . namespaceId ,
5643 params . packageId
5744 ) ;
58- result = {
59- status : null ,
60- source : source ,
61- message : undefined ,
45+
46+ return {
47+ source,
6248 } ;
6349 } catch ( error ) {
64- if ( isApiError ( error ) ) {
65- if ( error . response . status > 400 ) {
66- result = {
67- status : "error" ,
68- source : undefined ,
69- message : `Failed to load source: ${ error . message } ` ,
70- } ;
71- } else {
72- throw error ;
73- }
74- } else {
75- throw error ;
76- }
50+ handleLoaderError ( error , {
51+ mappings : [
52+ createNotFoundMapping (
53+ "Source not available." ,
54+ "We could not find the requested package source."
55+ ) ,
56+ ] ,
57+ } ) ;
7758 }
78- return result ;
7959 }
80- return {
81- status : "error" ,
82- message : "Failed to load source" ,
83- source : undefined ,
84- } ;
60+ throwUserFacingPayloadResponse ( {
61+ headline : "Source not available." ,
62+ description : "We could not find the requested package source." ,
63+ category : "not_found" ,
64+ status : 404 ,
65+ } ) ;
8566}
8667
87- export async function clientLoader ( { params } : LoaderFunctionArgs ) {
68+ export function clientLoader ( { params } : LoaderFunctionArgs ) {
8869 if ( params . namespaceId && params . packageId ) {
89- const tools = getSessionTools ( ) ;
90- const dapper = new DapperTs ( ( ) => {
91- return {
92- apiHost : tools . getConfig ( ) . apiHost ,
93- sessionId : tools . getConfig ( ) . sessionId ,
94- } ;
95- } ) ;
96- let result : ResultType = {
97- status : null ,
98- source : undefined ,
99- message : undefined ,
70+ const { dapper } = getLoaderTools ( ) ;
71+ const source = dapper . getPackageSource (
72+ params . namespaceId ,
73+ params . packageId
74+ ) ;
75+
76+ return {
77+ source,
10078 } ;
101- try {
102- const source = dapper . getPackageSource (
103- params . namespaceId ,
104- params . packageId
105- ) ;
106- result = {
107- status : null ,
108- source : source ,
109- message : undefined ,
110- } ;
111- } catch ( error ) {
112- result = {
113- status : "error" ,
114- source : undefined ,
115- message : "Failed to load source" ,
116- } ;
117- throw error ;
118- }
119- return result ;
12079 }
121- return {
122- status : "error" ,
123- message : "Failed to load source" ,
124- source : undefined ,
125- } ;
80+ throwUserFacingPayloadResponse ( {
81+ headline : "Source not available." ,
82+ description : "We could not find the requested package source." ,
83+ category : "not_found" ,
84+ status : 404 ,
85+ } ) ;
12686}
12787
12888export default function Source ( ) {
129- const { status, message, source } = useLoaderData <
130- typeof loader | typeof clientLoader
131- > ( ) ;
89+ const { source } = useLoaderData < typeof loader | typeof clientLoader > ( ) ;
13290 const outletContext = useOutletContext ( ) as PackageListingOutletContext ;
13391
134- if ( status === "error" ) {
135- return < div > { message } </ div > ;
136- }
13792 return (
13893 < Suspense fallback = { < SkeletonBox className = "package-source__skeleton" /> } >
139- < Await
140- resolve = { source }
141- errorElement = { < div > Error occurred while loading source</ div > }
142- >
94+ < Await resolve = { source } errorElement = { < NimbusAwaitErrorElement /> } >
14395 { ( resolvedValue ) => {
14496 const decompilations = resolvedValue ?. decompilations ?? [ ] ;
14597 const lastDecompilationDate = resolvedValue ?. last_decompilation_date ;
14698 if ( decompilations . length === 0 ) {
14799 return (
148- < Alert csVariant = "info" > Decompiled source not available.</ Alert >
100+ < NewAlert csVariant = "info" >
101+ Decompiled source not available.
102+ </ NewAlert >
149103 ) ;
150104 }
151105 return decompilations . map ( ( decompilation ) => {
@@ -171,10 +125,10 @@ export default function Source() {
171125 />
172126 </ div >
173127 { decompilation . is_truncated && (
174- < Alert csVariant = "warning" >
128+ < NewAlert csVariant = "warning" >
175129 The result has been truncated due to the large size,
176130 download it to view the full contents!
177- </ Alert >
131+ </ NewAlert >
178132 ) }
179133 < div
180134 className = "package-source__decompilations-file"
@@ -191,6 +145,10 @@ export default function Source() {
191145 ) ;
192146}
193147
148+ export function ErrorBoundary ( ) {
149+ return < NimbusDefaultRouteErrorBoundary /> ;
150+ }
151+
194152const DecompilationDateDisplay = ( props : {
195153 lastDecompilationDate : string | null | undefined ;
196154} ) => {
0 commit comments