import { ActionMetadata , Application , ControllerClass , ControllerMetadata , DiContainer , FormDataBody , helpers as oakHelpers , ListenOptions , Router , RouterContext , ServerPlatform , } from "./deps.ts" ; returns { OakPlatform } remarks export function platformOak ( ) ; param app param router returns { OakPlatform } remarks export function platformOak ( app , router ) ; export function platformOak ( app = new Application ( ) , router = new Router ( ) ) { return new OakPlatform ( DiContainer . root ( ) . createChild ( "platform" ) , app , router ) ; } export class OakPlatform extends ServerPlatform { #app : Application ; #router : Router ; constructor ( container , application , router ) { super ( container ) ; this . #app = application ; this . #router = router ; } async postBootstrap ( ) { this . #app . addEventListener ( "listen" , ( { hostname , port , secure } ) => { this . logger . log ( [ `PlatformOak listening on ` , secure ? "https://" : "http://" , hostname ?? "localhost" , `:${ port }` , ] . join ( "" ) ) ; } ) ; await super . postBootstrap ( ) ; this . #app . use ( this . #router . routes ( ) ) ; } addRouteHandler ( _controller , _action , route , _controllerMetadata , actionMetadata , handler ) { const routeHandler = async ( context ) => { const result = await handler ( context ) ; if ( result ) { context . response . body = result ; } } ; switch ( actionMetadata . method ) { case "get" : this . #router . get ( route , routeHandler ) ; break ; case "post" : this . #router . post ( route , routeHandler ) ; break ; case "put" : this . #router . put ( route , routeHandler ) ; break ; case "delete" : this . #router . delete ( route , routeHandler ) ; break ; case "head" : this . #router . head ( route , routeHandler ) ; break ; case "patch" : this . #router . patch ( route , routeHandler ) ; break ; } } addMiddlewareHandler ( handler ) { this . #app . use ( async ( context , next ) => { if ( await handler ( context ) ) { await next ( ) ; } } ) ; } async getContextItem ( kind , context , identifier ) { switch ( kind ) { case "url" : return context . request . url ; case "parameter" : return context . params [ identifier ] ; case "query" : return oakHelpers . getQuery ( context , { mergeParams : true } ) [ identifier ] ; case "body" : if ( context . request . hasBody ) { const body = context . request . body ( ) ; switch ( body . type ) { case "form" : return this . parseFormBody ( await body . value , identifier ) ; case "form-data" : return this . parseFormDataBody ( await body . value . read ( ) , identifier ) ; case "json" : return this . parseJsonBody ( await body . value , identifier ) ; default : return await body . value ; } } return ; case "cookie" : return context . cookies . get ( identifier ) ; case "header" : return context . request . headers . get ( identifier ) ; case "state" : return context . state [ identifier ] ; case "requestState" : { const request = context . request as unknown as { __state : Record < string , unknown > ; } ; let state = request . __state ; if ( ! state ) { return ; } return state [ identifier ] ; } case "request" : return context . request ; case "response" : return context . response ; default : throw new Error ( `Unsupported context data ${ kind }` ) ; } } setContextItem ( kind , context , value , identifier ? , options ? ) { switch ( kind ) { case "body" : context . response . body = value ; break ; case "status" : context . response . status = value ; break ; case "cookie" : context . cookies . set ( identifier , value , options ) ; break ; case "header" : context . response . headers . set ( identifier , value ) ; break ; case "state" : context . state [ identifier ] = value ; break ; case "requestState" : { const request = context . request as unknown as { __state : Record < string , unknown > ; } ; let state = request . __state ; if ( ! state ) { state = { } ; request . __state = state ; } state [ identifier ] = value ; } } } async sendFile ( context , path ) { context . response . body = await Deno . readFile ( path ) ; } /**
     * Start listening for requests
     */ async listen ( options ) { await this . #app . listen ( options ) ; } private parseFormBody ( form , identifier ) { if ( identifier ) { return form . get ( identifier ) ; } return Array . from ( form . entries ( ) ) . reduce ( ( prev , [ currKey , currValue ] ) => ( { ... prev , [ currKey ] : prev [ currKey ] ? Array . isArray ( prev [ currKey ] ) ? [ ... ( prev [ currKey ] as [ ] ) , currValue ] : [ prev [ currKey ] , currValue ] : currValue } ) , { } as Record < string , unknown > ) ; } private parseFormDataBody ( formData , identifier ) { if ( identifier ) { return formData . fields [ identifier ] ; } return formData . fields ; } private parseJsonBody ( json , identifier ) { if ( identifier ) { return json [ identifier ] ; } return json ; } }