UNPKG

13.2 kBSource Map (JSON)View Raw
1{"version":3,"file":"middleware.js","names":["expressBuiltinMiddleware","urlencoded","text","json","raw","printConfigWarnings","warnings","functionObj","length","warning","reporter","warn","property","originalRelativeFilePath","expectedType","JSON","stringify","original","replacedWith","createSetContextFunctionMiddleware","getFunctions","prepareFn","showDebugMessageInResponse","executeFunction","req","res","next","functions","pathFragment","params","find","functionRoute","some","f","matchPath","matchResult","reachMatch","userConfig","pathToFunction","absoluteCompiledFilePath","fnToExecute","require","cache","resolve","fn","config","default","e","message","includes","originalAbsoluteFilePath","undefined","error","headersSent","status","send","sendStatus","createConfig","context","setCookies","_res","cookies","headers","cookie","parse","bodyParserMiddlewareWithConfig","type","bodyParser","bodyParserConfig","verbose","start","Date","now","Promise","end","log","functionMiddlewares","middlewareConfig","setContext","multer","any"],"sources":["../../../src/internal-plugins/functions/middleware.ts"],"sourcesContent":["import { match as reachMatch } from \"@gatsbyjs/reach-router\"\nimport cookie from \"cookie\"\nimport { urlencoded, text, json, raw } from \"express\"\nimport type { RequestHandler, Request, Response, NextFunction } from \"express\"\nimport reporter from \"gatsby-cli/lib/reporter\"\nimport multer from \"multer\"\n\nimport {\n createConfig,\n IGatsbyFunctionConfigProcessed,\n IGatsbyBodyParserConfigProcessed,\n IAPIFunctionWarning,\n} from \"./config\"\nimport type { IGatsbyFunction } from \"../../redux/types\"\n\nconst expressBuiltinMiddleware = {\n urlencoded,\n text,\n json,\n raw,\n}\n\ninterface IGatsbyRequestContext {\n functionObj: IGatsbyFunction\n fnToExecute: (req: Request, res: Response) => void | Promise<void>\n // we massage params early in setContext middleware, but apparently other middlewares\n // reset it, so we will store those on our context and restore later\n params: Request[\"params\"]\n config: IGatsbyFunctionConfigProcessed\n showDebugMessageInResponse: boolean\n}\n\ninterface IGatsbyInternalRequest extends Request {\n context?: IGatsbyRequestContext\n}\n\ntype IGatsbyMiddleware = (\n req: IGatsbyInternalRequest,\n res: Response,\n next: NextFunction\n) => Promise<void> | void\n\ninterface ICreateMiddlewareConfig {\n getFunctions: () => Array<IGatsbyFunction>\n prepareFn?: (functionObj: IGatsbyFunction) => Promise<void> | void\n showDebugMessageInResponse?: boolean\n}\n\nexport function printConfigWarnings(\n warnings: Array<IAPIFunctionWarning>,\n functionObj: IGatsbyFunction\n): void {\n if (warnings.length) {\n for (const warning of warnings) {\n reporter.warn(\n `${\n warning.property\n ? `\\`${warning.property}\\` property of exported config`\n : `Exported config`\n } in \\`${\n functionObj.originalRelativeFilePath\n }\\` is misconfigured.\\nExpected object:\\n\\n${\n warning.expectedType\n }\\n\\nGot:\\n\\n${JSON.stringify(\n warning.original\n )}\\n\\nUsing default:\\n\\n${JSON.stringify(\n warning.replacedWith,\n null,\n 2\n )}`\n )\n }\n }\n}\n\nfunction createSetContextFunctionMiddleware({\n getFunctions,\n prepareFn,\n showDebugMessageInResponse,\n}: ICreateMiddlewareConfig): IGatsbyMiddleware {\n return async function executeFunction(\n req: IGatsbyInternalRequest,\n res: Response,\n next: NextFunction\n ): Promise<void> {\n const functions = getFunctions()\n const { \"0\": pathFragment } = req.params\n\n // Check first for exact matches.\n let functionObj = functions.find(\n ({ functionRoute }) => functionRoute === pathFragment\n )\n\n if (!functionObj) {\n // Check if there's any matchPaths that match.\n // We loop until we find the first match.\n functions.some(f => {\n if (f.matchPath) {\n const matchResult = reachMatch(f.matchPath, pathFragment)\n if (matchResult) {\n req.params = matchResult.params\n if (req.params[`*`]) {\n // Backwards compatability for v3\n // TODO remove in v5\n req.params[`0`] = req.params[`*`]\n }\n functionObj = f\n\n return true\n }\n }\n\n return false\n })\n }\n\n if (functionObj) {\n let userConfig\n if (prepareFn) {\n await prepareFn(functionObj)\n }\n\n const pathToFunction = functionObj.absoluteCompiledFilePath\n let fnToExecute\n try {\n delete require.cache[require.resolve(pathToFunction)]\n const fn = require(pathToFunction)\n userConfig = fn?.config\n\n fnToExecute = (fn && fn.default) || fn\n } catch (e) {\n if (e?.message?.includes(`fnToExecute is not a function`)) {\n e.message = `${functionObj.originalAbsoluteFilePath} does not export a function.`\n }\n\n fnToExecute = undefined\n reporter.error(e)\n if (!res.headersSent) {\n if (showDebugMessageInResponse) {\n res\n .status(500)\n .send(\n `Error when executing function \"${functionObj.originalAbsoluteFilePath}\":<br /><br />${e.message}`\n )\n } else {\n res.sendStatus(500)\n }\n }\n return\n }\n\n if (fnToExecute) {\n const { config, warnings } = createConfig(userConfig)\n\n printConfigWarnings(warnings, functionObj)\n\n req.context = {\n functionObj,\n fnToExecute,\n params: req.params,\n config,\n showDebugMessageInResponse: showDebugMessageInResponse ?? false,\n }\n }\n }\n\n next()\n }\n}\n\nfunction setCookies(\n req: IGatsbyInternalRequest,\n _res: Response,\n next: NextFunction\n): void {\n const cookies = req.headers.cookie\n\n if (!cookies) {\n return next()\n }\n\n req.cookies = cookie.parse(cookies)\n\n return next()\n}\n\nfunction bodyParserMiddlewareWithConfig(\n type: keyof IGatsbyBodyParserConfigProcessed\n): IGatsbyMiddleware {\n return function (\n req: IGatsbyInternalRequest,\n res: Response,\n next: NextFunction\n ): void {\n if (req.context && req.context.config.bodyParser) {\n const bodyParserConfig = req.context.config.bodyParser[type]\n expressBuiltinMiddleware[type](bodyParserConfig)(req, res, next)\n } else {\n next()\n }\n }\n}\n\nasync function executeFunction(\n req: IGatsbyInternalRequest,\n res: Response,\n next: NextFunction\n): Promise<void> {\n if (req.context) {\n reporter.verbose(`Running ${req.context.functionObj.functionRoute}`)\n req.params = req.context.params\n const start = Date.now()\n const context = req.context\n // we don't want to leak internal context to actual request handler\n delete req.context\n try {\n await Promise.resolve(context.fnToExecute(req, res))\n } catch (e) {\n if (e?.message?.includes(`fnToExecute is not a function`)) {\n e.message = `${context.functionObj.originalAbsoluteFilePath} does not export a function.`\n }\n\n reporter.error(e)\n // Don't send the error if that would cause another error.\n if (!res.headersSent) {\n if (context.showDebugMessageInResponse) {\n res\n .status(500)\n .send(\n `Error when executing function \"${context.functionObj.originalAbsoluteFilePath}\":<br /><br />${e.message}`\n )\n } else {\n res.sendStatus(500)\n }\n }\n }\n\n const end = Date.now()\n reporter.log(\n `Executed function \"/api/${context.functionObj.functionRoute}\" in ${\n end - start\n }ms`\n )\n } else {\n next()\n }\n}\n\nexport function functionMiddlewares(\n middlewareConfig: ICreateMiddlewareConfig\n): Array<RequestHandler> {\n const setContext = createSetContextFunctionMiddleware(middlewareConfig)\n\n return [\n setCookies,\n setContext,\n multer().any(),\n bodyParserMiddlewareWithConfig(`raw`),\n bodyParserMiddlewareWithConfig(`text`),\n bodyParserMiddlewareWithConfig(`urlencoded`),\n bodyParserMiddlewareWithConfig(`json`),\n executeFunction,\n ]\n}\n"],"mappings":"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"}
\No newline at end of file