@mxpicture/gcp-functions 0.1.1 → 0.1.2

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.
Files changed (60) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/base/BaseApi.js +38 -0
  3. package/dist/cjs/base/BaseFunction.js +23 -0
  4. package/dist/cjs/base/BaseHttp.js +106 -0
  5. package/dist/cjs/common/firebase.js +1 -168
  6. package/dist/cjs/demo/User.js +31 -0
  7. package/dist/cjs/lib.js +10 -9
  8. package/dist/{esm/store/IStore.js → cjs/store/Store.js} +28 -23
  9. package/dist/cjs/store/types.store.js +3 -8
  10. package/dist/cjs/types/types.apiRoutes.js +2 -0
  11. package/dist/cjs/types/types.common.js +2 -0
  12. package/dist/cjs/types/types.function.js +2 -0
  13. package/dist/cjs/types/types.httpHandler.js +2 -0
  14. package/dist/cjs/validation/Validation.js +38 -0
  15. package/dist/esm/base/BaseApi.js +38 -0
  16. package/dist/esm/base/BaseFunction.js +23 -0
  17. package/dist/esm/base/BaseHttp.js +106 -0
  18. package/dist/esm/common/firebase.js +1 -168
  19. package/dist/esm/demo/User.js +31 -0
  20. package/dist/esm/lib.js +10 -9
  21. package/dist/{cjs/store/IStore.js → esm/store/Store.js} +28 -23
  22. package/dist/esm/store/types.store.js +3 -8
  23. package/dist/esm/types/types.apiRoutes.js +2 -0
  24. package/dist/esm/types/types.common.js +2 -0
  25. package/dist/esm/types/types.function.js +2 -0
  26. package/dist/esm/types/types.httpHandler.js +2 -0
  27. package/dist/esm/validation/Validation.js +38 -0
  28. package/dist/types/base/BaseApi.d.ts +26 -0
  29. package/dist/types/base/BaseFunction.d.ts +11 -0
  30. package/dist/types/base/BaseHttp.d.ts +21 -0
  31. package/dist/types/common/firebase.d.ts +0 -9
  32. package/dist/types/demo/User.d.ts +24 -0
  33. package/dist/types/lib.d.ts +11 -10
  34. package/dist/types/store/Store.d.ts +24 -0
  35. package/dist/types/store/types.store.d.ts +3 -14
  36. package/dist/types/types/types.apiRoutes.d.ts +29 -0
  37. package/dist/types/types/types.common.d.ts +10 -0
  38. package/dist/types/types/types.function.d.ts +10 -0
  39. package/dist/types/types/types.httpHandler.d.ts +5 -0
  40. package/dist/types/validation/Validation.d.ts +14 -0
  41. package/package.json +2 -1
  42. package/dist/cjs/FunctionHandlers.js +0 -18
  43. package/dist/cjs/api/IApi.js +0 -52
  44. package/dist/cjs/common/http.js +0 -147
  45. package/dist/cjs/common/types.common.js +0 -30
  46. package/dist/cjs/handler/HttpHandler.js +0 -41
  47. package/dist/cjs/handler/IHttpHandlerItem.js +0 -169
  48. package/dist/esm/FunctionHandlers.js +0 -18
  49. package/dist/esm/api/IApi.js +0 -52
  50. package/dist/esm/common/http.js +0 -147
  51. package/dist/esm/common/types.common.js +0 -30
  52. package/dist/esm/handler/HttpHandler.js +0 -41
  53. package/dist/esm/handler/IHttpHandlerItem.js +0 -169
  54. package/dist/types/FunctionHandlers.d.ts +0 -12
  55. package/dist/types/api/IApi.d.ts +0 -27
  56. package/dist/types/common/http.d.ts +0 -20
  57. package/dist/types/common/types.common.d.ts +0 -31
  58. package/dist/types/handler/HttpHandler.d.ts +0 -15
  59. package/dist/types/handler/IHttpHandlerItem.d.ts +0 -23
  60. package/dist/types/store/IStore.d.ts +0 -25
@@ -1,23 +1,12 @@
1
1
  import { z } from "zod";
2
- export declare const storeBaseSchemaShape: {
2
+ export declare const storeSchemaShape: {
3
3
  id: z.ZodOptional<z.ZodString>;
4
4
  createTime: z.ZodOptional<z.ZodDate>;
5
5
  updateTime: z.ZodOptional<z.ZodDate>;
6
6
  };
7
- export declare const storePersistSchemaShape: {
8
- id: z.ZodString;
9
- createTime: z.ZodOptional<z.ZodDate>;
10
- updateTime: z.ZodOptional<z.ZodDate>;
11
- };
12
- export declare const storeBaseSchema: z.ZodObject<{
7
+ export declare const storeSchema: z.ZodObject<{
13
8
  id: z.ZodOptional<z.ZodString>;
14
9
  createTime: z.ZodOptional<z.ZodDate>;
15
10
  updateTime: z.ZodOptional<z.ZodDate>;
16
11
  }, z.core.$strip>;
17
- export type StoreBaseDoc = z.infer<typeof storeBaseSchema>;
18
- export declare const storePersistSchema: z.ZodObject<{
19
- id: z.ZodString;
20
- createTime: z.ZodOptional<z.ZodDate>;
21
- updateTime: z.ZodOptional<z.ZodDate>;
22
- }, z.core.$strip>;
23
- export type StorePersistDoc = z.infer<typeof storePersistSchema>;
12
+ export type StoreDoc = z.infer<typeof storeSchema>;
@@ -0,0 +1,29 @@
1
+ import { MetaItem } from "@mxpicture/zod-meta";
2
+ import { DocumentData, WithKey } from "./types.common.js";
3
+ export type ApiRouteDef<KEYS, PAYLOAD, RESULT> = {
4
+ keys: KEYS;
5
+ payload: PAYLOAD;
6
+ result: RESULT;
7
+ };
8
+ export type ApiRoutesMap = Record<string, ApiRouteDef<any, any, any>>;
9
+ export type WithApiRoutes<R extends ApiRoutesMap> = R;
10
+ export interface ApiKey {
11
+ id: string;
12
+ }
13
+ export type ApiRoutes<DTO extends DocumentData> = WithApiRoutes<{
14
+ create: ApiRouteDef<never, DTO, WithKey<DTO>>;
15
+ update: ApiRouteDef<ApiKey, Partial<DTO>, WithKey<DTO>>;
16
+ delete: ApiRouteDef<ApiKey, never, void>;
17
+ get: ApiRouteDef<ApiKey, never, WithKey<DTO>>;
18
+ query: ApiRouteDef<never, never, WithKey<DTO>[]>;
19
+ count: ApiRouteDef<never, never, {
20
+ count: number;
21
+ }>;
22
+ exists: ApiRouteDef<ApiKey, never, {
23
+ exists: boolean;
24
+ }>;
25
+ meta: ApiRouteDef<never, never, MetaItem[]>;
26
+ }>;
27
+ export type ApiFromRoutes<R extends ApiRoutesMap> = {
28
+ [K in keyof R]: (...args: R[K]["keys"] extends never ? [payload: R[K]["payload"]] : [keys: R[K]["keys"], payload: R[K]["payload"]]) => Promise<R[K]["result"]>;
29
+ };
@@ -0,0 +1,10 @@
1
+ export type DocumentFieldValue = any;
2
+ export type DocumentData = {
3
+ [field: string]: DocumentFieldValue;
4
+ };
5
+ export interface DocumentKey {
6
+ id?: string;
7
+ createTime?: Date;
8
+ updateTime?: Date;
9
+ }
10
+ export type WithKey<DTO extends DocumentData> = DocumentKey & DTO;
@@ -0,0 +1,10 @@
1
+ import { StoreDoc } from "../store/types.store";
2
+ import { ApiKey } from "./types.apiRoutes";
3
+ export interface FunctionPayload<DOC extends StoreDoc, KEYS extends ApiKey = never> {
4
+ route: string;
5
+ keys?: KEYS;
6
+ content?: DOC;
7
+ }
8
+ export interface FunctionResult<DOC extends StoreDoc> {
9
+ doc?: DOC | DOC[];
10
+ }
@@ -0,0 +1,5 @@
1
+ import { ApiRoutesMap } from "./types.apiRoutes";
2
+ import { FunctionPayload } from "./types.function";
3
+ export type HttpHandlers<R extends ApiRoutesMap> = {
4
+ [K in keyof R]: (payload: FunctionPayload<R[K]["payload"], R[K]["keys"]>) => Promise<R[K]["result"]>;
5
+ };
@@ -0,0 +1,14 @@
1
+ import { Store } from "../store/Store";
2
+ import { ZodError, ZodObject, ZodRawShape } from "zod";
3
+ import { DocumentData, WithKey } from "../types/types.common";
4
+ export type ValidationFieldErrors = Record<string, string[]>;
5
+ export declare class Validation<DTO extends DocumentData> {
6
+ readonly store: Store<DTO>;
7
+ shape: ZodRawShape;
8
+ createSchema: ZodObject;
9
+ updateSchema: ZodObject;
10
+ constructor(store: Store<DTO>, shape: ZodRawShape);
11
+ validate(doc: Partial<WithKey<DTO>>): Promise<WithKey<DTO>>;
12
+ validatePartial(doc: Partial<WithKey<DTO>>): Promise<Partial<WithKey<DTO>>>;
13
+ protected issuesToFieldErrors(issues: ZodError["issues"]): ValidationFieldErrors;
14
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mxpicture/gcp-functions",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Utils for google cloud functions, publishing both CommonJS and ESM builds",
5
5
  "author": "MXPicture",
6
6
  "license": "MIT",
@@ -49,6 +49,7 @@
49
49
  "firebase-admin": "^13.6.0",
50
50
  "firebase-functions": "^7.0.3",
51
51
  "short-uuid": "^6.0.3",
52
+ "ts-transformer-keys": "^0.4.4",
52
53
  "zod": "^4.3.5"
53
54
  },
54
55
  "devDependencies": {
@@ -1,18 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FunctionHandlers = void 0;
4
- class FunctionHandlers {
5
- constructor() {
6
- this.items = {};
7
- }
8
- add(handler) {
9
- this.items[handler.name] = handler;
10
- }
11
- functions() {
12
- const result = {};
13
- for (const [key, item] of Object.entries(this.items))
14
- result[key] = item.setup();
15
- return result;
16
- }
17
- }
18
- exports.FunctionHandlers = FunctionHandlers;
@@ -1,52 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.IApi = void 0;
4
- const zod_meta_1 = require("@mxpicture/zod-meta");
5
- class IApi {
6
- constructor(store, shape) {
7
- this.store = store;
8
- this.shape = shape;
9
- }
10
- metaItems() {
11
- return new zod_meta_1.Meta(this.shape).items();
12
- }
13
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
14
- async create(doc, params) {
15
- const storeDoc = await this.store.create(doc);
16
- return this.fromStore(storeDoc);
17
- }
18
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
19
- async get(id, params) {
20
- const storeDoc = await this.store.get(id);
21
- return this.fromStore(storeDoc);
22
- }
23
- async query(params) {
24
- const storeDocs = await this.store.query(params);
25
- return await Promise.all(storeDocs.map((s) => this.fromStore(s)));
26
- }
27
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
28
- async count(params) {
29
- return this.store.count();
30
- }
31
- async update(id, doc,
32
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
33
- params) {
34
- let storeDoc = await this.toStore(doc);
35
- storeDoc = await this.store.update(id, storeDoc);
36
- return this.fromStore(storeDoc);
37
- }
38
- async updatePartial(id, doc) {
39
- const storeDoc = await this.toStorePartial(doc);
40
- await this.store.update(id, storeDoc);
41
- return this.get(id);
42
- }
43
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
44
- async delete(id, params) {
45
- await this.store.delete(id);
46
- }
47
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
48
- async exists(id, params) {
49
- return this.store.exists(id);
50
- }
51
- }
52
- exports.IApi = IApi;
@@ -1,147 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.fixRequestBody = exports.hasBody = exports.contentstream = void 0;
40
- const querystring = __importStar(require("querystring"));
41
- const zlib_1 = require("zlib");
42
- const zlib = __importStar(require("zlib"));
43
- const http_errors_1 = __importDefault(require("http-errors"));
44
- // export const handleErrorMessage = (
45
- // response: express.Response,
46
- // error: unknown,
47
- // code: number = StatusCodes.BAD_REQUEST,
48
- // ) => {
49
- // // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
- // const ae = error as any;
51
- // const result = { message: "" };
52
- // if (error instanceof Error) result.message = error.message;
53
- // else if (typeof error === "string") result.message = error;
54
- // else if (ae.message) result.message = ae.message;
55
- // else if (ae.payload) {
56
- // if (ae.payload.message && typeof ae.payload.message === "string")
57
- // result.message = ae.payload.message;
58
- // else if (typeof ae.payload === "string") result.message = ae.payload;
59
- // } else result.message = "unknown";
60
- // return response.status(code).json(result);
61
- // };
62
- const hasBrotliSupport = "createBrotliDecompress" in zlib;
63
- /**
64
- * Get the content stream of the request.
65
- *
66
- * @param {object} req
67
- * @param {function} debug
68
- * @param {boolean} [inflate=true]
69
- * @return {object}
70
- * @api private
71
- */
72
- const contentstream = (req, inflate, debug = console) => {
73
- const encoding = (req.headers["content-encoding"] || "identity").toLowerCase();
74
- // const length = req.headers["content-length"];
75
- let stream;
76
- debug?.log('content-encoding "%s"', encoding);
77
- if (inflate === false && encoding !== "identity") {
78
- throw (0, http_errors_1.default)(415, "content encoding unsupported", {
79
- encoding: encoding,
80
- type: "encoding.unsupported",
81
- });
82
- }
83
- switch (encoding) {
84
- case "deflate":
85
- stream = (0, zlib_1.createInflate)();
86
- debug?.log("inflate body");
87
- req.pipe(stream);
88
- break;
89
- case "gzip":
90
- stream = (0, zlib_1.createGunzip)();
91
- debug?.log("gunzip body");
92
- req.pipe(stream);
93
- break;
94
- case "identity":
95
- stream = req;
96
- // stream.length = length;
97
- break;
98
- case "br":
99
- if (hasBrotliSupport) {
100
- stream = (0, zlib_1.createBrotliDecompress)();
101
- debug?.log("brotli decompress body");
102
- req.pipe(stream);
103
- }
104
- break;
105
- }
106
- if (stream === undefined) {
107
- throw (0, http_errors_1.default)(415, 'unsupported content encoding "' + encoding + '"', {
108
- encoding: encoding,
109
- type: "encoding.unsupported",
110
- });
111
- }
112
- return stream;
113
- };
114
- exports.contentstream = contentstream;
115
- const hasBody = (request) => {
116
- const contentType = request.headers["content-type"];
117
- return contentType
118
- ? contentType.includes("application/json") ||
119
- contentType.includes("+json") ||
120
- contentType.includes("application/x-www-form-urlencoded")
121
- : false;
122
- };
123
- exports.hasBody = hasBody;
124
- /**
125
- * Fix proxied body if bodyParser is involved.
126
- */
127
- const fixRequestBody = (proxyReq, requestBody) => {
128
- if (!requestBody) {
129
- return;
130
- }
131
- const contentType = proxyReq.getHeader("Content-Type");
132
- const writeBody = (bodyData) => {
133
- // deepcode ignore ContentLengthInCode: bodyParser fix
134
- proxyReq.setHeader("Content-Length", `'${Buffer.byteLength(bodyData)}'`);
135
- proxyReq.write(bodyData);
136
- };
137
- if (contentType &&
138
- (contentType.includes("application/json") || contentType.includes("+json"))) {
139
- writeBody(JSON.stringify(requestBody));
140
- }
141
- if (contentType &&
142
- contentType.includes("application/x-www-form-urlencoded") &&
143
- !Array.isArray(requestBody)) {
144
- writeBody(querystring.stringify(requestBody));
145
- }
146
- };
147
- exports.fixRequestBody = fixRequestBody;
@@ -1,30 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.castHttpError = exports.PrimitiveType = exports.HttpMethod = exports.HttpProtocol = void 0;
4
- var HttpProtocol;
5
- (function (HttpProtocol) {
6
- HttpProtocol["http"] = "http";
7
- HttpProtocol["https"] = "https";
8
- })(HttpProtocol || (exports.HttpProtocol = HttpProtocol = {}));
9
- var HttpMethod;
10
- (function (HttpMethod) {
11
- HttpMethod["POST"] = "POST";
12
- HttpMethod["PATCH"] = "PATCH";
13
- HttpMethod["PUT"] = "PUT";
14
- HttpMethod["GET"] = "GET";
15
- HttpMethod["DELETE"] = "DELETE";
16
- })(HttpMethod || (exports.HttpMethod = HttpMethod = {}));
17
- var PrimitiveType;
18
- (function (PrimitiveType) {
19
- PrimitiveType["string"] = "string";
20
- PrimitiveType["number"] = "number";
21
- PrimitiveType["boolean"] = "boolean";
22
- })(PrimitiveType || (exports.PrimitiveType = PrimitiveType = {}));
23
- const castHttpError = (error) => {
24
- if (!error.message || typeof error.message !== "string")
25
- return;
26
- if (error.context && typeof error.message !== "string")
27
- return;
28
- return { message: error.message, context: error.context };
29
- };
30
- exports.castHttpError = castHttpError;
@@ -1,41 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.HttpHandler = void 0;
7
- const express_1 = __importDefault(require("express"));
8
- const cookie_parser_1 = __importDefault(require("cookie-parser"));
9
- const cors_1 = __importDefault(require("cors"));
10
- const https_1 = require("firebase-functions/v2/https");
11
- // export interface HandlerEnv {
12
- // connectionToken: () => string;
13
- // }
14
- class HttpHandler {
15
- constructor(name) {
16
- this.name = name;
17
- this.corsAllowList = [];
18
- this.items = [];
19
- this.exp = (0, express_1.default)();
20
- }
21
- add(...items) {
22
- this.items.push(...items);
23
- return this;
24
- }
25
- baseSetup() {
26
- this.exp.use((0, cors_1.default)({ credentials: true, origin: true }));
27
- this.exp.use((0, cookie_parser_1.default)());
28
- this.exp.disable("x-powered-by");
29
- // this.exp.use(verifySessionCookie); // todo verify token (maybe connection token)
30
- }
31
- setup() {
32
- this.baseSetup();
33
- for (const item of this.items)
34
- item.setup(this.exp);
35
- return this.createFunction();
36
- }
37
- createFunction() {
38
- return (0, https_1.onRequest)({ cors: [/firebase\.com$/, /web\.app$/] }, this.exp);
39
- }
40
- }
41
- exports.HttpHandler = HttpHandler;
@@ -1,169 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.IHttpHandlerItem = void 0;
7
- const raw_body_1 = __importDefault(require("raw-body"));
8
- const http_js_1 = require("../common/http.js");
9
- const https_1 = require("firebase-functions/v2/https");
10
- const zod_1 = require("zod");
11
- const types_common_js_1 = require("../common/types.common.js");
12
- const http_status_codes_1 = require("@mxpicture/http-status-codes");
13
- // export interface HandlerEnv {
14
- // connectionToken: () => string;
15
- // }
16
- class IHttpHandlerItem {
17
- constructor(name, api) {
18
- this.name = name;
19
- this.api = api;
20
- this.corsAllowList = [];
21
- }
22
- setup(exp) {
23
- exp.get(`/api/${this.name}`, async (req, res) => {
24
- try {
25
- const items = await this.api.query();
26
- return this.httpSuccess(res, items);
27
- }
28
- catch (error) {
29
- return this.httpErrorUnnown(res, error);
30
- }
31
- });
32
- exp.get(`/api/${this.name}_meta`, async (req, res) => {
33
- try {
34
- const items = this.api.metaItems();
35
- return this.httpSuccess(res, items);
36
- }
37
- catch (error) {
38
- return this.httpErrorUnnown(res, error);
39
- }
40
- });
41
- exp.get(`/api/${this.name}/:id`, async (req, res) => {
42
- try {
43
- const item = await this.api.get(req.params.id);
44
- return this.httpSuccess(res, item);
45
- }
46
- catch (error) {
47
- return this.httpErrorUnnown(res, error);
48
- }
49
- });
50
- exp.post(`/api/${this.name}`, async (req, res) => {
51
- try {
52
- const item = await this.extractBodyItem(req);
53
- const valResult = await this.api.validate(item);
54
- if (!valResult.success)
55
- throw (0, zod_1.treeifyError)(valResult.error);
56
- const validated = await this.api.create(valResult.data);
57
- return this.httpSuccess(res, validated);
58
- }
59
- catch (error) {
60
- return this.httpErrorUnnown(res, error);
61
- }
62
- });
63
- exp.patch(`/api/${this.name}/:id`, async (req, res) => {
64
- try {
65
- const item = await this.extractBodyItem(req);
66
- const valResult = await this.api.validatePartial(item);
67
- if (!valResult.success)
68
- throw (0, zod_1.treeifyError)(valResult.error);
69
- const validated = await this.api.updatePartial(req.params.id, valResult.data);
70
- return this.httpSuccess(res, validated);
71
- }
72
- catch (error) {
73
- return this.httpErrorUnnown(res, error);
74
- }
75
- });
76
- }
77
- httpSuccess(res, payload, statusCode = http_status_codes_1.StatusCodes.OK) {
78
- const result = { statusCode, payload };
79
- return res.status(statusCode).json(result);
80
- }
81
- httpError(res, errors, statusCode = http_status_codes_1.StatusCodes.BAD_REQUEST) {
82
- const result = { statusCode, errors };
83
- return res.status(statusCode).json(result);
84
- }
85
- httpErrorUnnown(res, error, statusCode = http_status_codes_1.StatusCodes.BAD_REQUEST) {
86
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
87
- const ae = error;
88
- const messages = [];
89
- if (error instanceof Error) {
90
- messages.push({ message: error.message });
91
- }
92
- else if (typeof error === "string") {
93
- messages.push({ message: error });
94
- }
95
- else if (ae.message) {
96
- const err = (0, types_common_js_1.castHttpError)(ae.message);
97
- if (err)
98
- messages.push(err);
99
- }
100
- else if (ae.errors) {
101
- messages.push(...this.extractZodError(ae));
102
- }
103
- else if (ae.payload) {
104
- if (ae.payload.message && typeof ae.payload.message === "string")
105
- messages.push({ message: ae.payload.message });
106
- else if (typeof ae.payload === "string")
107
- messages.push({ message: ae.payload });
108
- }
109
- else {
110
- messages.push({ message: "unknown" });
111
- }
112
- return this.httpError(res, messages, statusCode);
113
- }
114
- extractZodError(tree, ...contexts) {
115
- const errors = tree.errors?.map((e) => ({
116
- message: e,
117
- context: this.contextPath(...contexts),
118
- })) ?? [];
119
- const items = "items" in tree && tree.items
120
- ? tree.items
121
- : "properties" in tree && tree.properties
122
- ? tree.properties
123
- : [];
124
- if (Array.isArray(items)) {
125
- for (let i = 0; i < items.length; i++)
126
- errors.push(...this.extractZodError(items[i], ...contexts, i));
127
- }
128
- else {
129
- for (const [key, item] of Object.entries(items))
130
- errors.push(...this.extractZodError(item, ...contexts, key));
131
- }
132
- return errors;
133
- }
134
- contextPath(...parts) {
135
- const ps = parts
136
- .filter((p) => !!p)
137
- .map((p) => (typeof p === "string" ? p : `${p}`));
138
- return ps.join(".");
139
- }
140
- createFunction(exp) {
141
- return (0, https_1.onRequest)({ cors: [/firebase\.com$/, /web\.app$/] }, exp);
142
- }
143
- async extractBody(req) {
144
- if (!req.headers["content-type"])
145
- throw new Error("No content type provided");
146
- const body = req.body ??
147
- JSON.parse(await (0, raw_body_1.default)((0, http_js_1.contentstream)(req, false), {
148
- encoding: "utf-8",
149
- }));
150
- if (Array.isArray(body))
151
- return body;
152
- if (body && Object.keys(body).length > 0)
153
- return body;
154
- throw new Error("Invalid / not existing body");
155
- }
156
- async extractBodyItem(req) {
157
- const extr = await this.extractBody(req);
158
- if (!extr || Array.isArray(extr))
159
- throw new Error(`No item found in body`);
160
- return extr;
161
- }
162
- async extractBodyItems(req) {
163
- const extr = await this.extractBody(req);
164
- if (!extr || !Array.isArray(extr))
165
- throw new Error(`No items found in body`);
166
- return extr;
167
- }
168
- }
169
- exports.IHttpHandlerItem = IHttpHandlerItem;
@@ -1,18 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FunctionHandlers = void 0;
4
- class FunctionHandlers {
5
- constructor() {
6
- this.items = {};
7
- }
8
- add(handler) {
9
- this.items[handler.name] = handler;
10
- }
11
- functions() {
12
- const result = {};
13
- for (const [key, item] of Object.entries(this.items))
14
- result[key] = item.setup();
15
- return result;
16
- }
17
- }
18
- exports.FunctionHandlers = FunctionHandlers;
@@ -1,52 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.IApi = void 0;
4
- const zod_meta_1 = require("@mxpicture/zod-meta");
5
- class IApi {
6
- constructor(store, shape) {
7
- this.store = store;
8
- this.shape = shape;
9
- }
10
- metaItems() {
11
- return new zod_meta_1.Meta(this.shape).items();
12
- }
13
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
14
- async create(doc, params) {
15
- const storeDoc = await this.store.create(doc);
16
- return this.fromStore(storeDoc);
17
- }
18
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
19
- async get(id, params) {
20
- const storeDoc = await this.store.get(id);
21
- return this.fromStore(storeDoc);
22
- }
23
- async query(params) {
24
- const storeDocs = await this.store.query(params);
25
- return await Promise.all(storeDocs.map((s) => this.fromStore(s)));
26
- }
27
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
28
- async count(params) {
29
- return this.store.count();
30
- }
31
- async update(id, doc,
32
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
33
- params) {
34
- let storeDoc = await this.toStore(doc);
35
- storeDoc = await this.store.update(id, storeDoc);
36
- return this.fromStore(storeDoc);
37
- }
38
- async updatePartial(id, doc) {
39
- const storeDoc = await this.toStorePartial(doc);
40
- await this.store.update(id, storeDoc);
41
- return this.get(id);
42
- }
43
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
44
- async delete(id, params) {
45
- await this.store.delete(id);
46
- }
47
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
48
- async exists(id, params) {
49
- return this.store.exists(id);
50
- }
51
- }
52
- exports.IApi = IApi;