{"version":3,"sources":["../../../src/server/web/edge-route-module-wrapper.ts"],"sourcesContent":["import type { NextRequest } from './spec-extension/request'\nimport type {\n  AppRouteRouteHandlerContext,\n  AppRouteRouteModule,\n} from '../route-modules/app-route/module'\n\nimport './globals'\n\nimport { adapter, type AdapterOptions } from './adapter'\nimport { IncrementalCache } from '../lib/incremental-cache'\nimport { RouteMatcher } from '../route-matchers/route-matcher'\nimport type { NextFetchEvent } from './spec-extension/fetch-event'\nimport { internal_getCurrentFunctionWaitUntil } from './internal-edge-wait-until'\nimport { getServerUtils } from '../server-utils'\nimport { searchParamsToUrlQuery } from '../../shared/lib/router/utils/querystring'\nimport { CloseController, trackStreamConsumed } from './web-on-close'\nimport { getEdgePreviewProps } from './get-edge-preview-props'\nimport type { NextConfigComplete } from '../config-shared'\n\nexport interface WrapOptions {\n  nextConfig: NextConfigComplete\n}\n\n/**\n * EdgeRouteModuleWrapper is a wrapper around a route module.\n *\n * Note that this class should only be used in the edge runtime.\n */\nexport class EdgeRouteModuleWrapper {\n  private readonly matcher: RouteMatcher\n\n  /**\n   * The constructor is wrapped with private to ensure that it can only be\n   * constructed by the static wrap method.\n   *\n   * @param routeModule the route module to wrap\n   */\n  private constructor(\n    private readonly routeModule: AppRouteRouteModule,\n    private readonly nextConfig: NextConfigComplete\n  ) {\n    // TODO: (wyattjoh) possibly allow the module to define it's own matcher\n    this.matcher = new RouteMatcher(routeModule.definition)\n  }\n\n  /**\n   * This will wrap a module with the EdgeModuleWrapper and return a function\n   * that can be used as a handler for the edge runtime.\n   *\n   * @param module the module to wrap\n   * @param options any options that should be passed to the adapter and\n   *                override the ones passed from the runtime\n   * @returns a function that can be used as a handler for the edge runtime\n   */\n  public static wrap(routeModule: AppRouteRouteModule, options: WrapOptions) {\n    // Create the module wrapper.\n    const wrapper = new EdgeRouteModuleWrapper(routeModule, options.nextConfig)\n\n    // Return the wrapping function.\n    return (opts: AdapterOptions) => {\n      return adapter({\n        ...opts,\n        IncrementalCache,\n        // Bind the handler method to the wrapper so it still has context.\n        handler: wrapper.handler.bind(wrapper),\n      })\n    }\n  }\n\n  private async handler(\n    request: NextRequest,\n    evt: NextFetchEvent\n  ): Promise<Response> {\n    const utils = getServerUtils({\n      pageIsDynamic: this.matcher.isDynamic,\n      page: this.matcher.definition.pathname,\n      basePath: request.nextUrl.basePath,\n      // We don't need the `handleRewrite` util, so can just pass an empty object\n      rewrites: {},\n      // only used for rewrites, so setting an arbitrary default value here\n      caseSensitive: false,\n    })\n\n    const { params } = utils.normalizeDynamicRouteParams(\n      searchParamsToUrlQuery(request.nextUrl.searchParams),\n      false\n    )\n\n    const waitUntil = evt.waitUntil.bind(evt)\n    const closeController = new CloseController()\n\n    const previewProps = getEdgePreviewProps()\n\n    // Create the context for the handler. This contains the params from the\n    // match (if any).\n    const context: AppRouteRouteHandlerContext = {\n      params,\n      prerenderManifest: {\n        version: 4,\n        routes: {},\n        dynamicRoutes: {},\n        preview: previewProps,\n        notFoundRoutes: [],\n      },\n      renderOpts: {\n        supportsDynamicResponse: true,\n        waitUntil,\n        onClose: closeController.onClose.bind(closeController),\n        onAfterTaskError: undefined,\n        experimental: {\n          cacheComponents: !!process.env.__NEXT_CACHE_COMPONENTS,\n          authInterrupts: !!process.env.__NEXT_EXPERIMENTAL_AUTH_INTERRUPTS,\n        },\n        cacheLifeProfiles: this.nextConfig.experimental.cacheLife,\n      },\n      sharedContext: {\n        buildId: '', // TODO: Populate this properly.\n      },\n    }\n\n    // Get the response from the handler.\n    let res = await this.routeModule.handle(request, context)\n\n    const waitUntilPromises = [internal_getCurrentFunctionWaitUntil()]\n    if (context.renderOpts.pendingWaitUntil) {\n      waitUntilPromises.push(context.renderOpts.pendingWaitUntil)\n    }\n    evt.waitUntil(Promise.all(waitUntilPromises))\n\n    if (!res.body) {\n      // we can delay running it until a bit later --\n      // if it's needed, we'll have a `waitUntil` lock anyway.\n      setTimeout(() => closeController.dispatchClose(), 0)\n    } else {\n      // NOTE: if this is a streaming response, onClose may be called later,\n      // so we can't rely on `closeController.listeners` -- it might be 0 at this point.\n      const trackedBody = trackStreamConsumed(res.body, () =>\n        closeController.dispatchClose()\n      )\n      res = new Response(trackedBody, {\n        status: res.status,\n        statusText: res.statusText,\n        headers: res.headers,\n      })\n    }\n\n    return res\n  }\n}\n"],"names":["adapter","IncrementalCache","RouteMatcher","internal_getCurrentFunctionWaitUntil","getServerUtils","searchParamsToUrlQuery","CloseController","trackStreamConsumed","getEdgePreviewProps","EdgeRouteModuleWrapper","routeModule","nextConfig","matcher","definition","wrap","options","wrapper","opts","handler","bind","request","evt","utils","pageIsDynamic","isDynamic","page","pathname","basePath","nextUrl","rewrites","caseSensitive","params","normalizeDynamicRouteParams","searchParams","waitUntil","closeController","previewProps","context","prerenderManifest","version","routes","dynamicRoutes","preview","notFoundRoutes","renderOpts","supportsDynamicResponse","onClose","onAfterTaskError","undefined","experimental","cacheComponents","process","env","__NEXT_CACHE_COMPONENTS","authInterrupts","__NEXT_EXPERIMENTAL_AUTH_INTERRUPTS","cacheLifeProfiles","cacheLife","sharedContext","buildId","res","handle","waitUntilPromises","pendingWaitUntil","push","Promise","all","body","setTimeout","dispatchClose","trackedBody","Response","status","statusText","headers"],"mappings":"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","ignoreList":[0]}