@goatlab/node-backend 0.0.16 → 0.1.1
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.
- package/README.md +54 -38
- package/dist/container/Container.d.ts +441 -0
- package/dist/container/Container.js +895 -0
- package/dist/container/Container.js.map +1 -0
- package/dist/container/DistributedCacheInvalidator.d.ts +84 -0
- package/dist/container/DistributedCacheInvalidator.js +213 -0
- package/dist/container/DistributedCacheInvalidator.js.map +1 -0
- package/dist/container/LruCache.d.ts +14 -0
- package/dist/container/LruCache.js +23 -0
- package/dist/container/LruCache.js.map +1 -0
- package/dist/container/types.d.ts +128 -0
- package/dist/container/types.js +6 -0
- package/dist/container/types.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +53 -1
- package/dist/index.js.map +1 -1
- package/dist/server/bootstraps/getExpressTrpcApp.d.ts +17 -0
- package/dist/server/bootstraps/getExpressTrpcApp.js +98 -0
- package/dist/server/bootstraps/getExpressTrpcApp.js.map +1 -0
- package/dist/server/consts.d.ts +35 -0
- package/dist/server/consts.js +33 -0
- package/dist/server/consts.js.map +1 -0
- package/dist/server/context/context.model.d.ts +13 -0
- package/dist/server/context/context.model.js +3 -0
- package/dist/server/context/context.model.js.map +1 -0
- package/dist/server/context/request.context.d.ts +40 -0
- package/dist/server/context/request.context.js +91 -0
- package/dist/server/context/request.context.js.map +1 -0
- package/dist/server/context/trpc.context.d.ts +11 -0
- package/dist/server/context/trpc.context.js +67 -0
- package/dist/server/context/trpc.context.js.map +1 -0
- package/dist/server/initOpenApiDocs.d.ts +9 -0
- package/dist/server/initOpenApiDocs.js +18 -0
- package/dist/server/initOpenApiDocs.js.map +1 -0
- package/dist/server/middleware/cloudTaskDecrypt.middleware.d.ts +6 -0
- package/dist/server/middleware/cloudTaskDecrypt.middleware.js +44 -0
- package/dist/server/middleware/cloudTaskDecrypt.middleware.js.map +1 -0
- package/dist/server/middleware/error.middleware.d.ts +17 -0
- package/dist/server/middleware/error.middleware.js +66 -0
- package/dist/server/middleware/error.middleware.js.map +1 -0
- package/dist/server/middleware/handleRequest.middleware.d.ts +7 -0
- package/dist/server/middleware/handleRequest.middleware.js +40 -0
- package/dist/server/middleware/handleRequest.middleware.js.map +1 -0
- package/dist/server/middleware/logger/cloudRun.logger.d.ts +27 -0
- package/dist/server/middleware/logger/cloudRun.logger.js +87 -0
- package/dist/server/middleware/logger/cloudRun.logger.js.map +1 -0
- package/dist/server/middleware/logger/logger.service.d.ts +6 -0
- package/dist/server/middleware/logger/logger.service.js +17 -0
- package/dist/server/middleware/logger/logger.service.js.map +1 -0
- package/dist/server/middleware/logs.middleware.d.ts +7 -0
- package/dist/server/middleware/logs.middleware.js +130 -0
- package/dist/server/middleware/logs.middleware.js.map +1 -0
- package/dist/server/middleware/requireAuthenticated.d.ts +2 -0
- package/dist/server/middleware/requireAuthenticated.js +13 -0
- package/dist/server/middleware/requireAuthenticated.js.map +1 -0
- package/dist/server/middleware/trpcError.middleware.d.ts +4 -0
- package/dist/server/middleware/trpcError.middleware.js +38 -0
- package/dist/server/middleware/trpcError.middleware.js.map +1 -0
- package/dist/server/schemas/user.schema.d.ts +109 -0
- package/dist/server/schemas/user.schema.js +28 -0
- package/dist/server/schemas/user.schema.js.map +1 -0
- package/dist/server/sentry/getSentry.d.ts +6 -0
- package/dist/server/sentry/getSentry.js +45 -0
- package/dist/server/sentry/getSentry.js.map +1 -0
- package/dist/server/sentry/sentry.service.d.ts +34 -0
- package/dist/server/sentry/sentry.service.js +110 -0
- package/dist/server/sentry/sentry.service.js.map +1 -0
- package/dist/server/services/email/email.model.d.ts +84 -0
- package/dist/server/services/email/email.model.js +62 -0
- package/dist/server/services/email/email.model.js.map +1 -0
- package/dist/server/services/email/email.service.d.ts +23 -0
- package/dist/server/services/email/email.service.js +139 -0
- package/dist/server/services/email/email.service.js.map +1 -0
- package/dist/server/services/gcp/getGcpServiceAccountFromBase64.d.ts +15 -0
- package/dist/server/services/gcp/getGcpServiceAccountFromBase64.js +9 -0
- package/dist/server/services/gcp/getGcpServiceAccountFromBase64.js.map +1 -0
- package/dist/server/services/secrets/secret.service.d.ts +32 -0
- package/dist/server/services/secrets/secret.service.js +220 -0
- package/dist/server/services/secrets/secret.service.js.map +1 -0
- package/dist/server/services/sendgrid/sendgrid.model.d.ts +118 -0
- package/dist/server/services/sendgrid/sendgrid.model.js +3 -0
- package/dist/server/services/sendgrid/sendgrid.model.js.map +1 -0
- package/dist/server/services/sendgrid/sendgridApi.service.d.ts +13 -0
- package/dist/server/services/sendgrid/sendgridApi.service.js +79 -0
- package/dist/server/services/sendgrid/sendgridApi.service.js.map +1 -0
- package/dist/server/services/sendgrid/sendgridHooks.model.d.ts +27 -0
- package/dist/server/services/sendgrid/sendgridHooks.model.js +19 -0
- package/dist/server/services/sendgrid/sendgridHooks.model.js.map +1 -0
- package/dist/server/services/translations/template.util.d.ts +7 -0
- package/dist/server/services/translations/template.util.js +11 -0
- package/dist/server/services/translations/template.util.js.map +1 -0
- package/dist/server/services/translations/translation.model.d.ts +4 -0
- package/dist/server/services/translations/translation.model.js +6 -0
- package/dist/server/services/translations/translation.model.js.map +1 -0
- package/dist/server/services/translations/translation.service.d.ts +25 -0
- package/dist/server/services/translations/translation.service.js +97 -0
- package/dist/server/services/translations/translation.service.js.map +1 -0
- package/dist/server/services/util/benchmarker.d.ts +13 -0
- package/dist/server/services/util/benchmarker.js +34 -0
- package/dist/server/services/util/benchmarker.js.map +1 -0
- package/dist/server/services/util/pagination.d.ts +50 -0
- package/dist/server/services/util/pagination.js +57 -0
- package/dist/server/services/util/pagination.js.map +1 -0
- package/dist/server/services/util/url.service.d.ts +75 -0
- package/dist/server/services/util/url.service.js +139 -0
- package/dist/server/services/util/url.service.js.map +1 -0
- package/dist/server/test/express.mock.d.ts +6 -0
- package/dist/server/test/express.mock.js +49 -0
- package/dist/server/test/express.mock.js.map +1 -0
- package/dist/server/test/firebase.mock.d.ts +4 -0
- package/dist/server/test/firebase.mock.js +30 -0
- package/dist/server/test/firebase.mock.js.map +1 -0
- package/dist/server/test/mock.model.d.ts +5 -0
- package/dist/server/test/mock.model.js +3 -0
- package/dist/server/test/mock.model.js.map +1 -0
- package/dist/server/test/trpc.mock.d.ts +6 -0
- package/dist/server/test/trpc.mock.js +14 -0
- package/dist/server/test/trpc.mock.js.map +1 -0
- package/dist/server/trpc.d.ts +364 -0
- package/dist/server/trpc.js +87 -0
- package/dist/server/trpc.js.map +1 -0
- package/dist/server/types/Envinronment.d.ts +1 -0
- package/dist/server/types/Envinronment.js +3 -0
- package/dist/server/types/Envinronment.js.map +1 -0
- package/dist/test/const.d.ts +4 -0
- package/dist/test/const.js +11 -1
- package/dist/test/const.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +34 -3
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { BuiltRouter } from '@trpc/server/unstable-core-do-not-import';
|
|
2
|
+
import type { Express, RequestHandler, Router } from 'express';
|
|
3
|
+
import { CommonLogger } from '@goatlab/js-utils';
|
|
4
|
+
import { SentryService } from '../sentry/sentry.service';
|
|
5
|
+
export declare function getExpressTrpcApp({ trpcRouter, port, expressResources, shouldInitOpenApiDocs, baseUrl, shouldEnableSentry, sentryService, logger, customHandlers }: {
|
|
6
|
+
appName?: string;
|
|
7
|
+
appVersion?: string;
|
|
8
|
+
port: number;
|
|
9
|
+
baseUrl?: string;
|
|
10
|
+
trpcRouter: BuiltRouter<any, any>;
|
|
11
|
+
expressResources?: Router[] | readonly Router[];
|
|
12
|
+
sentryService: SentryService;
|
|
13
|
+
shouldInitOpenApiDocs?: boolean;
|
|
14
|
+
shouldEnableSentry?: boolean;
|
|
15
|
+
logger?: CommonLogger;
|
|
16
|
+
customHandlers?: RequestHandler[];
|
|
17
|
+
}): Express;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getExpressTrpcApp = getExpressTrpcApp;
|
|
4
|
+
const path_1 = require("path");
|
|
5
|
+
const js_utils_1 = require("@goatlab/js-utils");
|
|
6
|
+
const Sentry = require("@sentry/node");
|
|
7
|
+
const trpcExpress = require("@trpc/server/adapters/express");
|
|
8
|
+
const cors_1 = require("cors");
|
|
9
|
+
const express_1 = require("express");
|
|
10
|
+
const helmet_1 = require("helmet");
|
|
11
|
+
const colors_1 = require("kleur/colors");
|
|
12
|
+
const trpc_to_openapi_1 = require("trpc-to-openapi");
|
|
13
|
+
const consts_1 = require("../consts");
|
|
14
|
+
const trpc_context_1 = require("../context/trpc.context");
|
|
15
|
+
const initOpenApiDocs_1 = require("../initOpenApiDocs");
|
|
16
|
+
const error_middleware_1 = require("../middleware/error.middleware");
|
|
17
|
+
const logs_middleware_1 = require("../middleware/logs.middleware");
|
|
18
|
+
const trpcError_middleware_1 = require("../middleware/trpcError.middleware");
|
|
19
|
+
// There is an issue returning the
|
|
20
|
+
// row count in Mysql (bigint) and parsing
|
|
21
|
+
// it back to JSON
|
|
22
|
+
/* eslint-disable */
|
|
23
|
+
// BigInt.prototype.toJSON = function () {
|
|
24
|
+
// return this.toString()
|
|
25
|
+
// }
|
|
26
|
+
/* eslint-enable */
|
|
27
|
+
function getExpressTrpcApp({ trpcRouter, port, expressResources, shouldInitOpenApiDocs, baseUrl = `http://localhost:${port}`, shouldEnableSentry, sentryService, logger = console, customHandlers }) {
|
|
28
|
+
logger.log(`Starting ${consts_1.pkg.name}`);
|
|
29
|
+
const app = (0, express_1.default)();
|
|
30
|
+
app.use((0, cors_1.default)());
|
|
31
|
+
app.use((0, helmet_1.default)());
|
|
32
|
+
app.disable('etag');
|
|
33
|
+
app.set('trust proxy', true);
|
|
34
|
+
if (shouldEnableSentry) {
|
|
35
|
+
Sentry.setupExpressErrorHandler(app);
|
|
36
|
+
}
|
|
37
|
+
app.use(express_1.default.json({ limit: '1mb', type: ['application/json', 'text/plain'] }));
|
|
38
|
+
app.use(express_1.default.urlencoded({ limit: '1mb', extended: true }));
|
|
39
|
+
app.use(express_1.default.raw({
|
|
40
|
+
inflate: true,
|
|
41
|
+
limit: '100kb'
|
|
42
|
+
}));
|
|
43
|
+
app.use((req, resp, next) => (0, logs_middleware_1.expressRequestLogger)(req, resp, next, logger));
|
|
44
|
+
app.use((0, error_middleware_1.genericErrorMiddleware)({
|
|
45
|
+
sentryService: shouldEnableSentry ? sentryService : undefined
|
|
46
|
+
}));
|
|
47
|
+
customHandlers?.forEach(customHandler => {
|
|
48
|
+
app.use(customHandler);
|
|
49
|
+
});
|
|
50
|
+
// TRPC endpoint
|
|
51
|
+
app.use('/trpc', trpcExpress.createExpressMiddleware({
|
|
52
|
+
router: trpcRouter,
|
|
53
|
+
createContext: trpc_context_1.createContext,
|
|
54
|
+
onError: e => (0, trpcError_middleware_1.trpcErrorMiddleware)({ sentryService, ...e })
|
|
55
|
+
}));
|
|
56
|
+
expressResources?.forEach(expressResource => {
|
|
57
|
+
app.use(expressResource);
|
|
58
|
+
});
|
|
59
|
+
if (shouldInitOpenApiDocs) {
|
|
60
|
+
(0, initOpenApiDocs_1.initOpenApiDocs)({
|
|
61
|
+
app,
|
|
62
|
+
appName: 'somename',
|
|
63
|
+
appVersion: 'someversion',
|
|
64
|
+
trpcRouter,
|
|
65
|
+
baseUrl
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
// Apply the OpenAPI Express middleware
|
|
69
|
+
app.use('/', (0, trpc_to_openapi_1.createOpenApiExpressMiddleware)({
|
|
70
|
+
router: trpcRouter,
|
|
71
|
+
createContext: trpc_context_1.createContext,
|
|
72
|
+
onError: trpcError_middleware_1.trpcErrorMiddleware
|
|
73
|
+
}));
|
|
74
|
+
app.use(async (req, res, next) => {
|
|
75
|
+
req.context = await (0, trpc_context_1.createContext)({
|
|
76
|
+
req
|
|
77
|
+
});
|
|
78
|
+
next();
|
|
79
|
+
});
|
|
80
|
+
app.set('view engine', 'ejs');
|
|
81
|
+
app.set('views', [(0, path_1.join)(__dirname, './api/posts/views')]);
|
|
82
|
+
/**
|
|
83
|
+
* Start the app
|
|
84
|
+
*/
|
|
85
|
+
if (process.env.K_SERVICE) {
|
|
86
|
+
app.listen(port, '0.0.0.0');
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
app.listen(port, '::');
|
|
90
|
+
}
|
|
91
|
+
const address = `http://localhost:${port}`;
|
|
92
|
+
const used = js_utils_1.Units.humanByteSize(process.memoryUsage().heapUsed);
|
|
93
|
+
console.log(`App Local Url:
|
|
94
|
+
${(0, colors_1.yellow)(address)}
|
|
95
|
+
in ${js_utils_1.Time.ms(process.uptime() * 1000)}, used ${used}`);
|
|
96
|
+
return app;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=getExpressTrpcApp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getExpressTrpcApp.js","sourceRoot":"","sources":["../../../src/server/bootstraps/getExpressTrpcApp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export declare const pkg: {
|
|
2
|
+
name: string;
|
|
3
|
+
version: string;
|
|
4
|
+
};
|
|
5
|
+
export interface PackageInfo {
|
|
6
|
+
name: string;
|
|
7
|
+
version: string;
|
|
8
|
+
description: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const srcPath: string;
|
|
11
|
+
export declare const secretStoragePath: string;
|
|
12
|
+
export declare const envPath: string;
|
|
13
|
+
export declare const templateDir: string;
|
|
14
|
+
export declare const langDir: string;
|
|
15
|
+
export declare const appStoreTestEmail = "appstore@test.com";
|
|
16
|
+
export declare const playStoreTestEmail = "playstore@test.com";
|
|
17
|
+
export declare const frontendTestUser = "testUser@test.gealium.com";
|
|
18
|
+
export declare const testEmailRegex: RegExp;
|
|
19
|
+
export declare const defaultTimeZone = "America/Santiago";
|
|
20
|
+
export declare const config: {
|
|
21
|
+
pkg: {
|
|
22
|
+
name: string;
|
|
23
|
+
version: string;
|
|
24
|
+
};
|
|
25
|
+
srcPath: string;
|
|
26
|
+
secretStoragePath: string;
|
|
27
|
+
envPath: string;
|
|
28
|
+
templateDir: string;
|
|
29
|
+
langDir: string;
|
|
30
|
+
appStoreTestEmail: string;
|
|
31
|
+
playStoreTestEmail: string;
|
|
32
|
+
frontendTestUser: string;
|
|
33
|
+
testEmailRegex: RegExp;
|
|
34
|
+
defaultTimeZone: string;
|
|
35
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.config = exports.defaultTimeZone = exports.testEmailRegex = exports.frontendTestUser = exports.playStoreTestEmail = exports.appStoreTestEmail = exports.langDir = exports.templateDir = exports.envPath = exports.secretStoragePath = exports.srcPath = exports.pkg = void 0;
|
|
4
|
+
const node_process_1 = require("node:process");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const rootPath = (0, node_process_1.cwd)();
|
|
7
|
+
exports.pkg = require((0, path_1.join)(rootPath, 'package.json'));
|
|
8
|
+
exports.srcPath = (0, path_1.join)(rootPath, './src');
|
|
9
|
+
exports.secretStoragePath = (0, path_1.join)(exports.srcPath, `/_secrets/storage`);
|
|
10
|
+
exports.envPath = (0, path_1.join)(exports.srcPath, `./_env/sodium`);
|
|
11
|
+
exports.templateDir = (0, path_1.join)(exports.srcPath, './services/email/templates');
|
|
12
|
+
exports.langDir = (0, path_1.join)(exports.srcPath, './lang');
|
|
13
|
+
// Stores Test
|
|
14
|
+
exports.appStoreTestEmail = 'appstore@test.com';
|
|
15
|
+
exports.playStoreTestEmail = 'playstore@test.com';
|
|
16
|
+
// Testing
|
|
17
|
+
exports.frontendTestUser = `testUser@test.gealium.com`;
|
|
18
|
+
exports.testEmailRegex = /^testUser(?:_[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})?@test\.gealium\.com$/i;
|
|
19
|
+
exports.defaultTimeZone = 'America/Santiago';
|
|
20
|
+
exports.config = {
|
|
21
|
+
pkg: exports.pkg,
|
|
22
|
+
srcPath: exports.srcPath,
|
|
23
|
+
secretStoragePath: exports.secretStoragePath,
|
|
24
|
+
envPath: exports.envPath,
|
|
25
|
+
templateDir: exports.templateDir,
|
|
26
|
+
langDir: exports.langDir,
|
|
27
|
+
appStoreTestEmail: exports.appStoreTestEmail,
|
|
28
|
+
playStoreTestEmail: exports.playStoreTestEmail,
|
|
29
|
+
frontendTestUser: exports.frontendTestUser,
|
|
30
|
+
testEmailRegex: exports.testEmailRegex,
|
|
31
|
+
defaultTimeZone: exports.defaultTimeZone,
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=consts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consts.js","sourceRoot":"","sources":["../../src/server/consts.ts"],"names":[],"mappings":";;;AAAA,+CAAkC;AAClC,+BAA2B;AAE3B,MAAM,QAAQ,GAAG,IAAA,kBAAG,GAAE,CAAA;AAET,QAAA,GAAG,GAAG,OAAO,CAAC,IAAA,WAAI,EAAC,QAAQ,EAAE,cAAc,CAAC,CAGxD,CAAA;AAQY,QAAA,OAAO,GAAG,IAAA,WAAI,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;AACjC,QAAA,iBAAiB,GAAG,IAAA,WAAI,EAAC,eAAO,EAAE,mBAAmB,CAAC,CAAA;AACtD,QAAA,OAAO,GAAG,IAAA,WAAI,EAAC,eAAO,EAAE,eAAe,CAAC,CAAA;AACxC,QAAA,WAAW,GAAG,IAAA,WAAI,EAAC,eAAO,EAAE,4BAA4B,CAAC,CAAA;AACzD,QAAA,OAAO,GAAG,IAAA,WAAI,EAAC,eAAO,EAAE,QAAQ,CAAC,CAAA;AAC9C,cAAc;AACD,QAAA,iBAAiB,GAAG,mBAAmB,CAAA;AACvC,QAAA,kBAAkB,GAAG,oBAAoB,CAAA;AAEtD,UAAU;AACG,QAAA,gBAAgB,GAAG,2BAA2B,CAAA;AAC9C,QAAA,cAAc,GACzB,kGAAkG,CAAA;AAEvF,QAAA,eAAe,GAAG,kBAAkB,CAAA;AAEpC,QAAA,MAAM,GAAG;IACpB,GAAG,EAAH,WAAG;IACH,OAAO,EAAP,eAAO;IACP,iBAAiB,EAAjB,yBAAiB;IACjB,OAAO,EAAP,eAAO;IACP,WAAW,EAAX,mBAAW;IACX,OAAO,EAAP,eAAO;IACP,iBAAiB,EAAjB,yBAAiB;IACjB,kBAAkB,EAAlB,0BAAkB;IAClB,gBAAgB,EAAhB,wBAAgB;IAChB,cAAc,EAAd,sBAAc;IACd,eAAe,EAAf,uBAAe;CAChB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.model.js","sourceRoot":"","sources":["../../../src/server/context/context.model.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Request } from 'express';
|
|
2
|
+
import type { DecodedUserToken } from '../schemas/user.schema';
|
|
3
|
+
import type { LocationOutput } from './context.model';
|
|
4
|
+
export declare const requestContext: (request: Request, token?: DecodedUserToken) => {
|
|
5
|
+
user: {
|
|
6
|
+
decodedToken: {
|
|
7
|
+
iss?: string;
|
|
8
|
+
aud?: string;
|
|
9
|
+
auth_time?: number;
|
|
10
|
+
sub?: string;
|
|
11
|
+
iat?: number;
|
|
12
|
+
exp?: number;
|
|
13
|
+
email?: string;
|
|
14
|
+
email_verified?: boolean;
|
|
15
|
+
firebase?: any;
|
|
16
|
+
uid?: string;
|
|
17
|
+
displayName?: string;
|
|
18
|
+
name?: string;
|
|
19
|
+
ownerId?: string;
|
|
20
|
+
user_id?: string;
|
|
21
|
+
};
|
|
22
|
+
email: string;
|
|
23
|
+
firebaseId: string;
|
|
24
|
+
};
|
|
25
|
+
url: string;
|
|
26
|
+
method: string;
|
|
27
|
+
xTenandId: string;
|
|
28
|
+
origin: string;
|
|
29
|
+
ip: string;
|
|
30
|
+
getLocation(): Promise<LocationOutput>;
|
|
31
|
+
endpoint: string;
|
|
32
|
+
device: {
|
|
33
|
+
isMobile: boolean;
|
|
34
|
+
isWebApp: boolean;
|
|
35
|
+
isMacPC: boolean;
|
|
36
|
+
os: any;
|
|
37
|
+
isIOS: boolean;
|
|
38
|
+
isAndroid: boolean;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.requestContext = void 0;
|
|
4
|
+
// Handle both CommonJS and ESM compatibility for ua-parser-js
|
|
5
|
+
let UAParser;
|
|
6
|
+
try {
|
|
7
|
+
// Try to import as ESM default
|
|
8
|
+
UAParser = require('ua-parser-js').default || require('ua-parser-js');
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
try {
|
|
12
|
+
// Try direct import
|
|
13
|
+
UAParser = require('ua-parser-js');
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
// Fallback - create a minimal parser
|
|
17
|
+
UAParser = class {
|
|
18
|
+
constructor(ua) { }
|
|
19
|
+
getResult() {
|
|
20
|
+
return {
|
|
21
|
+
browser: { name: 'Unknown', version: '' },
|
|
22
|
+
engine: { name: 'Unknown', version: '' },
|
|
23
|
+
os: { name: 'Unknown', version: '' },
|
|
24
|
+
device: { type: 'desktop' },
|
|
25
|
+
cpu: { architecture: 'unknown' }
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const requestContext = (request, token) => {
|
|
32
|
+
const userAgent = request.headers['user-agent'] || '';
|
|
33
|
+
const parser = new UAParser(userAgent);
|
|
34
|
+
const result = parser.getResult();
|
|
35
|
+
const ip = request.ip ??
|
|
36
|
+
request.socket.remoteAddress ??
|
|
37
|
+
request.headers['x-forwarded-for'] ??
|
|
38
|
+
'';
|
|
39
|
+
const xTenandId = request.headers['x-tenant-id'] || '';
|
|
40
|
+
return {
|
|
41
|
+
user: token && 'email' in token
|
|
42
|
+
? {
|
|
43
|
+
decodedToken: token,
|
|
44
|
+
email: 'email' in token ? token.email : undefined,
|
|
45
|
+
firebaseId: 'uid' in token ? token.uid : undefined
|
|
46
|
+
}
|
|
47
|
+
: undefined,
|
|
48
|
+
url: request.url,
|
|
49
|
+
method: request.method,
|
|
50
|
+
xTenandId,
|
|
51
|
+
origin: request.get('origin'),
|
|
52
|
+
ip,
|
|
53
|
+
async getLocation() {
|
|
54
|
+
// We do not want to import these at the top of the file
|
|
55
|
+
// because they are not used in all requests
|
|
56
|
+
// and we can use the user's location instead
|
|
57
|
+
const geoIp = await Promise.resolve().then(() => require('geoip-lite'));
|
|
58
|
+
const publicIP = await Promise.resolve().then(() => require('public-ip'));
|
|
59
|
+
const tryGetIp = async () => {
|
|
60
|
+
try {
|
|
61
|
+
return await publicIP.publicIpv4();
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const isLocalhost = ['127.0.0.1', 'localhost', '192.168.0.1'];
|
|
68
|
+
const publicIp = isLocalhost.includes(ip) ? await tryGetIp() : ip;
|
|
69
|
+
const location = geoIp.lookup(publicIp || '');
|
|
70
|
+
return {
|
|
71
|
+
ip,
|
|
72
|
+
publicIp: publicIp || '',
|
|
73
|
+
...location
|
|
74
|
+
};
|
|
75
|
+
},
|
|
76
|
+
endpoint: [request.method, request.path || request.url]
|
|
77
|
+
.map(s => s.toLowerCase())
|
|
78
|
+
.join(' '),
|
|
79
|
+
device: {
|
|
80
|
+
isMobile: result?.device?.type === 'mobile',
|
|
81
|
+
isWebApp: result?.device?.type !== 'mobile',
|
|
82
|
+
//isMobileApp: result.ua.includes(env.APP_NAME),
|
|
83
|
+
isMacPC: result.os.name === 'Mac OS' || result?.device?.model === 'Macintosh',
|
|
84
|
+
os: result.os.name,
|
|
85
|
+
isIOS: result.os.name === 'iOS',
|
|
86
|
+
isAndroid: result.os.name === 'Android'
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
exports.requestContext = requestContext;
|
|
91
|
+
//# sourceMappingURL=request.context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.context.js","sourceRoot":"","sources":["../../../src/server/context/request.context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type * as trpcExpress from '@trpc/server/adapters/express';
|
|
2
|
+
import { requestContext } from './request.context';
|
|
3
|
+
declare global {
|
|
4
|
+
namespace Express {
|
|
5
|
+
interface Request {
|
|
6
|
+
context: ReturnType<typeof requestContext>;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export declare const createContext: ({ req, }: trpcExpress.CreateExpressContextOptions) => Promise<ReturnType<typeof requestContext>>;
|
|
11
|
+
export type TrpcContext = Awaited<ReturnType<typeof createContext>>;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createContext = void 0;
|
|
4
|
+
// import { tokenService } from '@src/services/token.service'
|
|
5
|
+
const server_1 = require("@trpc/server");
|
|
6
|
+
const admin = require("firebase-admin");
|
|
7
|
+
const passport_jwt_1 = require("passport-jwt");
|
|
8
|
+
const user_schema_1 = require("../schemas/user.schema");
|
|
9
|
+
const request_context_1 = require("./request.context");
|
|
10
|
+
/**
|
|
11
|
+
* Validate Firebase Token
|
|
12
|
+
*/
|
|
13
|
+
const validateFirebaseToken = async (idToken) => {
|
|
14
|
+
try {
|
|
15
|
+
return await admin.auth().verifyIdToken(idToken);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
// Not a valid Firebase token
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Validate Internal Token
|
|
24
|
+
*/
|
|
25
|
+
const validateInternalToken = async (token) => {
|
|
26
|
+
// const isValid = await tokenService.validateToken({
|
|
27
|
+
// providedToken: token,
|
|
28
|
+
// purpose: 'INTERNAL_SERVICE', // Adjust if needed
|
|
29
|
+
// })
|
|
30
|
+
// if (isValid) {
|
|
31
|
+
// // Optionally fetch more details about the token if needed
|
|
32
|
+
// const tokenDetails = await tokenService.getTokenDetails(token)
|
|
33
|
+
// return {
|
|
34
|
+
// ownerId: tokenDetails?.ownerId,
|
|
35
|
+
// purpose: tokenDetails?.purpose,
|
|
36
|
+
// }
|
|
37
|
+
// }
|
|
38
|
+
return null;
|
|
39
|
+
};
|
|
40
|
+
const createContext = async ({ req, }) => {
|
|
41
|
+
const idToken = passport_jwt_1.ExtractJwt.fromAuthHeaderAsBearerToken()(req);
|
|
42
|
+
if (idToken) {
|
|
43
|
+
try {
|
|
44
|
+
// Check if it's a Firebase Token
|
|
45
|
+
const firebaseUser = await validateFirebaseToken(idToken);
|
|
46
|
+
const email = firebaseUser?.email;
|
|
47
|
+
// const emailVerified = firebaseUser?.email_verified ?? false
|
|
48
|
+
if (firebaseUser && email) {
|
|
49
|
+
//sentryService.setUserId(firebaseUser.uid)
|
|
50
|
+
return (0, request_context_1.requestContext)(req, user_schema_1.firebaseDecodedTokenSchema.parse(firebaseUser));
|
|
51
|
+
}
|
|
52
|
+
// Check if it's an internally generated token
|
|
53
|
+
const internalToken = await validateInternalToken(idToken);
|
|
54
|
+
if (internalToken) {
|
|
55
|
+
// sentryService.setUserId(internalToken.ownerId || 'INTERNAL')
|
|
56
|
+
return (0, request_context_1.requestContext)(req, { tokenPurpose: internalToken.purpose });
|
|
57
|
+
}
|
|
58
|
+
throw new Error('Invalid token format');
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
throw new server_1.TRPCError({ code: 'UNAUTHORIZED', message: err.message });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return (0, request_context_1.requestContext)(req);
|
|
65
|
+
};
|
|
66
|
+
exports.createContext = createContext;
|
|
67
|
+
//# sourceMappingURL=trpc.context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trpc.context.js","sourceRoot":"","sources":["../../../src/server/context/trpc.context.ts"],"names":[],"mappings":";;;AACA,6DAA6D;AAC7D,yCAAwC;AACxC,wCAAuC;AACvC,+CAAyC;AACzC,wDAAmE;AACnE,uDAAkD;AAUlD;;GAEG;AACH,MAAM,qBAAqB,GAAG,KAAK,EACjC,OAAe,EAC4B,EAAE;IAC7C,IAAI,CAAC;QACH,OAAO,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,6BAA6B;QAC7B,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,qBAAqB,GAAG,KAAK,EACjC,KAAa,EAIL,EAAE;IACV,qDAAqD;IACrD,0BAA0B;IAC1B,qDAAqD;IACrD,KAAK;IAEL,iBAAiB;IACjB,+DAA+D;IAC/D,mEAAmE;IACnE,aAAa;IACb,sCAAsC;IACtC,sCAAsC;IACtC,MAAM;IACN,IAAI;IAEJ,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAEM,MAAM,aAAa,GAAG,KAAK,EAAE,EAClC,GAAG,GACqC,EAExC,EAAE;IACF,MAAM,OAAO,GAAG,yBAAU,CAAC,2BAA2B,EAAE,CAAC,GAAG,CAAC,CAAA;IAE7D,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,CAAC;YACH,iCAAiC;YACjC,MAAM,YAAY,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAA;YAEzD,MAAM,KAAK,GAAG,YAAY,EAAE,KAAK,CAAA;YACjC,8DAA8D;YAE9D,IAAI,YAAY,IAAI,KAAK,EAAE,CAAC;gBAC1B,2CAA2C;gBAC3C,OAAO,IAAA,gCAAc,EACnB,GAAG,EACH,wCAA0B,CAAC,KAAK,CAAC,YAAY,CAAC,CAC/C,CAAA;YACH,CAAC;YAED,8CAA8C;YAC9C,MAAM,aAAa,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAA;YAC1D,IAAI,aAAa,EAAE,CAAC;gBAClB,+DAA+D;gBAC/D,OAAO,IAAA,gCAAc,EAAC,GAAG,EAAE,EAAE,YAAY,EAAE,aAAa,CAAC,OAAO,EAAE,CAAC,CAAA;YACrE,CAAC;YAED,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAA;QACzC,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,MAAM,IAAI,kBAAS,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;QACrE,CAAC;IACH,CAAC;IAED,OAAO,IAAA,gCAAc,EAAC,GAAG,CAAC,CAAA;AAC5B,CAAC,CAAA;AArCY,QAAA,aAAa,iBAqCzB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { BuiltRouter } from '@trpc/server/unstable-core-do-not-import';
|
|
2
|
+
import type express from 'express';
|
|
3
|
+
export declare function initOpenApiDocs({ app, appName, appVersion, trpcRouter, baseUrl, }: {
|
|
4
|
+
app: express.Application;
|
|
5
|
+
trpcRouter: BuiltRouter<any, any>;
|
|
6
|
+
appName: string;
|
|
7
|
+
appVersion: string;
|
|
8
|
+
baseUrl: string;
|
|
9
|
+
}): void;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.initOpenApiDocs = initOpenApiDocs;
|
|
4
|
+
const trpc_to_openapi_1 = require("trpc-to-openapi");
|
|
5
|
+
const swaggerUi = require('swagger-ui-express');
|
|
6
|
+
function initOpenApiDocs({ app, appName, appVersion, trpcRouter, baseUrl, }) {
|
|
7
|
+
const openApiDocument = (0, trpc_to_openapi_1.generateOpenApiDocument)(trpcRouter, {
|
|
8
|
+
title: appName,
|
|
9
|
+
version: appVersion,
|
|
10
|
+
baseUrl,
|
|
11
|
+
});
|
|
12
|
+
// Serve the OpenAPI document at /openapi
|
|
13
|
+
app.use('/openapi', (req, res) => {
|
|
14
|
+
res.json(openApiDocument);
|
|
15
|
+
});
|
|
16
|
+
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(openApiDocument));
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=initOpenApiDocs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initOpenApiDocs.js","sourceRoot":"","sources":["../../src/server/initOpenApiDocs.ts"],"names":[],"mappings":";;AAMA,0CAwBC;AA5BD,qDAAyD;AAEzD,MAAM,SAAS,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAA;AAE/C,SAAgB,eAAe,CAAC,EAC9B,GAAG,EACH,OAAO,EACP,UAAU,EACV,UAAU,EACV,OAAO,GAOR;IACC,MAAM,eAAe,GAAG,IAAA,yCAAuB,EAAC,UAAU,EAAE;QAC1D,KAAK,EAAE,OAAO;QACd,OAAO,EAAE,UAAU;QACnB,OAAO;KACR,CAAC,CAAA;IACF,yCAAyC;IACzC,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC/B,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;IAC3B,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAA;AACzE,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { NextFunction, Request, Response } from 'express';
|
|
2
|
+
import { CommonLogger } from '@goatlab/js-utils';
|
|
3
|
+
export declare const useCloudTaskDecryptMiddleware: ({ getLogger, getEncryptionKey, }: {
|
|
4
|
+
getEncryptionKey: () => string;
|
|
5
|
+
getLogger?: () => CommonLogger;
|
|
6
|
+
}) => (req: Request, res: Response, next: NextFunction) => void;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useCloudTaskDecryptMiddleware = void 0;
|
|
4
|
+
const node_utils_1 = require("@goatlab/node-utils");
|
|
5
|
+
const useCloudTaskDecryptMiddleware = ({ getLogger = () => console, getEncryptionKey, }) => {
|
|
6
|
+
const cloudTaskDecryptMiddleware = (req, res, next) => {
|
|
7
|
+
const logger = getLogger();
|
|
8
|
+
const isLocalTest = req.headers['local-queue'] === 'true';
|
|
9
|
+
const base64String = isLocalTest ? req.body.toString('utf8') : req.body;
|
|
10
|
+
try {
|
|
11
|
+
// Parse the body from base64 to ASCII then to JSON
|
|
12
|
+
const body = JSON.parse(Buffer.from(base64String, 'base64').toString('ascii'));
|
|
13
|
+
// Decrypt the body
|
|
14
|
+
const decryptedBody = node_utils_1.Security.decryptObject(body, getEncryptionKey());
|
|
15
|
+
if (!decryptedBody.content) {
|
|
16
|
+
throw new Error('Invalid or missing content in decrypted body');
|
|
17
|
+
}
|
|
18
|
+
// Assign the parsed content to req.body
|
|
19
|
+
req.body = JSON.parse(decryptedBody.content);
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
logger.error(err);
|
|
23
|
+
if (err instanceof Error) {
|
|
24
|
+
res.status(400).json({
|
|
25
|
+
status: 400,
|
|
26
|
+
message: err.message || 'Error processing request',
|
|
27
|
+
});
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
res.status(500).json({
|
|
32
|
+
status: 500,
|
|
33
|
+
message: 'Internal Server Error',
|
|
34
|
+
});
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Call next middleware if no error occurred
|
|
39
|
+
next();
|
|
40
|
+
};
|
|
41
|
+
return cloudTaskDecryptMiddleware;
|
|
42
|
+
};
|
|
43
|
+
exports.useCloudTaskDecryptMiddleware = useCloudTaskDecryptMiddleware;
|
|
44
|
+
//# sourceMappingURL=cloudTaskDecrypt.middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudTaskDecrypt.middleware.js","sourceRoot":"","sources":["../../../src/server/middleware/cloudTaskDecrypt.middleware.ts"],"names":[],"mappings":";;;AAEA,oDAA8C;AAEvC,MAAM,6BAA6B,GAAG,CAAC,EAC5C,SAAS,GAAG,GAAG,EAAE,CAAC,OAAO,EACzB,gBAAgB,GAIjB,EAAE,EAAE;IACH,MAAM,0BAA0B,GAAG,CACjC,GAAY,EACZ,GAAa,EACb,IAAkB,EACZ,EAAE;QACR,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;QAC1B,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,MAAM,CAAA;QACzD,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAA;QAEvE,IAAI,CAAC;YACH,mDAAmD;YACnD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CACrB,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CACtD,CAAA;YAED,mBAAmB;YACnB,MAAM,aAAa,GAAG,qBAAQ,CAAC,aAAa,CAAC,IAAI,EAAE,gBAAgB,EAAE,CAAC,CAAA;YAEtE,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;YACjE,CAAC;YAED,wCAAwC;YACxC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;QAC9C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YACjB,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;gBACzB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBACnB,MAAM,EAAE,GAAG;oBACX,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,0BAA0B;iBACnD,CAAC,CAAA;gBACF,OAAM;YACR,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBACnB,MAAM,EAAE,GAAG;oBACX,OAAO,EAAE,uBAAuB;iBACjC,CAAC,CAAA;gBACF,OAAM;YACR,CAAC;QACH,CAAC;QAED,4CAA4C;QAC5C,IAAI,EAAE,CAAA;IACR,CAAC,CAAA;IAED,OAAO,0BAA0B,CAAA;AACnC,CAAC,CAAA;AArDY,QAAA,6BAA6B,iCAqDzC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type Express from 'express';
|
|
2
|
+
import type { SentryService } from '../sentry/sentry.service';
|
|
3
|
+
export interface GenericErrorMiddlewareCfg {
|
|
4
|
+
sentryService?: SentryService;
|
|
5
|
+
/**
|
|
6
|
+
* Defaults to false.
|
|
7
|
+
* So, by default, it will report ALL errors, not only 5xx.
|
|
8
|
+
*/
|
|
9
|
+
reportOnly5xx?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Generic error handler.
|
|
13
|
+
* Returns HTTP code based on err.data.httpStatusCode (default to 500).
|
|
14
|
+
* Sends json payload as ErrorResponse, transformed via errorSharedUtil.
|
|
15
|
+
*/
|
|
16
|
+
export declare function genericErrorMiddleware(cfg?: GenericErrorMiddlewareCfg): any;
|
|
17
|
+
export declare function respondWithError(request: Express.Request, res: Express.Response, error: any): void;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.genericErrorMiddleware = genericErrorMiddleware;
|
|
4
|
+
exports.respondWithError = respondWithError;
|
|
5
|
+
const js_utils_1 = require("@goatlab/js-utils");
|
|
6
|
+
const { APP_ENV } = process.env;
|
|
7
|
+
const includeErrorStack = APP_ENV !== 'prod' && APP_ENV !== 'test';
|
|
8
|
+
// Hacky way to store the sentryService, so it's available to `respondWithError` function
|
|
9
|
+
let sentryService;
|
|
10
|
+
let reportOnly5xx = false;
|
|
11
|
+
/**
|
|
12
|
+
* Generic error handler.
|
|
13
|
+
* Returns HTTP code based on err.data.httpStatusCode (default to 500).
|
|
14
|
+
* Sends json payload as ErrorResponse, transformed via errorSharedUtil.
|
|
15
|
+
*/
|
|
16
|
+
function genericErrorMiddleware(cfg = {}) {
|
|
17
|
+
sentryService ||= cfg.sentryService;
|
|
18
|
+
reportOnly5xx = cfg.reportOnly5xx ?? false;
|
|
19
|
+
return (error, request, res, _next) => {
|
|
20
|
+
respondWithError(request, res, error);
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function respondWithError(request, res, error) {
|
|
24
|
+
const { headersSent } = res;
|
|
25
|
+
if (headersSent) {
|
|
26
|
+
console.error(`after headersSent`, error);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
console.error(error);
|
|
30
|
+
}
|
|
31
|
+
const originalError = js_utils_1.Errors.anyToError(error, Error, {
|
|
32
|
+
stringifyFn: js_utils_1.Inspect.anyStringifyFn,
|
|
33
|
+
});
|
|
34
|
+
let errorId;
|
|
35
|
+
if (sentryService && shouldReportToSentry(originalError)) {
|
|
36
|
+
errorId = sentryService.captureException(originalError, false);
|
|
37
|
+
}
|
|
38
|
+
if (res.headersSent)
|
|
39
|
+
return;
|
|
40
|
+
const httpError = js_utils_1.Errors.errorToErrorObject(originalError, includeErrorStack);
|
|
41
|
+
httpError.data.errorId = errorId;
|
|
42
|
+
httpError.data.httpStatusCode ||= 500; // Default to 500
|
|
43
|
+
httpError.data.headersSent = headersSent || undefined;
|
|
44
|
+
httpError.data.report ||= undefined; // Set to undefined if false
|
|
45
|
+
js_utils_1.Objects.filterUndefinedValues(httpError.data, true);
|
|
46
|
+
res.status(httpError.data.httpStatusCode).json({
|
|
47
|
+
error: httpError,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
function shouldReportToSentry(error) {
|
|
51
|
+
const e = error;
|
|
52
|
+
// By default - report
|
|
53
|
+
if (!e.data)
|
|
54
|
+
return true;
|
|
55
|
+
// If `report` is set - do as it says
|
|
56
|
+
if (e.data.report === true)
|
|
57
|
+
return true;
|
|
58
|
+
if (e.data.report === false)
|
|
59
|
+
return false;
|
|
60
|
+
// Report if http 5xx, otherwise not
|
|
61
|
+
// If no httpCode - report
|
|
62
|
+
// if httpCode >= 500 - report
|
|
63
|
+
// Otherwise - report, unless !reportOnly5xx is set
|
|
64
|
+
return (!reportOnly5xx || !e.data.httpStatusCode || e.data.httpStatusCode >= 500);
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=error.middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.middleware.js","sourceRoot":"","sources":["../../../src/server/middleware/error.middleware.ts"],"names":[],"mappings":";;AA+BA,wDAcC;AAED,4CAsCC;AA/ED,gDAA4D;AAa5D,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,GAAG,CAAA;AAC/B,MAAM,iBAAiB,GAAG,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,MAAM,CAAA;AAElE,yFAAyF;AACzF,IAAI,aAAwC,CAAA;AAC5C,IAAI,aAAa,GAAG,KAAK,CAAA;AAEzB;;;;GAIG;AACH,SAAgB,sBAAsB,CACpC,MAAiC,EAAE;IAEnC,aAAa,KAAK,GAAG,CAAC,aAAa,CAAA;IACnC,aAAa,GAAG,GAAG,CAAC,aAAa,IAAI,KAAK,CAAA;IAE1C,OAAO,CACL,KAAY,EACZ,OAAwB,EACxB,GAAqB,EACrB,KAA2B,EAC3B,EAAE;QACF,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,CAAA;IACvC,CAAC,CAAA;AACH,CAAC;AAED,SAAgB,gBAAgB,CAC9B,OAAwB,EACxB,GAAqB,EACrB,KAAU;IAEV,MAAM,EAAE,WAAW,EAAE,GAAG,GAAG,CAAA;IAC3B,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAA;IAC3C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IACtB,CAAC;IAED,MAAM,aAAa,GAAG,iBAAM,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE;QACpD,WAAW,EAAE,kBAAO,CAAC,cAAc;KACpC,CAAC,CAAA;IAEF,IAAI,OAA2B,CAAA;IAE/B,IAAI,aAAa,IAAI,oBAAoB,CAAC,aAAa,CAAC,EAAE,CAAC;QACzD,OAAO,GAAG,aAAa,CAAC,gBAAgB,CAAC,aAAa,EAAE,KAAK,CAAC,CAAA;IAChE,CAAC;IAED,IAAI,GAAG,CAAC,WAAW;QAAE,OAAM;IAE3B,MAAM,SAAS,GAAG,iBAAM,CAAC,kBAAkB,CACzC,aAAa,EACb,iBAAiB,CAClB,CAAA;IAED,SAAS,CAAC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IAChC,SAAS,CAAC,IAAI,CAAC,cAAc,KAAK,GAAG,CAAA,CAAC,iBAAiB;IACvD,SAAS,CAAC,IAAI,CAAC,WAAW,GAAG,WAAW,IAAI,SAAS,CAAA;IACrD,SAAS,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAA,CAAC,4BAA4B;IAChE,kBAAO,CAAC,qBAAqB,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IAEnD,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC;QAC7C,KAAK,EAAE,SAAS;KACI,CAAC,CAAA;AACzB,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAY;IACxC,MAAM,CAAC,GAAG,KAAkB,CAAA;IAE5B,sBAAsB;IACtB,IAAI,CAAC,CAAC,CAAC,IAAI;QAAE,OAAO,IAAI,CAAA;IAExB,qCAAqC;IACrC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IACvC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,KAAK;QAAE,OAAO,KAAK,CAAA;IAEzC,oCAAoC;IACpC,0BAA0B;IAC1B,8BAA8B;IAC9B,mDAAmD;IACnD,OAAO,CACL,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,IAAI,GAAG,CACzE,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { NextFunction, Request, Response } from 'express';
|
|
2
|
+
import type { z, ZodSchema } from 'zod';
|
|
3
|
+
export declare const handleRequest: <T extends ZodSchema>(schema: T, handler: (args: {
|
|
4
|
+
req: Request<any, any, z.infer<T>>;
|
|
5
|
+
res: Response;
|
|
6
|
+
body: z.infer<T>;
|
|
7
|
+
}) => Promise<void>) => (req: Request<any, any, any>, res: Response, next: NextFunction) => Promise<void | Response<any, Record<string, any>>>;
|