{"version":3,"file":"express.cjs","names":["frameworkName: SupportedFrameworkName","InngestCommHandler"],"sources":["../src/express.ts"],"sourcesContent":["/**\n * An adapter for Express to serve and register any declared functions with\n * Inngest, making them available to be triggered by events.\n *\n * @example\n * ```ts\n * import { serve } from \"inngest/express\";\n * import { inngest } from \"./src/inngest/client\";\n * import fnA from \"./src/inngest/fnA\"; // Your own function\n *\n * // Important:  ensure you add JSON middleware to process incoming JSON POST payloads.\n * app.use(express.json());\n * app.use(\n *   // Expose the middleware on our recommended path at `/api/inngest`.\n *   \"/api/inngest\",\n *   serve({ client: inngest, functions: [fnA] })\n * );\n * ```\n *\n * @module\n */\n\nimport type { VercelRequest, VercelResponse } from \"@vercel/node\";\nimport type { Request, Response } from \"express\";\nimport {\n  InngestCommHandler,\n  type ServeHandlerOptions,\n} from \"./components/InngestCommHandler.ts\";\nimport type { Either } from \"./helpers/types.ts\";\nimport type { SupportedFrameworkName } from \"./types.ts\";\n\n/**\n * The name of the framework, used to identify the framework in Inngest\n * dashboards and during testing.\n */\nexport const frameworkName: SupportedFrameworkName = \"express\";\n\n/**\n * Serve and register any declared functions with Inngest, making them available\n * to be triggered by events.\n *\n * The return type is currently `any` to ensure there's no required type matches\n * between the `express` and `vercel` packages. This may change in the future to\n * appropriately infer.\n *\n * @example\n * ```ts\n * import { serve } from \"inngest/express\";\n * import { inngest } from \"./src/inngest/client\";\n * import fnA from \"./src/inngest/fnA\"; // Your own function\n *\n * // Important:  ensure you add JSON middleware to process incoming JSON POST payloads.\n * app.use(express.json());\n * app.use(\n *   // Expose the middleware on our recommended path at `/api/inngest`.\n *   \"/api/inngest\",\n *   serve({ client: inngest, functions: [fnA] })\n * );\n * ```\n *\n * @public\n */\n// Has explicit return type to avoid JSR-defined \"slow types\"\n// biome-ignore lint/suspicious/noExplicitAny: intentional\nexport const serve = (options: ServeHandlerOptions): any => {\n  const handler = new InngestCommHandler({\n    frameworkName,\n    ...options,\n    handler: (\n      req: Either<VercelRequest, Request>,\n      res: Either<Response, VercelResponse>,\n    ) => {\n      return {\n        body: () => req.body,\n        headers: (key) => {\n          const header = req.headers[key];\n          return Array.isArray(header) ? header[0] : header;\n        },\n        method: () => req.method || \"GET\",\n        url: () => {\n          // `req.hostname` can filter out port numbers; beware!\n          const hostname = req.headers[\"host\"] || options?.serveOrigin;\n\n          const protocol = hostname?.includes(\"://\")\n            ? \"\"\n            : `${req.protocol || \"https\"}://`;\n\n          const url = new URL(\n            req.originalUrl || req.url || \"\",\n            `${protocol}${hostname || \"\"}`,\n          );\n\n          return url;\n        },\n        queryString: (key) => {\n          const qs = req.query[key];\n          return Array.isArray(qs) ? qs[0] : qs;\n        },\n        transformResponse: ({ body, headers, status }) => {\n          for (const [name, value] of Object.entries(headers)) {\n            res.setHeader(name, value);\n          }\n\n          return res.status(status).send(body);\n        },\n\n        /**\n         * Express doesn't support a Web API `ReadableStream` being written as\n         * the response body (only `node:stream` `ReadableStream`s), so we\n         * manually read the stream we're given and call `res.write()` for each\n         * chunk.\n         *\n         * See {@link https://github.com/expressjs/discussions/issues/288}.\n         *\n         * Alternatively, we could pipe this through a transform and create a\n         * Node stream, but the feels more dangerous than just writing directly\n         * to the response.\n         */\n        transformStreamingResponse: async ({ body, headers, status }) => {\n          for (const [name, value] of Object.entries(headers)) {\n            res.setHeader(name, value);\n          }\n\n          res.status(status);\n\n          const reader = body.getReader();\n          try {\n            // Keep writing from the stream until it's done\n            let done = false;\n            while (!done) {\n              const result = await reader.read();\n              done = result.done;\n              if (!done) {\n                res.write(result.value);\n              }\n            }\n            res.end();\n          } catch (error) {\n            if (error instanceof Error) {\n              res.destroy(error);\n            } else {\n              res.destroy(new Error(String(error)));\n            }\n          }\n        },\n      };\n    },\n  });\n\n  return handler.createHandler();\n};\n"],"mappings":";;;;;;;AAmCA,MAAaA,gBAAwC;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BrD,MAAa,SAAS,YAAsC;AAqF1D,QApFgB,IAAIC,8CAAmB;EACrC;EACA,GAAG;EACH,UACE,KACA,QACG;AACH,UAAO;IACL,YAAY,IAAI;IAChB,UAAU,QAAQ;KAChB,MAAM,SAAS,IAAI,QAAQ;AAC3B,YAAO,MAAM,QAAQ,OAAO,GAAG,OAAO,KAAK;;IAE7C,cAAc,IAAI,UAAU;IAC5B,WAAW;KAET,MAAM,WAAW,IAAI,QAAQ,WAAW,SAAS;KAEjD,MAAM,WAAW,UAAU,SAAS,MAAM,GACtC,KACA,GAAG,IAAI,YAAY,QAAQ;AAO/B,YALY,IAAI,IACd,IAAI,eAAe,IAAI,OAAO,IAC9B,GAAG,WAAW,YAAY,KAC3B;;IAIH,cAAc,QAAQ;KACpB,MAAM,KAAK,IAAI,MAAM;AACrB,YAAO,MAAM,QAAQ,GAAG,GAAG,GAAG,KAAK;;IAErC,oBAAoB,EAAE,MAAM,SAAS,aAAa;AAChD,UAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,QAAQ,CACjD,KAAI,UAAU,MAAM,MAAM;AAG5B,YAAO,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK;;IAetC,4BAA4B,OAAO,EAAE,MAAM,SAAS,aAAa;AAC/D,UAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,QAAQ,CACjD,KAAI,UAAU,MAAM,MAAM;AAG5B,SAAI,OAAO,OAAO;KAElB,MAAM,SAAS,KAAK,WAAW;AAC/B,SAAI;MAEF,IAAI,OAAO;AACX,aAAO,CAAC,MAAM;OACZ,MAAM,SAAS,MAAM,OAAO,MAAM;AAClC,cAAO,OAAO;AACd,WAAI,CAAC,KACH,KAAI,MAAM,OAAO,MAAM;;AAG3B,UAAI,KAAK;cACF,OAAO;AACd,UAAI,iBAAiB,MACnB,KAAI,QAAQ,MAAM;UAElB,KAAI,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC,CAAC;;;IAI5C;;EAEJ,CAAC,CAEa,eAAe"}