11import { NextRequest , NextResponse } from "next/server"
22import { env , makeAPIErrorResponse , makeUnauthenticatedAPIErrorResponse } from "@/common"
33import { session } from "@/composition"
4+ import { parse as parseYaml } from "yaml"
45
56const ErrorName = {
67 MAX_FILE_SIZE_EXCEEDED : "MaxFileSizeExceededError" ,
7- TIMEOUT : "TimeoutError"
8+ TIMEOUT : "TimeoutError" ,
9+ NOT_JSON_OR_YAML : "NotJsonOrYamlError" ,
810}
911
1012export async function GET ( req : NextRequest ) {
@@ -26,8 +28,9 @@ export async function GET(req: NextRequest) {
2628 const maxMegabytes = Number ( env . getOrThrow ( "PROXY_API_MAXIMUM_FILE_SIZE_IN_MEGABYTES" ) )
2729 const timeoutInSeconds = Number ( env . getOrThrow ( "PROXY_API_TIMEOUT_IN_SECONDS" ) )
2830 const maxBytes = maxMegabytes * 1024 * 1024
29- const file = await downloadFile ( { url, maxBytes, timeoutInSeconds } )
30- return new NextResponse ( file , { status : 200 } )
31+ const fileText = await downloadFile ( { url, maxBytes, timeoutInSeconds } )
32+ checkIfJsonOrYaml ( fileText )
33+ return new NextResponse ( fileText , { status : 200 } )
3134 } catch ( error ) {
3235 if ( error instanceof Error == false ) {
3336 return makeAPIErrorResponse ( 500 , "An unknown error occurred." )
@@ -36,6 +39,8 @@ export async function GET(req: NextRequest) {
3639 return makeAPIErrorResponse ( 413 , "The operation was aborted." )
3740 } else if ( error . name === ErrorName . TIMEOUT ) {
3841 return makeAPIErrorResponse ( 408 , "The operation timed out." )
42+ } else if ( error . name === ErrorName . NOT_JSON_OR_YAML ) {
43+ return makeAPIErrorResponse ( 400 , "Url does not point to a JSON or YAML file." )
3944 } else {
4045 return makeAPIErrorResponse ( 500 , error . message )
4146 }
@@ -46,7 +51,7 @@ async function downloadFile(params: {
4651 url : URL ,
4752 maxBytes : number ,
4853 timeoutInSeconds : number
49- } ) : Promise < Blob > {
54+ } ) : Promise < string > {
5055 const { url, maxBytes, timeoutInSeconds } = params
5156 const abortController = new AbortController ( )
5257 const timeoutSignal = AbortSignal . timeout ( timeoutInSeconds * 1000 )
@@ -80,5 +85,18 @@ async function downloadFile(params: {
8085 error . name = ErrorName . MAX_FILE_SIZE_EXCEEDED
8186 throw error
8287 }
83- return new Blob ( chunks )
88+ const blob = new Blob ( chunks )
89+ const arrayBuffer = await blob . arrayBuffer ( )
90+ const decoder = new TextDecoder ( )
91+ return decoder . decode ( arrayBuffer )
92+ }
93+
94+ function checkIfJsonOrYaml ( fileText : string ) {
95+ try {
96+ parseYaml ( fileText ) // will also parse JSON as it is a subset of YAML
97+ } catch {
98+ const error = new Error ( "File is not JSON or YAML" )
99+ error . name = ErrorName . NOT_JSON_OR_YAML
100+ throw error
101+ }
84102}
0 commit comments