UNPKG

@h4ad/serverless-adapter

Version:

Run REST APIs and other web applications using your existing Node.js application framework (NestJS, Express, Koa, Hapi, Fastify and many others), on top of AWS, Azure, Digital Ocean and many other clouds.

1 lines 5.98 kB
{"version":3,"sources":["../../../src/adapters/digital-ocean/http-function.adapter.ts"],"sourcesContent":["//#region Imports\n\n//#region Imports\n\nimport type {\n DigitalOceanHttpEvent,\n DigitalOceanHttpResponse,\n} from '../../@types/digital-ocean';\nimport type {\n AdapterContract,\n AdapterRequest,\n GetResponseAdapterProps,\n OnErrorProps,\n} from '../../contracts';\nimport {\n getDefaultIfUndefined,\n getEventBodyAsBuffer,\n getFlattenedHeadersMap,\n getPathWithQueryStringParams,\n} from '../../core';\n\n//#endregion\n\n/**\n * The options to customize the {@link HttpFunctionAdapter}\n *\n * @breadcrumb Adapters / Digital Ocean / HttpFunctionAdapter\n * @public\n */\nexport interface HttpFunctionAdapterOptions {\n /**\n * Strip base path for custom domains\n *\n * @defaultValue ''\n */\n stripBasePath?: string;\n}\n\n/**\n * The adapter to handle requests from Digital Ocean Functions when called from HTTP Endpoint.\n *\n * @example\n * ```typescript\n * const stripBasePath = '/any/custom/base/path'; // default ''\n * const adapter = new HttpFunctionAdapter({ stripBasePath });\n * ```\n *\n * @breadcrumb Adapters / Digital Ocean / HttpFunctionAdapter\n * @public\n */\nexport class HttpFunctionAdapter\n implements\n AdapterContract<DigitalOceanHttpEvent, void, DigitalOceanHttpResponse>\n{\n //#region Constructor\n\n /**\n * Default constructor\n *\n * @param options - The options to customize the {@link HttpFunctionAdapter}\n */\n constructor(protected readonly options?: HttpFunctionAdapterOptions) {}\n\n //#endregion\n\n //#region Public Methods\n\n /**\n * {@inheritDoc}\n */\n public getAdapterName(): string {\n return HttpFunctionAdapter.name;\n }\n\n /**\n * {@inheritDoc}\n */\n public canHandle(event: unknown): event is DigitalOceanHttpEvent {\n const digitalOceanHttpEvent = event as DigitalOceanHttpEvent;\n\n return (\n !!digitalOceanHttpEvent &&\n digitalOceanHttpEvent.__ow_path !== undefined &&\n digitalOceanHttpEvent.__ow_method !== undefined &&\n digitalOceanHttpEvent.__ow_headers !== undefined\n );\n }\n\n /**\n * {@inheritDoc}\n */\n public getRequest(event: DigitalOceanHttpEvent): AdapterRequest {\n const headers = event.__ow_headers;\n const method = event.__ow_method.toUpperCase();\n const path = this.getPathFromEvent(event);\n\n let body: Buffer | undefined;\n\n if (event.__ow_body) {\n const [bufferBody, contentLength] = getEventBodyAsBuffer(\n event.__ow_body,\n !!event.__ow_isBase64Encoded,\n );\n\n body = bufferBody;\n headers['content-length'] = String(contentLength);\n }\n\n const remoteAddress = headers['x-forwarded-for'];\n\n return {\n method,\n headers,\n body,\n remoteAddress,\n path,\n };\n }\n\n /**\n * {@inheritDoc}\n */\n public getResponse({\n headers: responseHeaders,\n body,\n statusCode,\n }: GetResponseAdapterProps<DigitalOceanHttpEvent>): DigitalOceanHttpResponse {\n const headers = getFlattenedHeadersMap(responseHeaders);\n\n return {\n statusCode,\n body,\n headers,\n };\n }\n\n /**\n * {@inheritDoc}\n */\n public onErrorWhileForwarding({\n error,\n delegatedResolver,\n respondWithErrors,\n event,\n log,\n }: OnErrorProps<DigitalOceanHttpEvent, DigitalOceanHttpResponse>): void {\n const body = respondWithErrors ? error.stack : '';\n const errorResponse = this.getResponse({\n event,\n statusCode: 500,\n body: body || '',\n headers: {},\n isBase64Encoded: false,\n log,\n });\n\n delegatedResolver.succeed(errorResponse);\n }\n\n //#endregion\n\n //#region Protected Methods\n\n /**\n * Get path from event with query strings\n *\n * @param event - The event sent by digital ocean\n */\n protected getPathFromEvent(event: DigitalOceanHttpEvent): string {\n const stripBasePath = getDefaultIfUndefined(\n this.options?.stripBasePath,\n '',\n );\n const replaceRegex = new RegExp(`^${stripBasePath}`);\n\n const path = event.__ow_path.replace(replaceRegex, '');\n const queryParams = event.__ow_query;\n\n return getPathWithQueryStringParams(path, queryParams || {});\n }\n\n //#endregion\n}\n"],"mappings":"+GAkDO,IAAMA,EAAN,MAAMC,CAGb,CAQE,YAA+BC,EAAsC,CAAtC,aAAAA,CAAuC,CA7DxE,MAqDA,CAAAC,EAAA,4BAiBS,gBAAyB,CAC9B,OAAOF,EAAoB,IAC7B,CAKO,UAAUG,EAAgD,CAC/D,IAAMC,EAAwBD,EAE9B,MACE,CAAC,CAACC,GACFA,EAAsB,YAAc,QACpCA,EAAsB,cAAgB,QACtCA,EAAsB,eAAiB,MAE3C,CAKO,WAAWD,EAA8C,CAC9D,IAAME,EAAUF,EAAM,aAChBG,EAASH,EAAM,YAAY,YAAY,EACvCI,EAAO,KAAK,iBAAiBJ,CAAK,EAEpCK,EAEJ,GAAIL,EAAM,UAAW,CACnB,GAAM,CAACM,EAAYC,CAAa,EAAIC,EAClCR,EAAM,UACN,CAAC,CAACA,EAAM,oBACV,EAEAK,EAAOC,EACPJ,EAAQ,gBAAgB,EAAI,OAAOK,CAAa,CAClD,CAEA,IAAME,EAAgBP,EAAQ,iBAAiB,EAE/C,MAAO,CACL,OAAAC,EACA,QAAAD,EACA,KAAAG,EACA,cAAAI,EACA,KAAAL,CACF,CACF,CAKO,YAAY,CACjB,QAASM,EACT,KAAAL,EACA,WAAAM,CACF,EAA6E,CAC3E,IAAMT,EAAUU,EAAuBF,CAAe,EAEtD,MAAO,CACL,WAAAC,EACA,KAAAN,EACA,QAAAH,CACF,CACF,CAKO,uBAAuB,CAC5B,MAAAW,EACA,kBAAAC,EACA,kBAAAC,EACA,MAAAf,EACA,IAAAgB,CACF,EAAwE,CACtE,IAAMX,EAAOU,EAAoBF,EAAM,MAAQ,GACzCI,EAAgB,KAAK,YAAY,CACrC,MAAAjB,EACA,WAAY,IACZ,KAAMK,GAAQ,GACd,QAAS,CAAC,EACV,gBAAiB,GACjB,IAAAW,CACF,CAAC,EAEDF,EAAkB,QAAQG,CAAa,CACzC,CAWU,iBAAiBjB,EAAsC,CAC/D,IAAMkB,EAAgBC,EACpB,KAAK,SAAS,cACd,EACF,EACMC,EAAe,IAAI,OAAO,IAAIF,CAAa,EAAE,EAE7Cd,EAAOJ,EAAM,UAAU,QAAQoB,EAAc,EAAE,EAC/CC,EAAcrB,EAAM,WAE1B,OAAOsB,EAA6BlB,EAAMiB,GAAe,CAAC,CAAC,CAC7D,CAGF","names":["HttpFunctionAdapter","_HttpFunctionAdapter","options","__name","event","digitalOceanHttpEvent","headers","method","path","body","bufferBody","contentLength","getEventBodyAsBuffer","remoteAddress","responseHeaders","statusCode","getFlattenedHeadersMap","error","delegatedResolver","respondWithErrors","log","errorResponse","stripBasePath","getDefaultIfUndefined","replaceRegex","queryParams","getPathWithQueryStringParams"]}