@mionjs/platform-gcloud 0.8.0-alpha.0 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const src_googleCF = require("./src/googleCF.cjs");
4
4
  const src_constants = require("./src/constants.cjs");
5
+ exports.createGoogleCFHandler = src_googleCF.createGoogleCFHandler;
5
6
  exports.googleCFHandler = src_googleCF.googleCFHandler;
6
7
  exports.resetGoogleCFOpts = src_googleCF.resetGoogleCFOpts;
7
8
  exports.setGoogleCFOpts = src_googleCF.setGoogleCFOpts;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}
@@ -14,8 +14,13 @@ function setGoogleCFOpts(routerOptions) {
14
14
  ...googleCFOptions,
15
15
  ...routerOptions
16
16
  };
17
+ router.setPlatformConfig({ ...googleCFOptions });
17
18
  return googleCFOptions;
18
19
  }
20
+ function createGoogleCFHandler(options) {
21
+ setGoogleCFOpts(options);
22
+ return googleCFHandler;
23
+ }
19
24
  async function googleCFHandler(rawRequest, rawResponse) {
20
25
  rawResponse.setHeader("server", "@mionjs");
21
26
  const reqHeaders = src_headers.headersFromIncomingMessage(rawRequest);
@@ -94,6 +99,7 @@ function unexpectedFail(resp, respHeaders, error) {
94
99
  const routeResponse = router.getRouterFatalErrorResponse(error, respHeaders);
95
100
  reply(routeResponse, resp);
96
101
  }
102
+ exports.createGoogleCFHandler = createGoogleCFHandler;
97
103
  exports.googleCFHandler = googleCFHandler;
98
104
  exports.resetGoogleCFOpts = resetGoogleCFOpts;
99
105
  exports.setGoogleCFOpts = setGoogleCFOpts;
@@ -1 +1 @@
1
- {"version":3,"file":"googleCF.cjs","sources":["../../../src/googleCF.ts"],"sourcesContent":["/* ########\n * 2023 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {RpcError, SerializerModes} from '@mionjs/core';\nimport type {SerializerCode} from '@mionjs/core';\nimport {dispatchRoute, getRouterFatalErrorResponse, resetRouter, decodeQueryBody} from '@mionjs/router';\nimport type {MionHeaders, MionResponse} from '@mionjs/router';\nimport {Request, Response} from 'express';\nimport {DEFAULT_GOOGLE_CF_OPTIONS} from './constants.ts';\nimport {GoogleCFOptions} from './types.ts';\nimport {headersFromIncomingMessage, headersFromServerResponse} from './headers.ts';\n\n// ############# STATE #############\n\nlet googleCFOptions: Readonly<GoogleCFOptions> = {...DEFAULT_GOOGLE_CF_OPTIONS};\n\n// ############# PUBLIC METHODS #############\n\nexport function resetGoogleCFOpts() {\n googleCFOptions = {...DEFAULT_GOOGLE_CF_OPTIONS};\n resetRouter();\n}\n\nexport function setGoogleCFOpts(routerOptions?: Partial<GoogleCFOptions>) {\n googleCFOptions = {\n ...googleCFOptions,\n ...routerOptions,\n };\n return googleCFOptions;\n}\n\nexport async function googleCFHandler(rawRequest: Request, rawResponse: Response): Promise<void> {\n // Express in Google Cloud Functions might parse the body automatically when Content-Type is application/json\n // We handle both cases: string body and already-parsed object body\n // For binary requests, we need to handle the raw buffer\n\n // TODO use its own express headers wrapper instead headers from record\n rawResponse.setHeader('server', '@mionjs');\n const reqHeaders = headersFromIncomingMessage(rawRequest);\n const respHeaders = headersFromServerResponse(rawResponse, googleCFOptions.defaultResponseHeaders);\n const contentType = rawRequest.headers['content-type'] || '';\n const isBinary = contentType.startsWith('application/octet-stream');\n let rawBody = isBinary ? (rawRequest as any).rawBody : rawRequest.body;\n let reqBodyType: SerializerCode = isBinary\n ? SerializerModes.binary\n : typeof rawBody === 'string'\n ? SerializerModes.stringifyJson\n : SerializerModes.json;\n // Extract query string from Express request\n const urlQuery = rawRequest.originalUrl?.includes('?') ? rawRequest.originalUrl.split('?')[1] : undefined;\n const queryBody = decodeQueryBody(urlQuery, rawBody);\n if (queryBody) {\n rawBody = queryBody.rawBody;\n reqBodyType = queryBody.bodyType;\n }\n\n try {\n const routeResponse = await dispatchRoute(\n rawRequest.path,\n rawBody,\n reqHeaders,\n respHeaders,\n rawRequest,\n rawResponse,\n reqBodyType,\n urlQuery\n );\n reply(routeResponse, rawResponse);\n } catch (err) {\n const error =\n err instanceof RpcError\n ? err\n : new RpcError({\n publicMessage: 'Internal Error',\n originalError: err as Error,\n type: 'unknown-error',\n });\n const routeResponse = getRouterFatalErrorResponse(error, respHeaders);\n reply(routeResponse, rawResponse);\n }\n}\n\n// ############# PRIVATE METHODS #############\n\nfunction reply(mionResp: MionResponse, resp: Response): void {\n resp.status(mionResp.statusCode);\n const bodyType = mionResp.serializer;\n switch (bodyType) {\n case SerializerModes.stringifyJson: {\n const buffer = Buffer.from(mionResp.rawBody as string, 'utf8');\n resp.set('content-length', `${buffer.byteLength}`);\n // content-type already set by serializer\n resp.end(buffer);\n break;\n }\n case SerializerModes.json: {\n // Platform adapter stringifies the prepared body object\n const jsonString = JSON.stringify(mionResp.body);\n const buffer = Buffer.from(jsonString, 'utf8');\n resp.set('content-type', 'application/json; charset=utf-8');\n resp.set('content-length', `${buffer.byteLength}`);\n resp.end(buffer);\n break;\n }\n case SerializerModes.binary: {\n const serializer = mionResp.binSerializer!;\n resp.set('content-length', `${serializer.getLength()}`);\n // content-type already set by serializer\n resp.end(Buffer.from(serializer.getBufferView()));\n\n // Release buffer when response is finished\n const onFinish = () => serializer.markAsEnded();\n resp.on('finish', onFinish);\n resp.on('close', onFinish); // Fallback for aborted connection\n break;\n }\n default: {\n const error = new RpcError({\n publicMessage: 'unknown-mion-response-format',\n type: 'unknown-error',\n errorData: {bodyType},\n });\n unexpectedFail(resp, mionResp.headers, error);\n }\n }\n}\n\nfunction unexpectedFail(resp: Response, respHeaders: MionHeaders, error: RpcError<string>) {\n if (resp.writableEnded) return;\n const routeResponse = getRouterFatalErrorResponse(error, respHeaders);\n reply(routeResponse, resp);\n}\n"],"names":["DEFAULT_GOOGLE_CF_OPTIONS","resetRouter","headersFromIncomingMessage","headersFromServerResponse","SerializerModes","decodeQueryBody","dispatchRoute","RpcError","getRouterFatalErrorResponse"],"mappings":"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"}
1
+ {"version":3,"file":"googleCF.cjs","sources":["../../../src/googleCF.ts"],"sourcesContent":["/* ########\n * 2023 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {RpcError, SerializerModes} from '@mionjs/core';\nimport type {SerializerCode} from '@mionjs/core';\nimport {dispatchRoute, getRouterFatalErrorResponse, resetRouter, decodeQueryBody, setPlatformConfig} from '@mionjs/router';\nimport type {MionHeaders, MionResponse} from '@mionjs/router';\nimport {Request, Response} from 'express';\nimport {DEFAULT_GOOGLE_CF_OPTIONS} from './constants.ts';\nimport {GoogleCFOptions} from './types.ts';\nimport {headersFromIncomingMessage, headersFromServerResponse} from './headers.ts';\n\n// ############# STATE #############\n\nlet googleCFOptions: Readonly<GoogleCFOptions> = {...DEFAULT_GOOGLE_CF_OPTIONS};\n\n// ############# PUBLIC METHODS #############\n\nexport function resetGoogleCFOpts() {\n googleCFOptions = {...DEFAULT_GOOGLE_CF_OPTIONS};\n resetRouter();\n}\n\nexport function setGoogleCFOpts(routerOptions?: Partial<GoogleCFOptions>) {\n googleCFOptions = {\n ...googleCFOptions,\n ...routerOptions,\n };\n setPlatformConfig({...googleCFOptions});\n return googleCFOptions;\n}\n\n/** Creates a Google Cloud Functions handler with optional platform config */\nexport function createGoogleCFHandler(options?: Partial<GoogleCFOptions>) {\n setGoogleCFOpts(options);\n return googleCFHandler;\n}\n\nexport async function googleCFHandler(rawRequest: Request, rawResponse: Response): Promise<void> {\n // Express in Google Cloud Functions might parse the body automatically when Content-Type is application/json\n // We handle both cases: string body and already-parsed object body\n // For binary requests, we need to handle the raw buffer\n\n // TODO use its own express headers wrapper instead headers from record\n rawResponse.setHeader('server', '@mionjs');\n const reqHeaders = headersFromIncomingMessage(rawRequest);\n const respHeaders = headersFromServerResponse(rawResponse, googleCFOptions.defaultResponseHeaders);\n const contentType = rawRequest.headers['content-type'] || '';\n const isBinary = contentType.startsWith('application/octet-stream');\n let rawBody = isBinary ? (rawRequest as any).rawBody : rawRequest.body;\n let reqBodyType: SerializerCode = isBinary\n ? SerializerModes.binary\n : typeof rawBody === 'string'\n ? SerializerModes.stringifyJson\n : SerializerModes.json;\n // Extract query string from Express request\n const urlQuery = rawRequest.originalUrl?.includes('?') ? rawRequest.originalUrl.split('?')[1] : undefined;\n const queryBody = decodeQueryBody(urlQuery, rawBody);\n if (queryBody) {\n rawBody = queryBody.rawBody;\n reqBodyType = queryBody.bodyType;\n }\n\n try {\n const routeResponse = await dispatchRoute(\n rawRequest.path,\n rawBody,\n reqHeaders,\n respHeaders,\n rawRequest,\n rawResponse,\n reqBodyType,\n urlQuery\n );\n reply(routeResponse, rawResponse);\n } catch (err) {\n const error =\n err instanceof RpcError\n ? err\n : new RpcError({\n publicMessage: 'Internal Error',\n originalError: err as Error,\n type: 'unknown-error',\n });\n const routeResponse = getRouterFatalErrorResponse(error, respHeaders);\n reply(routeResponse, rawResponse);\n }\n}\n\n// ############# PRIVATE METHODS #############\n\nfunction reply(mionResp: MionResponse, resp: Response): void {\n resp.status(mionResp.statusCode);\n const bodyType = mionResp.serializer;\n switch (bodyType) {\n case SerializerModes.stringifyJson: {\n const buffer = Buffer.from(mionResp.rawBody as string, 'utf8');\n resp.set('content-length', `${buffer.byteLength}`);\n // content-type already set by serializer\n resp.end(buffer);\n break;\n }\n case SerializerModes.json: {\n // Platform adapter stringifies the prepared body object\n const jsonString = JSON.stringify(mionResp.body);\n const buffer = Buffer.from(jsonString, 'utf8');\n resp.set('content-type', 'application/json; charset=utf-8');\n resp.set('content-length', `${buffer.byteLength}`);\n resp.end(buffer);\n break;\n }\n case SerializerModes.binary: {\n const serializer = mionResp.binSerializer!;\n resp.set('content-length', `${serializer.getLength()}`);\n // content-type already set by serializer\n resp.end(Buffer.from(serializer.getBufferView()));\n\n // Release buffer when response is finished\n const onFinish = () => serializer.markAsEnded();\n resp.on('finish', onFinish);\n resp.on('close', onFinish); // Fallback for aborted connection\n break;\n }\n default: {\n const error = new RpcError({\n publicMessage: 'unknown-mion-response-format',\n type: 'unknown-error',\n errorData: {bodyType},\n });\n unexpectedFail(resp, mionResp.headers, error);\n }\n }\n}\n\nfunction unexpectedFail(resp: Response, respHeaders: MionHeaders, error: RpcError<string>) {\n if (resp.writableEnded) return;\n const routeResponse = getRouterFatalErrorResponse(error, respHeaders);\n reply(routeResponse, resp);\n}\n"],"names":["DEFAULT_GOOGLE_CF_OPTIONS","resetRouter","setPlatformConfig","headersFromIncomingMessage","headersFromServerResponse","SerializerModes","decodeQueryBody","dispatchRoute","RpcError","getRouterFatalErrorResponse"],"mappings":"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"}
@@ -2,4 +2,5 @@ import { Request, Response } from 'express';
2
2
  import { GoogleCFOptions } from './types.ts';
3
3
  export declare function resetGoogleCFOpts(): void;
4
4
  export declare function setGoogleCFOpts(routerOptions?: Partial<GoogleCFOptions>): Readonly<GoogleCFOptions>;
5
+ export declare function createGoogleCFHandler(options?: Partial<GoogleCFOptions>): typeof googleCFHandler;
5
6
  export declare function googleCFHandler(rawRequest: Request, rawResponse: Response): Promise<void>;
@@ -1,7 +1,8 @@
1
- import { googleCFHandler, resetGoogleCFOpts, setGoogleCFOpts } from "./src/googleCF.js";
1
+ import { createGoogleCFHandler, googleCFHandler, resetGoogleCFOpts, setGoogleCFOpts } from "./src/googleCF.js";
2
2
  import { DEFAULT_GOOGLE_CF_OPTIONS } from "./src/constants.js";
3
3
  export {
4
4
  DEFAULT_GOOGLE_CF_OPTIONS,
5
+ createGoogleCFHandler,
5
6
  googleCFHandler,
6
7
  resetGoogleCFOpts,
7
8
  setGoogleCFOpts
@@ -2,4 +2,5 @@ import { Request, Response } from 'express';
2
2
  import { GoogleCFOptions } from './types.ts';
3
3
  export declare function resetGoogleCFOpts(): void;
4
4
  export declare function setGoogleCFOpts(routerOptions?: Partial<GoogleCFOptions>): Readonly<GoogleCFOptions>;
5
+ export declare function createGoogleCFHandler(options?: Partial<GoogleCFOptions>): typeof googleCFHandler;
5
6
  export declare function googleCFHandler(rawRequest: Request, rawResponse: Response): Promise<void>;
@@ -1,5 +1,5 @@
1
1
  import { SerializerModes, RpcError } from "@mionjs/core";
2
- import { decodeQueryBody, dispatchRoute, getRouterFatalErrorResponse, resetRouter } from "@mionjs/router";
2
+ import { decodeQueryBody, dispatchRoute, getRouterFatalErrorResponse, resetRouter, setPlatformConfig } from "@mionjs/router";
3
3
  import { DEFAULT_GOOGLE_CF_OPTIONS } from "./constants.js";
4
4
  import { headersFromIncomingMessage, headersFromServerResponse } from "./headers.js";
5
5
  let googleCFOptions = { ...DEFAULT_GOOGLE_CF_OPTIONS };
@@ -12,8 +12,13 @@ function setGoogleCFOpts(routerOptions) {
12
12
  ...googleCFOptions,
13
13
  ...routerOptions
14
14
  };
15
+ setPlatformConfig({ ...googleCFOptions });
15
16
  return googleCFOptions;
16
17
  }
18
+ function createGoogleCFHandler(options) {
19
+ setGoogleCFOpts(options);
20
+ return googleCFHandler;
21
+ }
17
22
  async function googleCFHandler(rawRequest, rawResponse) {
18
23
  rawResponse.setHeader("server", "@mionjs");
19
24
  const reqHeaders = headersFromIncomingMessage(rawRequest);
@@ -93,6 +98,7 @@ function unexpectedFail(resp, respHeaders, error) {
93
98
  reply(routeResponse, resp);
94
99
  }
95
100
  export {
101
+ createGoogleCFHandler,
96
102
  googleCFHandler,
97
103
  resetGoogleCFOpts,
98
104
  setGoogleCFOpts
@@ -1 +1 @@
1
- {"version":3,"file":"googleCF.js","sources":["../../../src/googleCF.ts"],"sourcesContent":["/* ########\n * 2023 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {RpcError, SerializerModes} from '@mionjs/core';\nimport type {SerializerCode} from '@mionjs/core';\nimport {dispatchRoute, getRouterFatalErrorResponse, resetRouter, decodeQueryBody} from '@mionjs/router';\nimport type {MionHeaders, MionResponse} from '@mionjs/router';\nimport {Request, Response} from 'express';\nimport {DEFAULT_GOOGLE_CF_OPTIONS} from './constants.ts';\nimport {GoogleCFOptions} from './types.ts';\nimport {headersFromIncomingMessage, headersFromServerResponse} from './headers.ts';\n\n// ############# STATE #############\n\nlet googleCFOptions: Readonly<GoogleCFOptions> = {...DEFAULT_GOOGLE_CF_OPTIONS};\n\n// ############# PUBLIC METHODS #############\n\nexport function resetGoogleCFOpts() {\n googleCFOptions = {...DEFAULT_GOOGLE_CF_OPTIONS};\n resetRouter();\n}\n\nexport function setGoogleCFOpts(routerOptions?: Partial<GoogleCFOptions>) {\n googleCFOptions = {\n ...googleCFOptions,\n ...routerOptions,\n };\n return googleCFOptions;\n}\n\nexport async function googleCFHandler(rawRequest: Request, rawResponse: Response): Promise<void> {\n // Express in Google Cloud Functions might parse the body automatically when Content-Type is application/json\n // We handle both cases: string body and already-parsed object body\n // For binary requests, we need to handle the raw buffer\n\n // TODO use its own express headers wrapper instead headers from record\n rawResponse.setHeader('server', '@mionjs');\n const reqHeaders = headersFromIncomingMessage(rawRequest);\n const respHeaders = headersFromServerResponse(rawResponse, googleCFOptions.defaultResponseHeaders);\n const contentType = rawRequest.headers['content-type'] || '';\n const isBinary = contentType.startsWith('application/octet-stream');\n let rawBody = isBinary ? (rawRequest as any).rawBody : rawRequest.body;\n let reqBodyType: SerializerCode = isBinary\n ? SerializerModes.binary\n : typeof rawBody === 'string'\n ? SerializerModes.stringifyJson\n : SerializerModes.json;\n // Extract query string from Express request\n const urlQuery = rawRequest.originalUrl?.includes('?') ? rawRequest.originalUrl.split('?')[1] : undefined;\n const queryBody = decodeQueryBody(urlQuery, rawBody);\n if (queryBody) {\n rawBody = queryBody.rawBody;\n reqBodyType = queryBody.bodyType;\n }\n\n try {\n const routeResponse = await dispatchRoute(\n rawRequest.path,\n rawBody,\n reqHeaders,\n respHeaders,\n rawRequest,\n rawResponse,\n reqBodyType,\n urlQuery\n );\n reply(routeResponse, rawResponse);\n } catch (err) {\n const error =\n err instanceof RpcError\n ? err\n : new RpcError({\n publicMessage: 'Internal Error',\n originalError: err as Error,\n type: 'unknown-error',\n });\n const routeResponse = getRouterFatalErrorResponse(error, respHeaders);\n reply(routeResponse, rawResponse);\n }\n}\n\n// ############# PRIVATE METHODS #############\n\nfunction reply(mionResp: MionResponse, resp: Response): void {\n resp.status(mionResp.statusCode);\n const bodyType = mionResp.serializer;\n switch (bodyType) {\n case SerializerModes.stringifyJson: {\n const buffer = Buffer.from(mionResp.rawBody as string, 'utf8');\n resp.set('content-length', `${buffer.byteLength}`);\n // content-type already set by serializer\n resp.end(buffer);\n break;\n }\n case SerializerModes.json: {\n // Platform adapter stringifies the prepared body object\n const jsonString = JSON.stringify(mionResp.body);\n const buffer = Buffer.from(jsonString, 'utf8');\n resp.set('content-type', 'application/json; charset=utf-8');\n resp.set('content-length', `${buffer.byteLength}`);\n resp.end(buffer);\n break;\n }\n case SerializerModes.binary: {\n const serializer = mionResp.binSerializer!;\n resp.set('content-length', `${serializer.getLength()}`);\n // content-type already set by serializer\n resp.end(Buffer.from(serializer.getBufferView()));\n\n // Release buffer when response is finished\n const onFinish = () => serializer.markAsEnded();\n resp.on('finish', onFinish);\n resp.on('close', onFinish); // Fallback for aborted connection\n break;\n }\n default: {\n const error = new RpcError({\n publicMessage: 'unknown-mion-response-format',\n type: 'unknown-error',\n errorData: {bodyType},\n });\n unexpectedFail(resp, mionResp.headers, error);\n }\n }\n}\n\nfunction unexpectedFail(resp: Response, respHeaders: MionHeaders, error: RpcError<string>) {\n if (resp.writableEnded) return;\n const routeResponse = getRouterFatalErrorResponse(error, respHeaders);\n reply(routeResponse, resp);\n}\n"],"names":[],"mappings":";;;;AAkBA,IAAI,kBAA6C,EAAC,GAAG,0BAAA;AAI9C,SAAS,oBAAoB;AAChC,oBAAkB,EAAC,GAAG,0BAAA;AACtB,cAAA;AACJ;AAEO,SAAS,gBAAgB,eAA0C;AACtE,oBAAkB;AAAA,IACd,GAAG;AAAA,IACH,GAAG;AAAA,EAAA;AAEP,SAAO;AACX;AAEA,eAAsB,gBAAgB,YAAqB,aAAsC;AAM7F,cAAY,UAAU,UAAU,SAAS;AACzC,QAAM,aAAa,2BAA2B,UAAU;AACxD,QAAM,cAAc,0BAA0B,aAAa,gBAAgB,sBAAsB;AACjG,QAAM,cAAc,WAAW,QAAQ,cAAc,KAAK;AAC1D,QAAM,WAAW,YAAY,WAAW,0BAA0B;AAClE,MAAI,UAAU,WAAY,WAAmB,UAAU,WAAW;AAClE,MAAI,cAA8B,WAC5B,gBAAgB,SAChB,OAAO,YAAY,WACjB,gBAAgB,gBAChB,gBAAgB;AAExB,QAAM,WAAW,WAAW,aAAa,SAAS,GAAG,IAAI,WAAW,YAAY,MAAM,GAAG,EAAE,CAAC,IAAI;AAChG,QAAM,YAAY,gBAAgB,UAAU,OAAO;AACnD,MAAI,WAAW;AACX,cAAU,UAAU;AACpB,kBAAc,UAAU;AAAA,EAC5B;AAEA,MAAI;AACA,UAAM,gBAAgB,MAAM;AAAA,MACxB,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEJ,UAAM,eAAe,WAAW;AAAA,EACpC,SAAS,KAAK;AACV,UAAM,QACF,eAAe,WACT,MACA,IAAI,SAAS;AAAA,MACT,eAAe;AAAA,MACf,eAAe;AAAA,MACf,MAAM;AAAA,IAAA,CACT;AACX,UAAM,gBAAgB,4BAA4B,OAAO,WAAW;AACpE,UAAM,eAAe,WAAW;AAAA,EACpC;AACJ;AAIA,SAAS,MAAM,UAAwB,MAAsB;AACzD,OAAK,OAAO,SAAS,UAAU;AAC/B,QAAM,WAAW,SAAS;AAC1B,UAAQ,UAAA;AAAA,IACJ,KAAK,gBAAgB,eAAe;AAChC,YAAM,SAAS,OAAO,KAAK,SAAS,SAAmB,MAAM;AAC7D,WAAK,IAAI,kBAAkB,GAAG,OAAO,UAAU,EAAE;AAEjD,WAAK,IAAI,MAAM;AACf;AAAA,IACJ;AAAA,IACA,KAAK,gBAAgB,MAAM;AAEvB,YAAM,aAAa,KAAK,UAAU,SAAS,IAAI;AAC/C,YAAM,SAAS,OAAO,KAAK,YAAY,MAAM;AAC7C,WAAK,IAAI,gBAAgB,iCAAiC;AAC1D,WAAK,IAAI,kBAAkB,GAAG,OAAO,UAAU,EAAE;AACjD,WAAK,IAAI,MAAM;AACf;AAAA,IACJ;AAAA,IACA,KAAK,gBAAgB,QAAQ;AACzB,YAAM,aAAa,SAAS;AAC5B,WAAK,IAAI,kBAAkB,GAAG,WAAW,UAAA,CAAW,EAAE;AAEtD,WAAK,IAAI,OAAO,KAAK,WAAW,cAAA,CAAe,CAAC;AAGhD,YAAM,WAAW,MAAM,WAAW,YAAA;AAClC,WAAK,GAAG,UAAU,QAAQ;AAC1B,WAAK,GAAG,SAAS,QAAQ;AACzB;AAAA,IACJ;AAAA,IACA,SAAS;AACL,YAAM,QAAQ,IAAI,SAAS;AAAA,QACvB,eAAe;AAAA,QACf,MAAM;AAAA,QACN,WAAW,EAAC,SAAA;AAAA,MAAQ,CACvB;AACD,qBAAe,MAAM,SAAS,SAAS,KAAK;AAAA,IAChD;AAAA,EAAA;AAER;AAEA,SAAS,eAAe,MAAgB,aAA0B,OAAyB;AACvF,MAAI,KAAK,cAAe;AACxB,QAAM,gBAAgB,4BAA4B,OAAO,WAAW;AACpE,QAAM,eAAe,IAAI;AAC7B;"}
1
+ {"version":3,"file":"googleCF.js","sources":["../../../src/googleCF.ts"],"sourcesContent":["/* ########\n * 2023 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {RpcError, SerializerModes} from '@mionjs/core';\nimport type {SerializerCode} from '@mionjs/core';\nimport {dispatchRoute, getRouterFatalErrorResponse, resetRouter, decodeQueryBody, setPlatformConfig} from '@mionjs/router';\nimport type {MionHeaders, MionResponse} from '@mionjs/router';\nimport {Request, Response} from 'express';\nimport {DEFAULT_GOOGLE_CF_OPTIONS} from './constants.ts';\nimport {GoogleCFOptions} from './types.ts';\nimport {headersFromIncomingMessage, headersFromServerResponse} from './headers.ts';\n\n// ############# STATE #############\n\nlet googleCFOptions: Readonly<GoogleCFOptions> = {...DEFAULT_GOOGLE_CF_OPTIONS};\n\n// ############# PUBLIC METHODS #############\n\nexport function resetGoogleCFOpts() {\n googleCFOptions = {...DEFAULT_GOOGLE_CF_OPTIONS};\n resetRouter();\n}\n\nexport function setGoogleCFOpts(routerOptions?: Partial<GoogleCFOptions>) {\n googleCFOptions = {\n ...googleCFOptions,\n ...routerOptions,\n };\n setPlatformConfig({...googleCFOptions});\n return googleCFOptions;\n}\n\n/** Creates a Google Cloud Functions handler with optional platform config */\nexport function createGoogleCFHandler(options?: Partial<GoogleCFOptions>) {\n setGoogleCFOpts(options);\n return googleCFHandler;\n}\n\nexport async function googleCFHandler(rawRequest: Request, rawResponse: Response): Promise<void> {\n // Express in Google Cloud Functions might parse the body automatically when Content-Type is application/json\n // We handle both cases: string body and already-parsed object body\n // For binary requests, we need to handle the raw buffer\n\n // TODO use its own express headers wrapper instead headers from record\n rawResponse.setHeader('server', '@mionjs');\n const reqHeaders = headersFromIncomingMessage(rawRequest);\n const respHeaders = headersFromServerResponse(rawResponse, googleCFOptions.defaultResponseHeaders);\n const contentType = rawRequest.headers['content-type'] || '';\n const isBinary = contentType.startsWith('application/octet-stream');\n let rawBody = isBinary ? (rawRequest as any).rawBody : rawRequest.body;\n let reqBodyType: SerializerCode = isBinary\n ? SerializerModes.binary\n : typeof rawBody === 'string'\n ? SerializerModes.stringifyJson\n : SerializerModes.json;\n // Extract query string from Express request\n const urlQuery = rawRequest.originalUrl?.includes('?') ? rawRequest.originalUrl.split('?')[1] : undefined;\n const queryBody = decodeQueryBody(urlQuery, rawBody);\n if (queryBody) {\n rawBody = queryBody.rawBody;\n reqBodyType = queryBody.bodyType;\n }\n\n try {\n const routeResponse = await dispatchRoute(\n rawRequest.path,\n rawBody,\n reqHeaders,\n respHeaders,\n rawRequest,\n rawResponse,\n reqBodyType,\n urlQuery\n );\n reply(routeResponse, rawResponse);\n } catch (err) {\n const error =\n err instanceof RpcError\n ? err\n : new RpcError({\n publicMessage: 'Internal Error',\n originalError: err as Error,\n type: 'unknown-error',\n });\n const routeResponse = getRouterFatalErrorResponse(error, respHeaders);\n reply(routeResponse, rawResponse);\n }\n}\n\n// ############# PRIVATE METHODS #############\n\nfunction reply(mionResp: MionResponse, resp: Response): void {\n resp.status(mionResp.statusCode);\n const bodyType = mionResp.serializer;\n switch (bodyType) {\n case SerializerModes.stringifyJson: {\n const buffer = Buffer.from(mionResp.rawBody as string, 'utf8');\n resp.set('content-length', `${buffer.byteLength}`);\n // content-type already set by serializer\n resp.end(buffer);\n break;\n }\n case SerializerModes.json: {\n // Platform adapter stringifies the prepared body object\n const jsonString = JSON.stringify(mionResp.body);\n const buffer = Buffer.from(jsonString, 'utf8');\n resp.set('content-type', 'application/json; charset=utf-8');\n resp.set('content-length', `${buffer.byteLength}`);\n resp.end(buffer);\n break;\n }\n case SerializerModes.binary: {\n const serializer = mionResp.binSerializer!;\n resp.set('content-length', `${serializer.getLength()}`);\n // content-type already set by serializer\n resp.end(Buffer.from(serializer.getBufferView()));\n\n // Release buffer when response is finished\n const onFinish = () => serializer.markAsEnded();\n resp.on('finish', onFinish);\n resp.on('close', onFinish); // Fallback for aborted connection\n break;\n }\n default: {\n const error = new RpcError({\n publicMessage: 'unknown-mion-response-format',\n type: 'unknown-error',\n errorData: {bodyType},\n });\n unexpectedFail(resp, mionResp.headers, error);\n }\n }\n}\n\nfunction unexpectedFail(resp: Response, respHeaders: MionHeaders, error: RpcError<string>) {\n if (resp.writableEnded) return;\n const routeResponse = getRouterFatalErrorResponse(error, respHeaders);\n reply(routeResponse, resp);\n}\n"],"names":[],"mappings":";;;;AAkBA,IAAI,kBAA6C,EAAC,GAAG,0BAAA;AAI9C,SAAS,oBAAoB;AAChC,oBAAkB,EAAC,GAAG,0BAAA;AACtB,cAAA;AACJ;AAEO,SAAS,gBAAgB,eAA0C;AACtE,oBAAkB;AAAA,IACd,GAAG;AAAA,IACH,GAAG;AAAA,EAAA;AAEP,oBAAkB,EAAC,GAAG,iBAAgB;AACtC,SAAO;AACX;AAGO,SAAS,sBAAsB,SAAoC;AACtE,kBAAgB,OAAO;AACvB,SAAO;AACX;AAEA,eAAsB,gBAAgB,YAAqB,aAAsC;AAM7F,cAAY,UAAU,UAAU,SAAS;AACzC,QAAM,aAAa,2BAA2B,UAAU;AACxD,QAAM,cAAc,0BAA0B,aAAa,gBAAgB,sBAAsB;AACjG,QAAM,cAAc,WAAW,QAAQ,cAAc,KAAK;AAC1D,QAAM,WAAW,YAAY,WAAW,0BAA0B;AAClE,MAAI,UAAU,WAAY,WAAmB,UAAU,WAAW;AAClE,MAAI,cAA8B,WAC5B,gBAAgB,SAChB,OAAO,YAAY,WACjB,gBAAgB,gBAChB,gBAAgB;AAExB,QAAM,WAAW,WAAW,aAAa,SAAS,GAAG,IAAI,WAAW,YAAY,MAAM,GAAG,EAAE,CAAC,IAAI;AAChG,QAAM,YAAY,gBAAgB,UAAU,OAAO;AACnD,MAAI,WAAW;AACX,cAAU,UAAU;AACpB,kBAAc,UAAU;AAAA,EAC5B;AAEA,MAAI;AACA,UAAM,gBAAgB,MAAM;AAAA,MACxB,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEJ,UAAM,eAAe,WAAW;AAAA,EACpC,SAAS,KAAK;AACV,UAAM,QACF,eAAe,WACT,MACA,IAAI,SAAS;AAAA,MACT,eAAe;AAAA,MACf,eAAe;AAAA,MACf,MAAM;AAAA,IAAA,CACT;AACX,UAAM,gBAAgB,4BAA4B,OAAO,WAAW;AACpE,UAAM,eAAe,WAAW;AAAA,EACpC;AACJ;AAIA,SAAS,MAAM,UAAwB,MAAsB;AACzD,OAAK,OAAO,SAAS,UAAU;AAC/B,QAAM,WAAW,SAAS;AAC1B,UAAQ,UAAA;AAAA,IACJ,KAAK,gBAAgB,eAAe;AAChC,YAAM,SAAS,OAAO,KAAK,SAAS,SAAmB,MAAM;AAC7D,WAAK,IAAI,kBAAkB,GAAG,OAAO,UAAU,EAAE;AAEjD,WAAK,IAAI,MAAM;AACf;AAAA,IACJ;AAAA,IACA,KAAK,gBAAgB,MAAM;AAEvB,YAAM,aAAa,KAAK,UAAU,SAAS,IAAI;AAC/C,YAAM,SAAS,OAAO,KAAK,YAAY,MAAM;AAC7C,WAAK,IAAI,gBAAgB,iCAAiC;AAC1D,WAAK,IAAI,kBAAkB,GAAG,OAAO,UAAU,EAAE;AACjD,WAAK,IAAI,MAAM;AACf;AAAA,IACJ;AAAA,IACA,KAAK,gBAAgB,QAAQ;AACzB,YAAM,aAAa,SAAS;AAC5B,WAAK,IAAI,kBAAkB,GAAG,WAAW,UAAA,CAAW,EAAE;AAEtD,WAAK,IAAI,OAAO,KAAK,WAAW,cAAA,CAAe,CAAC;AAGhD,YAAM,WAAW,MAAM,WAAW,YAAA;AAClC,WAAK,GAAG,UAAU,QAAQ;AAC1B,WAAK,GAAG,SAAS,QAAQ;AACzB;AAAA,IACJ;AAAA,IACA,SAAS;AACL,YAAM,QAAQ,IAAI,SAAS;AAAA,QACvB,eAAe;AAAA,QACf,MAAM;AAAA,QACN,WAAW,EAAC,SAAA;AAAA,MAAQ,CACvB;AACD,qBAAe,MAAM,SAAS,SAAS,KAAK;AAAA,IAChD;AAAA,EAAA;AAER;AAEA,SAAS,eAAe,MAAgB,aAA0B,OAAyB;AACvF,MAAI,KAAK,cAAe;AACxB,QAAM,gBAAgB,4BAA4B,OAAO,WAAW;AACpE,QAAM,eAAe,IAAI;AAC7B;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mionjs/platform-gcloud",
3
- "version": "0.8.0-alpha.0",
3
+ "version": "0.8.4",
4
4
  "type": "module",
5
5
  "description": "Google Cloud functions wrapper for mion router.",
6
6
  "keywords": [
@@ -54,11 +54,11 @@
54
54
  },
55
55
  "dependencies": {
56
56
  "@google-cloud/functions-framework": "^3.3.0",
57
- "@mionjs/core": "^0.8.0-alpha.0",
58
- "@mionjs/router": "^0.8.0-alpha.0"
57
+ "@mionjs/core": "^0.8.4",
58
+ "@mionjs/router": "^0.8.4"
59
59
  },
60
60
  "devDependencies": {
61
61
  "@types/express": "^4.17.20"
62
62
  },
63
- "gitHead": "5d2ec524ba39d040338ce8946d8edf78aa7291a3"
63
+ "gitHead": "c53dbf8bc494d950876e0bf171cb15078356a6cf"
64
64
  }