node-server-engine 1.4.9 → 1.5.0
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/.commitlintrc.js +27 -0
- package/.releaserc.js +56 -0
- package/README.md +154 -2
- package/dist/const/tokenIssuer.js +1 -0
- package/dist/const/tokenIssuer.js.map +1 -1
- package/dist/db/models/SequelizeMeta.js +3 -1
- package/dist/db/models/SequelizeMeta.js.map +1 -1
- package/dist/entities/ElasticSearch/ElasticSearch.js +1 -2
- package/dist/entities/ElasticSearch/ElasticSearch.js.map +1 -1
- package/dist/entities/SocketClient/SocketClient.js +1 -0
- package/dist/entities/SocketClient/SocketClient.js.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/middleware/checkPermission/checkPermission.d.ts +1 -1
- package/dist/middleware/checkPermission/checkPermission.js +4 -2
- package/dist/middleware/checkPermission/checkPermission.js.map +1 -1
- package/dist/utils/jwt/jwt.js +1 -1
- package/dist/utils/jwt/jwt.js.map +1 -1
- package/dist/utils/semverCompare/semverCompare.js +1 -5
- package/dist/utils/semverCompare/semverCompare.js.map +1 -1
- package/package.json +30 -19
- package/.env.example +0 -186
- package/.github/workflows/publish.yml +0 -41
- package/.prettierrc +0 -7
- package/Dockerfile +0 -31
- package/babel.config.json +0 -34
- package/eslint.config.mjs +0 -11
- package/src/const/DebeziumEvent.ts +0 -6
- package/src/const/LogSeverity.ts +0 -7
- package/src/const/index.ts +0 -5
- package/src/const/metrics.ts +0 -6
- package/src/const/mime.ts +0 -37
- package/src/const/tokenIssuer.ts +0 -7
- package/src/db/migrations/20241030121500-create-sequelize-meta-table.ts +0 -29
- package/src/db/models/SequelizeMeta.ts +0 -16
- package/src/db/models/index.ts +0 -2
- package/src/entities/ElasticSearch/ElasticSearch.ts +0 -103
- package/src/entities/ElasticSearch/ElasticSearch.types.ts +0 -7
- package/src/entities/ElasticSearch/index.ts +0 -2
- package/src/entities/Endpoint/Endpoint.test.ts +0 -248
- package/src/entities/Endpoint/Endpoint.ts +0 -221
- package/src/entities/Endpoint/Endpoint.types.ts +0 -181
- package/src/entities/Endpoint/index.ts +0 -2
- package/src/entities/EngineError/EngineError.ts +0 -28
- package/src/entities/EngineError/EngineError.types.ts +0 -15
- package/src/entities/EngineError/index.ts +0 -2
- package/src/entities/KeySet/KeySet.test.ts +0 -126
- package/src/entities/KeySet/KeySet.ts +0 -172
- package/src/entities/KeySet/KeySet.types.ts +0 -28
- package/src/entities/KeySet/index.ts +0 -2
- package/src/entities/LifecycleController/LifecycleController.test.ts +0 -48
- package/src/entities/LifecycleController/LifecycleController.ts +0 -24
- package/src/entities/LifecycleController/LifecycleController.types.ts +0 -5
- package/src/entities/LifecycleController/index.ts +0 -2
- package/src/entities/Localizator/Localizator.ts +0 -139
- package/src/entities/Localizator/Localizator.types.ts +0 -52
- package/src/entities/Localizator/guessNamingConvention/guessNamingConvention.test.ts +0 -165
- package/src/entities/Localizator/guessNamingConvention/guessNamingConvention.ts +0 -58
- package/src/entities/Localizator/guessNamingConvention/index.ts +0 -1
- package/src/entities/Localizator/index.ts +0 -2
- package/src/entities/MessageHandler/MessageHandler.test.ts +0 -130
- package/src/entities/MessageHandler/MessageHandler.ts +0 -72
- package/src/entities/MessageHandler/MessageHandler.types.ts +0 -15
- package/src/entities/MessageHandler/index.ts +0 -2
- package/src/entities/PubSub/PubSub.test.ts +0 -297
- package/src/entities/PubSub/PubSub.ts +0 -202
- package/src/entities/PubSub/PubSub.types.ts +0 -76
- package/src/entities/PubSub/handleMessage/handleMessage.test.ts +0 -102
- package/src/entities/PubSub/handleMessage/handleMessage.ts +0 -65
- package/src/entities/PubSub/handleMessage/index.ts +0 -1
- package/src/entities/PubSub/index.ts +0 -2
- package/src/entities/PushNotification/PushNotification.test.ts +0 -35
- package/src/entities/PushNotification/PushNotification.ts +0 -44
- package/src/entities/PushNotification/PushNotification.types.ts +0 -25
- package/src/entities/PushNotification/index.ts +0 -2
- package/src/entities/Redis/Redis.ts +0 -71
- package/src/entities/Redis/Redis.types.ts +0 -19
- package/src/entities/Redis/Redis.validate.ts +0 -17
- package/src/entities/Redis/index.ts +0 -2
- package/src/entities/Sequelize/Sequelize.config.ts +0 -59
- package/src/entities/Sequelize/Sequelize.test.ts +0 -21
- package/src/entities/Sequelize/Sequelize.ts +0 -75
- package/src/entities/Sequelize/Sequelize.types.ts +0 -10
- package/src/entities/Sequelize/Sequelize.validate.ts +0 -15
- package/src/entities/Sequelize/index.ts +0 -2
- package/src/entities/Server/Server.const.ts +0 -56
- package/src/entities/Server/Server.test.ts +0 -272
- package/src/entities/Server/Server.ts +0 -471
- package/src/entities/Server/Server.types.ts +0 -88
- package/src/entities/Server/index.ts +0 -2
- package/src/entities/SocketClient/SocketClient.test.ts +0 -392
- package/src/entities/SocketClient/SocketClient.ts +0 -401
- package/src/entities/SocketClient/SocketClient.types.ts +0 -62
- package/src/entities/SocketClient/index.ts +0 -2
- package/src/entities/SocketClient/parseMessage/index.ts +0 -1
- package/src/entities/SocketClient/parseMessage/parseMessage.test.ts +0 -20
- package/src/entities/SocketClient/parseMessage/parseMessage.ts +0 -26
- package/src/entities/Storage/Storage.test.ts +0 -58
- package/src/entities/Storage/Storage.ts +0 -219
- package/src/entities/Storage/Storage.types.ts +0 -57
- package/src/entities/Storage/index.ts +0 -2
- package/src/entities/ValidationError/ValidationError.ts +0 -34
- package/src/entities/ValidationError/index.ts +0 -1
- package/src/entities/WebError/WebError.test.ts +0 -18
- package/src/entities/WebError/WebError.ts +0 -23
- package/src/entities/WebError/WebError.types.ts +0 -9
- package/src/entities/WebError/index.ts +0 -2
- package/src/entities/index.ts +0 -16
- package/src/index.ts +0 -6
- package/src/metrics/debug.ts +0 -10
- package/src/metrics/index.ts +0 -2
- package/src/metrics/request.ts +0 -17
- package/src/middleware/authHmac/authHmac.test.ts +0 -86
- package/src/middleware/authHmac/authHmac.ts +0 -56
- package/src/middleware/authHmac/authHmac.types.ts +0 -7
- package/src/middleware/authHmac/index.ts +0 -2
- package/src/middleware/authJwt/authJwt.test.ts +0 -54
- package/src/middleware/authJwt/authJwt.ts +0 -55
- package/src/middleware/authJwt/authJwt.types.ts +0 -14
- package/src/middleware/authJwt/index.ts +0 -2
- package/src/middleware/authStatic/authStatic.test.ts +0 -36
- package/src/middleware/authStatic/authStatic.ts +0 -45
- package/src/middleware/authStatic/index.ts +0 -1
- package/src/middleware/authTls/authTls.test.ts +0 -138
- package/src/middleware/authTls/authTls.ts +0 -119
- package/src/middleware/authTls/authTls.types.ts +0 -13
- package/src/middleware/authTls/index.ts +0 -2
- package/src/middleware/checkPermission/checkPermission.ts +0 -33
- package/src/middleware/checkPermission/index.ts +0 -1
- package/src/middleware/error/error.test.ts +0 -60
- package/src/middleware/error/error.ts +0 -25
- package/src/middleware/error/index.ts +0 -1
- package/src/middleware/fileUploader/fileUploader.ts +0 -154
- package/src/middleware/fileUploader/fileUploader.types.ts +0 -35
- package/src/middleware/fileUploader/index.ts +0 -2
- package/src/middleware/fileUploader/isMultiPart/index.ts +0 -1
- package/src/middleware/fileUploader/isMultiPart/isMultipart.ts +0 -9
- package/src/middleware/fileUploader/validate/index.ts +0 -1
- package/src/middleware/fileUploader/validate/validate.ts +0 -27
- package/src/middleware/fourOhFour/fourOhFour.test.ts +0 -14
- package/src/middleware/fourOhFour/fourOhFour.ts +0 -13
- package/src/middleware/fourOhFour/index.ts +0 -1
- package/src/middleware/geminiFileUploader/geminiFileUploader.ts +0 -68
- package/src/middleware/geminiFileUploader/index.ts +0 -1
- package/src/middleware/healthCheck/healthCheck.test.ts +0 -12
- package/src/middleware/healthCheck/healthCheck.ts +0 -14
- package/src/middleware/healthCheck/index.ts +0 -1
- package/src/middleware/index.ts +0 -17
- package/src/middleware/metrics/index.ts +0 -1
- package/src/middleware/metrics/metrics.test.ts +0 -46
- package/src/middleware/metrics/metrics.ts +0 -24
- package/src/middleware/multiPartFileUploader/index.ts +0 -2
- package/src/middleware/multiPartFileUploader/multiPartFileUploader.ts +0 -249
- package/src/middleware/multiPartFileUploader/multiPartFileUploader.types.ts +0 -23
- package/src/middleware/multiPartFileUploader/validate/index.ts +0 -1
- package/src/middleware/multiPartFileUploader/validate/validate.ts +0 -27
- package/src/middleware/requestMetrics/index.ts +0 -1
- package/src/middleware/requestMetrics/requestMetrics.test.ts +0 -77
- package/src/middleware/requestMetrics/requestMetrics.ts +0 -20
- package/src/middleware/swaggerDocs/index.ts +0 -2
- package/src/middleware/swaggerDocs/swaggerDocs.ts +0 -114
- package/src/middleware/swaggerDocs/swaggerDocs.types.ts +0 -41
- package/src/middleware/userResolver/index.ts +0 -1
- package/src/middleware/userResolver/userResolver.ts +0 -53
- package/src/middleware/validate/index.ts +0 -1
- package/src/middleware/validate/validate.test.ts +0 -43
- package/src/middleware/validate/validate.ts +0 -25
- package/src/middleware/version/index.ts +0 -1
- package/src/middleware/version/version.test.ts +0 -23
- package/src/middleware/version/version.ts +0 -12
- package/src/utils/checkEnvironment/index.ts +0 -49
- package/src/utils/createHttpServer/createHttpServer.test.ts +0 -24
- package/src/utils/createHttpServer/createHttpServer.ts +0 -34
- package/src/utils/createHttpServer/createHttpServer.validate.ts +0 -17
- package/src/utils/createHttpServer/index.ts +0 -1
- package/src/utils/createSortedObject/createSortedObject.ts +0 -20
- package/src/utils/createSortedObject/createSortedObjet.test.ts +0 -47
- package/src/utils/createSortedObject/index.ts +0 -1
- package/src/utils/dbMigration/dbMigration.test.ts +0 -209
- package/src/utils/dbMigration/dbMigration.ts +0 -199
- package/src/utils/dbMigration/dbMigration.types.ts +0 -11
- package/src/utils/dbMigration/index.ts +0 -2
- package/src/utils/dbMigration/migrateMetadataTable/index.ts +0 -1
- package/src/utils/dbMigration/migrateMetadataTable/migrateMetadataTable.test.ts +0 -59
- package/src/utils/dbMigration/migrateMetadataTable/migrateMetadataTable.ts +0 -102
- package/src/utils/envAssert/envAssert.ts +0 -31
- package/src/utils/envAssert/index.ts +0 -1
- package/src/utils/envAssert/validators/hostList.ts +0 -17
- package/src/utils/envAssert/validators/index.ts +0 -5
- package/src/utils/envAssert/validators/ipList.ts +0 -13
- package/src/utils/envAssert/validators/path.ts +0 -13
- package/src/utils/envAssert/validators/string.ts +0 -9
- package/src/utils/envAssert/validators/stringList.ts +0 -13
- package/src/utils/filter/filter.ts +0 -17
- package/src/utils/filter/index.ts +0 -1
- package/src/utils/geminiFileUpload/geminiFileUpload.ts +0 -93
- package/src/utils/geminiFileUpload/index.ts +0 -1
- package/src/utils/hmac/checkEnv/checkEnv.test.ts +0 -18
- package/src/utils/hmac/checkEnv/checkEnv.ts +0 -9
- package/src/utils/hmac/checkEnv/index.ts +0 -1
- package/src/utils/hmac/createHmac/createHmac.ts +0 -33
- package/src/utils/hmac/createHmac/index.ts +0 -1
- package/src/utils/hmac/index.ts +0 -4
- package/src/utils/hmac/index.types.ts +0 -13
- package/src/utils/hmac/signPayload/index.ts +0 -1
- package/src/utils/hmac/signPayload/signPayload.ts +0 -16
- package/src/utils/hmac/verifySignature/index.ts +0 -1
- package/src/utils/hmac/verifySignature/verifySignature.ts +0 -24
- package/src/utils/index.ts +0 -29
- package/src/utils/jwt/index.ts +0 -2
- package/src/utils/jwt/jwt.test.ts +0 -28
- package/src/utils/jwt/jwt.ts +0 -182
- package/src/utils/jwt/jwt.types.ts +0 -21
- package/src/utils/report/index.ts +0 -3
- package/src/utils/report/output.ts +0 -45
- package/src/utils/report/output.types.ts +0 -70
- package/src/utils/report/report.test.ts +0 -133
- package/src/utils/report/report.ts +0 -133
- package/src/utils/report/report.types.ts +0 -13
- package/src/utils/request/index.ts +0 -1
- package/src/utils/request/request.test.ts +0 -26
- package/src/utils/request/request.ts +0 -48
- package/src/utils/secretManager/index.ts +0 -2
- package/src/utils/secretManager/secretLoader.ts +0 -62
- package/src/utils/secretManager/secretResolver.ts +0 -35
- package/src/utils/semverCompare/index.ts +0 -1
- package/src/utils/semverCompare/semverCompare.test.ts +0 -49
- package/src/utils/semverCompare/semverCompare.ts +0 -60
- package/src/utils/sendEmail/index.ts +0 -2
- package/src/utils/sendEmail/sendEmail.ts +0 -61
- package/src/utils/sendEmail/sendEmail.types.ts +0 -61
- package/src/utils/sendPush/index.ts +0 -2
- package/src/utils/sendPush/sendPush.ts +0 -20
- package/src/utils/sendPush/sendPush.types.ts +0 -25
- package/src/utils/tlsConfig/index.ts +0 -2
- package/src/utils/tlsConfig/tlsConfig.test.ts +0 -32
- package/src/utils/tlsConfig/tlsConfig.ts +0 -47
- package/src/utils/tlsConfig/tlsConfig.types.ts +0 -11
- package/src/utils/tlsConfig/tlsConfig.validate.ts +0 -25
- package/src/utils/tlsRequest/index.ts +0 -1
- package/src/utils/tlsRequest/tlsRequest.test.ts +0 -63
- package/src/utils/tlsRequest/tlsRequest.ts +0 -12
- package/src/utils/trimPathSlash/index.ts +0 -1
- package/src/utils/trimPathSlash/trimPathSlash.test.ts +0 -26
- package/src/utils/trimPathSlash/trimPathSlash.ts +0 -8
- package/test/env.ts +0 -53
- package/test/factory/index.ts +0 -8
- package/test/factory/sequelizeMeta.ts +0 -12
- package/test/hooks.ts +0 -35
- package/test/index.ts +0 -3
- package/test/stub/index.ts +0 -3
- package/test/stub/stubLocales.ts +0 -68
- package/test/stub/stubPubSub.ts +0 -7
- package/test/stub/stubStorage.ts +0 -77
- package/test/stub/stubStorage.types.ts +0 -11
- package/test/utils/app.ts +0 -31
- package/test/utils/index.ts +0 -1
- package/tsconfig.build.json +0 -5
- package/tsconfig.json +0 -32
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { Subscription, Message } from '@google-cloud/pubsub';
|
|
2
|
-
import { PubSubMessageHandler, PubSubDebeziumPayload } from '../PubSub.types';
|
|
3
|
-
import { LogSeverity } from 'const';
|
|
4
|
-
import { EngineError } from 'entities/EngineError';
|
|
5
|
-
import { reportDebug, reportError } from 'utils';
|
|
6
|
-
|
|
7
|
-
const namespace = 'engine:PubSub:handleMessage';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* handle the pubSubClients on message event
|
|
11
|
-
* @param message - Message to parse and handle
|
|
12
|
-
* @param subscription - The related Pub/Sub subscription object
|
|
13
|
-
* @param handlers - Message handlers
|
|
14
|
-
* @param isDebezium - Indicates that the subscription from Debezium events
|
|
15
|
-
*/
|
|
16
|
-
export async function handleMessage(
|
|
17
|
-
message: Message,
|
|
18
|
-
subscription: Subscription,
|
|
19
|
-
handlers: Array<PubSubMessageHandler<unknown>>,
|
|
20
|
-
isDebezium = false
|
|
21
|
-
): Promise<void> {
|
|
22
|
-
reportDebug({
|
|
23
|
-
namespace,
|
|
24
|
-
message: `Received message from Pub/Sub [${subscription.name}]`
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
message.ack();
|
|
28
|
-
|
|
29
|
-
let payload;
|
|
30
|
-
try {
|
|
31
|
-
payload = JSON.parse(message.data.toString()) as unknown;
|
|
32
|
-
|
|
33
|
-
// When handling Debezium message, we calculate automatically the keys that have changed between the previous and current state
|
|
34
|
-
if (isDebezium) {
|
|
35
|
-
payload = payload as PubSubDebeziumPayload<Record<string, unknown>>;
|
|
36
|
-
const { before, after } = payload;
|
|
37
|
-
if (before && after)
|
|
38
|
-
payload.diff = Object.keys(after).filter(
|
|
39
|
-
(key) => after[key] !== before[key]
|
|
40
|
-
);
|
|
41
|
-
else if (before) payload.diff = Object.keys(before);
|
|
42
|
-
else if (after) payload.diff = Object.keys(after);
|
|
43
|
-
else
|
|
44
|
-
throw new EngineError({
|
|
45
|
-
severity: LogSeverity.WARNING,
|
|
46
|
-
message: `Debezium Pub/Sub message did not include before nor after value [${subscription.name}]`,
|
|
47
|
-
data: { subscription, message: message.data.toString() }
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
} catch {
|
|
51
|
-
throw new EngineError({
|
|
52
|
-
severity: LogSeverity.WARNING,
|
|
53
|
-
message: `Pub/Sub message is not valid JSON ${subscription.name}`,
|
|
54
|
-
data: { subscription, message: message.data.toString() }
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
for (const handler of handlers) {
|
|
59
|
-
try {
|
|
60
|
-
await handler(payload, message.attributes, message.publishTime);
|
|
61
|
-
} catch (error) {
|
|
62
|
-
reportError(error);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './handleMessage';
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { expect } from 'chai';
|
|
2
|
-
import { faker } from '@faker-js/faker';
|
|
3
|
-
import { stub, SinonStub } from 'sinon';
|
|
4
|
-
import { PushNotification } from './PushNotification';
|
|
5
|
-
import { PushNotificationNotification } from './PushNotification.types';
|
|
6
|
-
import { PubSub } from 'entities/PubSub/PubSub';
|
|
7
|
-
|
|
8
|
-
describe('Entities - PushNotification', function () {
|
|
9
|
-
let notification: PushNotificationNotification;
|
|
10
|
-
let publishStub: SinonStub;
|
|
11
|
-
let userId: string;
|
|
12
|
-
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
process.env.CHART = 'test';
|
|
15
|
-
process.env.PUBSUB_PUSH_NOTIFICATION_QUEUE_TOPIC = 'notification_queue';
|
|
16
|
-
userId = faker.string.uuid();
|
|
17
|
-
notification = {
|
|
18
|
-
title: faker.lorem.word(),
|
|
19
|
-
body: faker.lorem.word()
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
publishStub = stub(PubSub, 'publish');
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it('should send push notification to the user', async () => {
|
|
26
|
-
await PushNotification.sendPush(userId, notification);
|
|
27
|
-
expect(publishStub).to.have.been.calledOnceWithExactly(
|
|
28
|
-
'notification_queue',
|
|
29
|
-
{
|
|
30
|
-
...notification,
|
|
31
|
-
userId
|
|
32
|
-
}
|
|
33
|
-
);
|
|
34
|
-
});
|
|
35
|
-
});
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { PushNotificationNotification } from './PushNotification.types';
|
|
2
|
-
import { EngineError } from 'entities';
|
|
3
|
-
import { PubSub } from 'entities/PubSub';
|
|
4
|
-
import { reportDebug } from 'utils';
|
|
5
|
-
|
|
6
|
-
const namespace = 'engine:PushNotification';
|
|
7
|
-
|
|
8
|
-
export const PushNotification = {
|
|
9
|
-
/** Initialize the push notification entity */
|
|
10
|
-
init(): void {
|
|
11
|
-
reportDebug({ namespace, message: 'Initializing PushNotification' });
|
|
12
|
-
if (!process.env.PUBSUB_PUSH_NOTIFICATION_QUEUE_TOPIC)
|
|
13
|
-
throw new EngineError({
|
|
14
|
-
message:
|
|
15
|
-
'Environment variable PUBSUB_PUSH_NOTIFICATION_QUEUE_TOPIC is not defined'
|
|
16
|
-
});
|
|
17
|
-
// Register publisher
|
|
18
|
-
PubSub.addPublisher(process.env.PUBSUB_PUSH_NOTIFICATION_QUEUE_TOPIC);
|
|
19
|
-
},
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Send a push notification through the push service
|
|
23
|
-
* @param userId - ID of the user that should receive the notification
|
|
24
|
-
* @param notification - Notification that should be sent
|
|
25
|
-
*/
|
|
26
|
-
async sendPush(
|
|
27
|
-
userId: string,
|
|
28
|
-
notification: PushNotificationNotification
|
|
29
|
-
): Promise<void> {
|
|
30
|
-
reportDebug({
|
|
31
|
-
namespace,
|
|
32
|
-
message: `Received data to send notification to user with Id '${userId}'`,
|
|
33
|
-
data: { userId, notification }
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
await PubSub.publish(
|
|
37
|
-
process.env.PUBSUB_PUSH_NOTIFICATION_QUEUE_TOPIC as string,
|
|
38
|
-
{
|
|
39
|
-
...notification,
|
|
40
|
-
userId
|
|
41
|
-
}
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
};
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/** Notification to send to the user's device */
|
|
2
|
-
export interface PushNotificationNotification {
|
|
3
|
-
/** Title of the notification */
|
|
4
|
-
title?: string;
|
|
5
|
-
/** Body of the notification */
|
|
6
|
-
body?: string;
|
|
7
|
-
/** Data payload of the notification */
|
|
8
|
-
payload?: unknown;
|
|
9
|
-
/** Indicates that the notification is a VOIP notification */
|
|
10
|
-
voip?: boolean;
|
|
11
|
-
/** Indicate that it is a background notification (data only, low priority) */
|
|
12
|
-
background?: boolean;
|
|
13
|
-
/** Push token can be specified here is we want to send to a given user */
|
|
14
|
-
token?: string;
|
|
15
|
-
/** Indicates that the data content can be mutated by the client (iOS) */
|
|
16
|
-
mutable?: boolean;
|
|
17
|
-
/** Indicates that the notification requires some client side processing to be displayed (iOS) */
|
|
18
|
-
contentAvailable?: boolean;
|
|
19
|
-
/** Time to live of the notification in seconds. After this the notification will not be distributed */
|
|
20
|
-
ttl?: number;
|
|
21
|
-
/** Indicate that it is a high priority notification */
|
|
22
|
-
priority?: boolean;
|
|
23
|
-
/** Notifications with the same string here will be collapsed in the system tray */
|
|
24
|
-
collapseId?: string;
|
|
25
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { Redis as RedisClient } from 'ioredis';
|
|
2
|
-
import { RedisInterface, RedisCreateOptions } from './Redis.types';
|
|
3
|
-
import { validateRedisEnvironment } from './Redis.validate';
|
|
4
|
-
import { EngineError } from 'entities/EngineError';
|
|
5
|
-
import { LifecycleController } from 'entities/LifecycleController';
|
|
6
|
-
|
|
7
|
-
export let redisClient: undefined | RedisClient;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* We use a proxy to extend the Redis behavior and allow initialization of the client only when needed while keeping the same interface
|
|
11
|
-
*/
|
|
12
|
-
export const Redis = new Proxy<RedisInterface>(
|
|
13
|
-
// Due to how we do the proxying, we are forced to ignore ts-errors, we could never create an object that respects the interface properly
|
|
14
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
15
|
-
// @ts-ignore
|
|
16
|
-
{},
|
|
17
|
-
{
|
|
18
|
-
get: function (target, property): unknown {
|
|
19
|
-
if (property === 'init') return init;
|
|
20
|
-
if (property === 'shutdown') return shutdown;
|
|
21
|
-
// Create the redis client if it does not exist
|
|
22
|
-
if (!redisClient)
|
|
23
|
-
throw new EngineError({ message: 'Redis client was not initialized' });
|
|
24
|
-
// Call the function on the redis client
|
|
25
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
26
|
-
// @ts-ignore
|
|
27
|
-
return redisClient[property] as unknown;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* On init create client anc connect
|
|
34
|
-
*/
|
|
35
|
-
export function init(): void {
|
|
36
|
-
// Ignore if already initialized
|
|
37
|
-
if (redisClient) return;
|
|
38
|
-
redisClient = createRedisClient();
|
|
39
|
-
LifecycleController.register(Redis);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* On shutdown close connection and clear client
|
|
44
|
-
*/
|
|
45
|
-
export async function shutdown(): Promise<void> {
|
|
46
|
-
if (redisClient) await redisClient.quit();
|
|
47
|
-
redisClient = undefined;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Create Redis client
|
|
52
|
-
*/
|
|
53
|
-
export function createRedisClient(
|
|
54
|
-
options: RedisCreateOptions = {}
|
|
55
|
-
): RedisClient {
|
|
56
|
-
// Check that environment variables are correctly set
|
|
57
|
-
validateRedisEnvironment(options);
|
|
58
|
-
// Throw an error if there is no host initial
|
|
59
|
-
if (!process.env.REDIS_HOST)
|
|
60
|
-
throw new EngineError({
|
|
61
|
-
message: 'Host required to initialize Redis connection'
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
return new RedisClient({
|
|
65
|
-
port: process.env.REDIS_PORT ? parseInt(process.env.REDIS_PORT) : undefined,
|
|
66
|
-
host: process.env.REDIS_HOST,
|
|
67
|
-
username: process.env.REDIS_USERNAME,
|
|
68
|
-
password: process.env.REDIS_PASSWORD,
|
|
69
|
-
db: 0
|
|
70
|
-
});
|
|
71
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { Redis as IoRedis, Cluster, RedisOptions } from 'ioredis';
|
|
2
|
-
|
|
3
|
-
export type RedisInterface = IoRedis &
|
|
4
|
-
Cluster & {
|
|
5
|
-
/** Start the redis service */
|
|
6
|
-
init: () => void;
|
|
7
|
-
/** Stop the redis service */
|
|
8
|
-
shutdown: () => Promise<void>;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
/** Options to initialize a Redis client */
|
|
12
|
-
export interface RedisCreateOptions {
|
|
13
|
-
/** Redis client settings */
|
|
14
|
-
redis?: RedisOptions;
|
|
15
|
-
/** Should the client perform readiness check when establishing the connection */
|
|
16
|
-
enableReadyCheck?: boolean;
|
|
17
|
-
/** Cluster mode read operation settings, can make reads on masters, slaves, or both */
|
|
18
|
-
scaleReads?: string;
|
|
19
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { RedisCreateOptions } from './Redis.types';
|
|
2
|
-
import { EngineError } from 'entities/EngineError';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Verify that the environment variables to connect to a Redis server are properly set
|
|
6
|
-
*/
|
|
7
|
-
export function validateRedisEnvironment(options: RedisCreateOptions): void {
|
|
8
|
-
const host = process.env.REDIS_HOST ?? options.redis?.host;
|
|
9
|
-
if (typeof host !== 'string')
|
|
10
|
-
throw new EngineError({ message: 'No host specified for Redis instance' });
|
|
11
|
-
|
|
12
|
-
const port = process.env.REDIS_PORT
|
|
13
|
-
? parseInt(process.env.REDIS_PORT)
|
|
14
|
-
: options.redis?.port;
|
|
15
|
-
if (typeof port !== 'number')
|
|
16
|
-
throw new EngineError({ message: 'No port specified for Redis instance' });
|
|
17
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { Options, Dialect } from 'sequelize';
|
|
2
|
-
import { validateSequelizeEnvironment } from './Sequelize.validate';
|
|
3
|
-
|
|
4
|
-
// Check that environment variables are correctly set
|
|
5
|
-
validateSequelizeEnvironment();
|
|
6
|
-
|
|
7
|
-
const config: Options = {
|
|
8
|
-
username: process.env.SQL_USER,
|
|
9
|
-
password: process.env.SQL_PASSWORD,
|
|
10
|
-
database: process.env.SQL_DB,
|
|
11
|
-
host: process.env.SQL_HOST,
|
|
12
|
-
port: process.env.SQL_PORT ? parseInt(process.env.SQL_PORT) : 5432, // Default port for PostgreSQL
|
|
13
|
-
dialect: (process.env.SQL_TYPE ?? 'postgres') as Dialect, // Dynamically set the dialect (postgres, mysql, mssql)
|
|
14
|
-
logging: false, // Set to true for debugging SQL queries
|
|
15
|
-
define: {
|
|
16
|
-
freezeTableName: false, // Prevent automatic pluralization of table names
|
|
17
|
-
charset: 'utf8mb4', // Set character set for MySQL/MariaDB
|
|
18
|
-
collate: 'utf8mb4_unicode_ci' // Set collation for MySQL/MariaDB
|
|
19
|
-
},
|
|
20
|
-
retry: {
|
|
21
|
-
max: 5 // Maximum retry attempts for failed queries
|
|
22
|
-
},
|
|
23
|
-
dialectOptions: {},
|
|
24
|
-
pool: {
|
|
25
|
-
max: 5,
|
|
26
|
-
min: 0,
|
|
27
|
-
acquire: 30000, // Maximum time to wait for a connection
|
|
28
|
-
idle: 10000 // Maximum idle time for connections
|
|
29
|
-
},
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
// Additional configurations for MSSQL
|
|
33
|
-
if (config.dialect === 'mssql') {
|
|
34
|
-
config.dialectOptions = {
|
|
35
|
-
requestTimeout: 30000, // Increase request timeout for MSSQL
|
|
36
|
-
connectTimeout: 30000, // Increase connection timeout for MSSQL
|
|
37
|
-
encrypt: true, // Use encryption for MSSQL (set to false if not needed)
|
|
38
|
-
trustServerCertificate: true, // Set to true if using self-signed certificates
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Add specific dialect configurations if necessary for MySQL/PostgreSQL
|
|
43
|
-
if (config.dialect === 'mysql') {
|
|
44
|
-
config.dialectOptions = {
|
|
45
|
-
timezone: 'Z', // Set timezone for MySQL
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (config.dialect === 'postgres') {
|
|
50
|
-
config.dialectOptions = {
|
|
51
|
-
ssl: process.env.PG_SSL === 'true' ? { rejectUnauthorized: false } : false, // SSL options for PostgreSQL (if required)
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export const development = config;
|
|
56
|
-
export const staging = config;
|
|
57
|
-
export const production = config;
|
|
58
|
-
export const test = config;
|
|
59
|
-
export default config;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { expect } from 'chai';
|
|
2
|
-
import { validateSequelizeEnvironment } from './Sequelize.validate';
|
|
3
|
-
|
|
4
|
-
describe('Entity - Sequelize', () => {
|
|
5
|
-
it('Should validate process env if needed', () => {
|
|
6
|
-
process.env.SQL_HOST = '127.0.0.1';
|
|
7
|
-
process.env.SQL_PORT = '5423';
|
|
8
|
-
process.env.SQL_PASSWORD = 'password';
|
|
9
|
-
process.env.SQL_DB = 'db';
|
|
10
|
-
process.env.SQL_USER = 'sql';
|
|
11
|
-
expect(validateSequelizeEnvironment).not.to.throw();
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it('Should allow only required variables', () => {
|
|
15
|
-
process.env.SQL_HOST = '127.0.0.1';
|
|
16
|
-
process.env.SQL_PASSWORD = 'password';
|
|
17
|
-
process.env.SQL_DB = 'db';
|
|
18
|
-
process.env.SQL_USER = 'sql';
|
|
19
|
-
expect(validateSequelizeEnvironment).not.to.throw();
|
|
20
|
-
});
|
|
21
|
-
});
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { Sequelize, ModelCtor } from 'sequelize-typescript';
|
|
2
|
-
import dbConfig from './Sequelize.config';
|
|
3
|
-
import { Sequelize as SequelizeInterface } from './Sequelize.types';
|
|
4
|
-
import { validateSequelizeEnvironment } from './Sequelize.validate';
|
|
5
|
-
import { EngineError } from 'entities/EngineError';
|
|
6
|
-
import { LifecycleController } from 'entities/LifecycleController';
|
|
7
|
-
|
|
8
|
-
export let sequelizeClient: undefined | Sequelize;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* We use a proxy to extend the Sequelize behavior and allow initialization of the client only when needed while keeping the same interface
|
|
12
|
-
*/
|
|
13
|
-
export const sequelize = new Proxy<SequelizeInterface>(
|
|
14
|
-
// Due to how we do the proxying, we are forced to ignore ts-errors, we could never create an object that respects the interface properly
|
|
15
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
16
|
-
// @ts-ignore
|
|
17
|
-
{},
|
|
18
|
-
{
|
|
19
|
-
get: function (target, property): unknown {
|
|
20
|
-
if (property === 'init') return init;
|
|
21
|
-
if (property === 'shutdown') return shutdown;
|
|
22
|
-
if (property === 'addModels') return addModels;
|
|
23
|
-
// Create the sequelize client if it does not exist
|
|
24
|
-
if (!sequelizeClient)
|
|
25
|
-
throw new EngineError({
|
|
26
|
-
message: 'Sequelize client was not initialized'
|
|
27
|
-
});
|
|
28
|
-
// Call the function on the sequelize client
|
|
29
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
30
|
-
// @ts-ignore
|
|
31
|
-
return sequelizeClient[property] as unknown;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
/** On init create client and connect */
|
|
37
|
-
export function init(): void {
|
|
38
|
-
// Ignore if already initialized
|
|
39
|
-
if (sequelizeClient) return;
|
|
40
|
-
sequelizeClient = createSequelizeClient();
|
|
41
|
-
sequelizeClient
|
|
42
|
-
.authenticate()
|
|
43
|
-
.then(() => console.log('Connected to database.'))
|
|
44
|
-
.catch((err: Error) =>
|
|
45
|
-
console.error('Unable to connect to the database:', err)
|
|
46
|
-
);
|
|
47
|
-
LifecycleController.register(sequelize);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/** On shutdown close connection and clear client */
|
|
51
|
-
export async function shutdown(): Promise<void> {
|
|
52
|
-
if (sequelizeClient) await sequelizeClient.close();
|
|
53
|
-
sequelizeClient = undefined;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export function addModels(models: Array<ModelCtor>): void {
|
|
57
|
-
if (!sequelizeClient)
|
|
58
|
-
throw new EngineError({
|
|
59
|
-
message: 'Sequelize client was not initialized'
|
|
60
|
-
});
|
|
61
|
-
sequelizeClient.addModels(models);
|
|
62
|
-
sequelizeClient.sync();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/** Create Sequelize client */
|
|
66
|
-
export function createSequelizeClient(): Sequelize {
|
|
67
|
-
// Throw an error if there is no host initial
|
|
68
|
-
validateSequelizeEnvironment();
|
|
69
|
-
return new Sequelize(
|
|
70
|
-
process.env.SQL_DB as string,
|
|
71
|
-
process.env.SQL_USER as string,
|
|
72
|
-
process.env.SQL_PASSWORD as string,
|
|
73
|
-
dbConfig
|
|
74
|
-
);
|
|
75
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Sequelize as SequelizeClass, ModelCtor } from 'sequelize-typescript';
|
|
2
|
-
|
|
3
|
-
export type Sequelize = SequelizeClass & {
|
|
4
|
-
/** Start the sequelize service */
|
|
5
|
-
init: () => void;
|
|
6
|
-
/** Stop the sequelize service */
|
|
7
|
-
shutdown: () => Promise<void>;
|
|
8
|
-
/** Register a model with sequelize */
|
|
9
|
-
addModels: (models: Array<ModelCtor>) => void;
|
|
10
|
-
};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { assertEnvironment } from 'utils/checkEnvironment';
|
|
2
|
-
import { envAssert } from 'utils/envAssert';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Verify that the environment variables to connect to a SQL server are properly set
|
|
6
|
-
*/
|
|
7
|
-
export function validateSequelizeEnvironment(): void {
|
|
8
|
-
// We only check if there is at least the host specified
|
|
9
|
-
if (process.env.SQL_HOST) assertEnvironment({ SQL_HOST: envAssert.isHost() });
|
|
10
|
-
if (process.env.SQL_PASSWORD)
|
|
11
|
-
assertEnvironment({ SQL_PASSWORD: envAssert.isString() });
|
|
12
|
-
if (process.env.SQL_DB) assertEnvironment({ SQL_DB: envAssert.isString() });
|
|
13
|
-
if (process.env.SQL_USER)
|
|
14
|
-
assertEnvironment({ SQL_USER: envAssert.isString() });
|
|
15
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { json, urlencoded, ErrorRequestHandler, RequestHandler } from 'express';
|
|
2
|
-
import morgan from 'morgan';
|
|
3
|
-
import {
|
|
4
|
-
metrics,
|
|
5
|
-
error,
|
|
6
|
-
fourOhFour,
|
|
7
|
-
healthCheck,
|
|
8
|
-
version,
|
|
9
|
-
swaggerDocs
|
|
10
|
-
} from 'middleware';
|
|
11
|
-
|
|
12
|
-
const ACCESS_LOG = JSON.stringify({
|
|
13
|
-
method: ':method',
|
|
14
|
-
status: ':status',
|
|
15
|
-
url: ':url',
|
|
16
|
-
'http-version': ':http-version',
|
|
17
|
-
ip: ':remote-addr',
|
|
18
|
-
'user-agent': ':user-agent',
|
|
19
|
-
'content-length': ':res[content-length]',
|
|
20
|
-
referrer: ':referrer',
|
|
21
|
-
'response-time': ':response-time',
|
|
22
|
-
severity: 'DEBUG',
|
|
23
|
-
message: ':method :url [:status]'
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
// Default middleware that are applied first thing on the primary port, before the business logic endpoints
|
|
27
|
-
export const defaultMiddleware: Array<RequestHandler> = [
|
|
28
|
-
healthCheck(),
|
|
29
|
-
json({ limit: process.env.REQUEST_SIZE_LIMIT ?? '1mb' }),
|
|
30
|
-
urlencoded({
|
|
31
|
-
extended: true,
|
|
32
|
-
limit: process.env.REQUEST_SIZE_LIMIT ?? '1mb'
|
|
33
|
-
}),
|
|
34
|
-
metrics(),
|
|
35
|
-
version()
|
|
36
|
-
].filter((val) => val);
|
|
37
|
-
|
|
38
|
-
// Error handling middleware that are run after the main business logic endpoints
|
|
39
|
-
export const defaultErrorMiddleware: Array<
|
|
40
|
-
RequestHandler | ErrorRequestHandler
|
|
41
|
-
> = [error, fourOhFour];
|
|
42
|
-
|
|
43
|
-
// Middleware that are served on the secondary port
|
|
44
|
-
export const secondaryMiddleware: Array<RequestHandler> = [
|
|
45
|
-
metrics(),
|
|
46
|
-
version(),
|
|
47
|
-
swaggerDocs()
|
|
48
|
-
];
|
|
49
|
-
|
|
50
|
-
// Add morgan logging to default middleware chain when reporting is not silenced
|
|
51
|
-
if (!process.env.SILENCE_REPORT) {
|
|
52
|
-
defaultMiddleware.unshift(morgan(ACCESS_LOG));
|
|
53
|
-
secondaryMiddleware.unshift(morgan(ACCESS_LOG));
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export const shutdownSignals = ['SIGTERM', 'SIGUSR2', 'SIGINT'];
|