@@ -24,7 +24,7 @@ import cors from "cors";
2424import express from "express" ;
2525import fs from "fs" ;
2626import { GraphQLResolveInfo } from "graphql" ;
27- import { HttpsFunction , HttpsOptions , onRequest } from "./https" ;
27+ import { HttpsFunction , HttpsOptions } from "./https" ;
2828import { CloudEvent , CloudFunction } from "../core" ;
2929import { ParamsOf , VarName } from "../../common/params" ;
3030import {
@@ -39,7 +39,11 @@ import { withInit } from "../../common/onInit";
3939import { initV2Endpoint , ManifestEndpoint } from "../../runtime/manifest" ;
4040import { PathPattern } from "../../common/utilities/path-pattern" ;
4141import { Expression } from "../../params" ;
42+ import * as options from "../options" ;
4243import { ResetValue } from "../../common/options" ;
44+ import { withErrorHandler , Request } from "../../common/providers/https" ;
45+ import { isDebugFeatureEnabled } from "../../common/debug" ;
46+ import { convertIfPresent , convertInvoker } from "../../common/encoding" ;
4347
4448/** @internal */
4549export const mutationExecutedEventType =
@@ -423,18 +427,68 @@ let serverPromise: Promise<express.Express> | null = null;
423427 * @returns {HttpsFunction } A function you can export and deploy.
424428 */
425429export function onGraphRequest ( opts : GraphqlServerOptions ) : HttpsFunction {
426- const func = onRequest ( opts , async ( req , res ) => {
427- serverPromise = serverPromise ?? initGraphqlServer ( opts ) ;
428- const app = await serverPromise ;
429- app ( req , res ) ;
430- } ) ;
431- func . __endpoint . dataConnectHttpsTrigger = { } ;
432- const invoker = func . __endpoint . httpsTrigger ?. invoker ;
433- if ( invoker && invoker . length ) {
434- func . __endpoint . dataConnectHttpsTrigger . invoker = invoker ;
430+ let handler : ( req : Request , res : express . Response ) => void | Promise < void > = withErrorHandler (
431+ async ( req : Request , res : express . Response ) => {
432+ serverPromise = serverPromise ?? initGraphqlServer ( opts ) ;
433+ const app = await serverPromise ;
434+ app ( req , res ) ;
435+ }
436+ ) ;
437+
438+ if ( isDebugFeatureEnabled ( "enableCors" ) || "cors" in opts ) {
439+ let origin = opts . cors instanceof Expression ? opts . cors . value ( ) : opts . cors ;
440+ if ( isDebugFeatureEnabled ( "enableCors" ) ) {
441+ // Respect `cors: false` to turn off cors even if debug feature is enabled.
442+ origin = opts . cors === false ? false : true ;
443+ }
444+ // Arrays cause the access-control-allow-origin header to be dynamic based
445+ // on the origin header of the request. If there is only one element in the
446+ // array, this is unnecessary.
447+ if ( Array . isArray ( origin ) && origin . length === 1 ) {
448+ origin = origin [ 0 ] ;
449+ }
450+ const middleware = cors ( { origin } ) ;
451+
452+ const userProvidedHandler = handler ;
453+ handler = ( req : Request , res : express . Response ) : void | Promise < void > => {
454+ return new Promise ( ( resolve ) => {
455+ res . on ( "finish" , resolve ) ;
456+ middleware ( req , res , ( ) => {
457+ resolve ( userProvidedHandler ( req , res ) ) ;
458+ } ) ;
459+ } ) ;
460+ } ;
435461 }
436- delete func . __endpoint . httpsTrigger ;
437- return func ;
462+
463+ handler = wrapTraceContext ( withInit ( handler ) ) ;
464+
465+ const globalOpts = options . getGlobalOptions ( ) ;
466+ const baseOpts = options . optionsToEndpoint ( globalOpts ) ;
467+ // global options calls region a scalar and https allows it to be an array,
468+ // but optionsToTriggerAnnotations handles both cases.
469+ const specificOpts = options . optionsToEndpoint ( opts as options . GlobalOptions ) ;
470+ const endpoint : Partial < ManifestEndpoint > = {
471+ ...initV2Endpoint ( globalOpts , opts ) ,
472+ platform : "gcfv2" ,
473+ ...baseOpts ,
474+ ...specificOpts ,
475+ labels : {
476+ ...baseOpts ?. labels ,
477+ ...specificOpts ?. labels ,
478+ } ,
479+ dataConnectHttpsTrigger : { } ,
480+ } ;
481+ convertIfPresent (
482+ endpoint . dataConnectHttpsTrigger ,
483+ globalOpts ,
484+ "invoker" ,
485+ "invoker" ,
486+ convertInvoker
487+ ) ;
488+ convertIfPresent ( endpoint . dataConnectHttpsTrigger , opts , "invoker" , "invoker" , convertInvoker ) ;
489+ ( handler as HttpsFunction ) . __endpoint = endpoint ;
490+
491+ return handler as HttpsFunction ;
438492}
439493
440494/** Options for configuring the GraphQL server. */
0 commit comments