@zerooneit/expressive-tea 1.3.0-beta.4 → 1.3.0-beta.5

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/classes/Boot.d.ts CHANGED
@@ -1,14 +1,13 @@
1
1
  import 'reflect-metadata';
2
- import '../inversify.config';
3
2
  import { Express } from 'express';
4
- import Settings from '../classes/Settings';
5
3
  import { ExpressiveTeaApplication } from '@expressive-tea/commons/interfaces';
4
+ import Settings from '../classes/Settings';
6
5
  /**
7
6
  * Expressive Tea Application interface is the response from an started application, contains the express application
8
7
  * and a node http server instance.
9
8
  * @typedef {Object} ExpressiveTeaApplication
10
9
  * @property {Express} application - Express Application Instance
11
- * @property {HTTPServer} server - HTTP Server Object
10
+ * @property { HTTPServer } server - HTTP Server Object
12
11
  * @summary Application Interface
13
12
  */
14
13
  /**
package/classes/Boot.js CHANGED
@@ -1,27 +1,28 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  require("reflect-metadata");
4
- require("../inversify.config");
5
- const $P = require("bluebird");
4
+ const inversify_config_1 = require("../inversify.config");
6
5
  // tslint:disable-next-line:no-duplicate-imports
7
6
  const express = require("express");
7
+ const constants_1 = require("@expressive-tea/commons/constants");
8
+ const Metadata_1 = require("@expressive-tea/commons/classes/Metadata");
9
+ const object_helper_1 = require("@expressive-tea/commons/helpers/object-helper");
10
+ const http_1 = require("../engines/http");
11
+ const websocket_1 = require("../engines/websocket");
12
+ const index_1 = require("../engines/teapot/index");
13
+ const teacup_1 = require("../engines/teacup");
14
+ const Engine_1 = require("../classes/Engine");
15
+ const Settings_1 = require("../classes/Settings");
16
+ const index_2 = require("../engines/socketio/index");
8
17
  const fs = require("fs");
9
18
  const http = require("http");
10
19
  const https = require("https");
11
- const Settings_1 = require("../classes/Settings");
12
- const constants_1 = require("@expressive-tea/commons/constants");
13
- const index_1 = require("../engines/http/index");
14
- const index_2 = require("../engines/websocket/index");
15
- const index_3 = require("../engines/teapot/index");
16
- const teacup_1 = require("../engines/teacup");
17
- // tslint:disable-next-line:no-duplicate-imports
18
- const inversify_config_1 = require("../inversify.config");
19
20
  /**
20
21
  * Expressive Tea Application interface is the response from an started application, contains the express application
21
22
  * and a node http server instance.
22
23
  * @typedef {Object} ExpressiveTeaApplication
23
24
  * @property {Express} application - Express Application Instance
24
- * @property {HTTPServer} server - HTTP Server Object
25
+ * @property { HTTPServer } server - HTTP Server Object
25
26
  * @summary Application Interface
26
27
  */
27
28
  /**
@@ -59,7 +60,7 @@ class Boot {
59
60
  * @returns {Promise<ExpressiveTeaApplication>}
60
61
  */
61
62
  async start() {
62
- return new $P(async (resolver, rejector) => {
63
+ return new Promise(async (resolver, reject) => {
63
64
  try {
64
65
  const localContainer = inversify_config_1.default.createChild();
65
66
  const privateKey = this.settings.get('privateKey');
@@ -68,29 +69,33 @@ class Boot {
68
69
  const secureServer = privateKey && certificate && https.createServer({
69
70
  cert: fs.readFileSync(certificate).toString('utf-8'),
70
71
  key: fs.readFileSync(privateKey).toString('utf-8')
71
- }, this.server);
72
+ });
72
73
  // Injectables
73
74
  localContainer.bind('server').toConstantValue(server);
74
75
  localContainer.bind('secureServer').toConstantValue(secureServer || undefined);
75
76
  localContainer.bind('context').toConstantValue(this);
76
77
  localContainer.bind('settings').toConstantValue(this.settings);
77
- const httpEngine = localContainer.resolve(index_1.default);
78
- const websocketEngine = localContainer.resolve(index_2.default);
79
- const teapotEngine = localContainer.resolve(index_3.default);
80
- const teacupEngine = localContainer.resolve(teacup_1.default);
81
- await websocketEngine.init();
78
+ // Activation
79
+ const isActiveTeapot = Metadata_1.default.get(constants_1.ASSIGN_TEAPOT_KEY, (0, object_helper_1.getClass)(this), 'isTeapotActive');
80
+ const isActiveTeacup = Metadata_1.default.get(constants_1.ASSIGN_TEACUP_KEY, (0, object_helper_1.getClass)(this), 'isTeacupActive');
81
+ const isActiveWebsockets = this.settings.get('startWebsocket');
82
+ // Resolve Engines
83
+ const httpEngine = localContainer.resolve(http_1.default);
84
+ const availableEngines = [
85
+ localContainer.resolve(index_2.default),
86
+ ...isActiveWebsockets ? [localContainer.resolve(websocket_1.default)] : [],
87
+ ...isActiveTeapot ? [localContainer.resolve(index_1.default)] : [],
88
+ ...isActiveTeacup ? [localContainer.resolve(teacup_1.default)] : [],
89
+ ];
90
+ // Initialize Engines
91
+ await Engine_1.default.exec(availableEngines, 'init');
82
92
  await httpEngine.init();
83
- await httpEngine.resolveProxyContainers();
84
- await httpEngine.resolveStages(constants_1.BOOT_ORDER);
85
- await httpEngine.resolveStages([constants_1.BOOT_STAGES.AFTER_APPLICATION_MIDDLEWARES, constants_1.BOOT_STAGES.ON_HTTP_CREATION], server, secureServer);
86
- const listenerServers = await httpEngine.start();
87
- await httpEngine.resolveStages([constants_1.BOOT_STAGES.START], ...listenerServers);
88
- await teapotEngine.start();
89
- await teacupEngine.start();
93
+ await httpEngine.start();
94
+ await Engine_1.default.exec(availableEngines, 'start');
90
95
  resolver({ application: this.server, server, secureServer });
91
96
  }
92
97
  catch (e) {
93
- return rejector(e);
98
+ return reject(e);
94
99
  }
95
100
  });
96
101
  }
@@ -0,0 +1,14 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import Settings from './Settings';
4
+ import Boot from './Boot';
5
+ import http from 'http';
6
+ import https from 'https';
7
+ export default class ExpressiveTeaEngine {
8
+ protected readonly settings: Settings;
9
+ protected readonly context: Boot;
10
+ protected readonly server: http.Server;
11
+ protected readonly serverSecure?: https.Server;
12
+ constructor(ctx: any, server: any, serverSecure: any, settings: any);
13
+ static exec(availableEngines: ExpressiveTeaEngine[], method: string): any;
14
+ }
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const inversify_1 = require("inversify");
5
+ let ExpressiveTeaEngine = class ExpressiveTeaEngine {
6
+ constructor(ctx, server, serverSecure, settings) {
7
+ this.settings = settings;
8
+ this.context = ctx;
9
+ this.server = server;
10
+ this.serverSecure = serverSecure;
11
+ }
12
+ static exec(availableEngines, method) {
13
+ return Promise.all(availableEngines
14
+ // tslint:disable-next-line:no-string-literal
15
+ .filter(engine => typeof engine[method] === 'function')
16
+ // tslint:disable-next-line:no-string-literal
17
+ .map(engine => engine[method]()));
18
+ }
19
+ };
20
+ ExpressiveTeaEngine = tslib_1.__decorate([
21
+ (0, inversify_1.injectable)(),
22
+ tslib_1.__param(0, (0, inversify_1.inject)('context')),
23
+ tslib_1.__param(1, (0, inversify_1.inject)('server')),
24
+ tslib_1.__param(2, (0, inversify_1.inject)('secureServer')),
25
+ tslib_1.__param(2, (0, inversify_1.optional)()),
26
+ tslib_1.__param(3, (0, inversify_1.inject)('settings')),
27
+ tslib_1.__metadata("design:paramtypes", [Object, Object, Object, Object])
28
+ ], ExpressiveTeaEngine);
29
+ exports.default = ExpressiveTeaEngine;
@@ -0,0 +1,2 @@
1
+ export declare const SOCKET_IO_INSTANCE_KEY = "SOCKETIO:INSTANCE";
2
+ export declare const SOCKET_IO_SECURE_INSTANCE_KEY = "SOCKETIO:INSTANCE:SECURE";
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SOCKET_IO_SECURE_INSTANCE_KEY = exports.SOCKET_IO_INSTANCE_KEY = void 0;
4
+ exports.SOCKET_IO_INSTANCE_KEY = 'SOCKETIO:INSTANCE';
5
+ exports.SOCKET_IO_SECURE_INSTANCE_KEY = 'SOCKETIO:INSTANCE:SECURE';
@@ -3,12 +3,8 @@
3
3
  import * as http from 'http';
4
4
  import * as https from 'https';
5
5
  import { BOOT_STAGES } from '@expressive-tea/commons/constants';
6
- export default class HTTPEngine {
7
- private readonly settings;
8
- private readonly context;
9
- private readonly server;
10
- private readonly serverSecure?;
11
- constructor(ctx: any, server: any, serverSecure: any, settings: any);
6
+ import ExpressiveTeaEngine from '../../classes/Engine';
7
+ export default class HTTPEngine extends ExpressiveTeaEngine {
12
8
  private listen;
13
9
  start(): Promise<(http.Server | https.Server)[]>;
14
10
  init(): Promise<void>;
@@ -1,21 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
- const $P = require("bluebird");
5
4
  const inversify_1 = require("inversify");
6
5
  const boot_helper_1 = require("../../helpers/boot-helper");
7
6
  const constants_1 = require("@expressive-tea/commons/constants");
8
7
  const object_helper_1 = require("@expressive-tea/commons/helpers/object-helper");
9
8
  const Metadata_1 = require("@expressive-tea/commons/classes/Metadata");
10
- let HTTPEngine = class HTTPEngine {
11
- constructor(ctx, server, serverSecure, settings) {
12
- this.context = ctx;
13
- this.server = server;
14
- this.serverSecure = serverSecure;
15
- this.settings = settings;
16
- }
9
+ const Engine_1 = require("../../classes/Engine");
10
+ let HTTPEngine = class HTTPEngine extends Engine_1.default {
17
11
  listen(server, port) {
18
- return new $P((resolve, reject) => {
12
+ return new Promise((resolve, reject) => {
13
+ console.log('Listening on port', port, server.listen);
19
14
  server.listen(port);
20
15
  server.on('error', error => {
21
16
  reject(error);
@@ -27,19 +22,24 @@ let HTTPEngine = class HTTPEngine {
27
22
  });
28
23
  }
29
24
  async start() {
30
- return [
25
+ console.log(`Starting Server Test`);
26
+ const listenerServers = [
31
27
  await this.listen(this.server, this.settings.get('port')),
32
28
  (this.serverSecure) ? await this.listen(this.serverSecure, this.settings.get('securePort')) : null
33
29
  ];
30
+ await this.resolveStages([constants_1.BOOT_STAGES.START], ...listenerServers);
31
+ return listenerServers;
34
32
  }
35
33
  async init() {
36
34
  await (0, boot_helper_1.resolveDirectives)(this.context, this.context.getApplication());
37
35
  await (0, boot_helper_1.resolveStatic)(this.context, this.context.getApplication());
36
+ // HTTP Engine Resolve Stages
37
+ await this.resolveProxyContainers();
38
+ await this.resolveStages(constants_1.BOOT_ORDER);
39
+ await this.resolveStages([constants_1.BOOT_STAGES.AFTER_APPLICATION_MIDDLEWARES, constants_1.BOOT_STAGES.ON_HTTP_CREATION], this.server, this.serverSecure);
38
40
  }
39
41
  async resolveStages(stages, ...extraArgs) {
40
- return $P.map(stages, s => {
41
- return (0, boot_helper_1.resolveStage)(s, this.context, this.context.getApplication(), ...extraArgs);
42
- });
42
+ return Promise.all(stages.map(s => (0, boot_helper_1.resolveStage)(s, this.context, this.context.getApplication(), ...extraArgs)));
43
43
  }
44
44
  async resolveProxyContainers() {
45
45
  const ProxyContainers = Metadata_1.default.get(constants_1.ROUTER_PROXIES_KEY, (0, object_helper_1.getClass)(this.context)) || [];
@@ -49,12 +49,6 @@ let HTTPEngine = class HTTPEngine {
49
49
  }
50
50
  };
51
51
  HTTPEngine = tslib_1.__decorate([
52
- (0, inversify_1.injectable)(),
53
- tslib_1.__param(0, (0, inversify_1.inject)('context')),
54
- tslib_1.__param(1, (0, inversify_1.inject)('server')),
55
- tslib_1.__param(2, (0, inversify_1.inject)('secureServer')),
56
- tslib_1.__param(2, (0, inversify_1.optional)()),
57
- tslib_1.__param(3, (0, inversify_1.inject)('settings')),
58
- tslib_1.__metadata("design:paramtypes", [Object, Object, Object, Object])
52
+ (0, inversify_1.injectable)()
59
53
  ], HTTPEngine);
60
54
  exports.default = HTTPEngine;
@@ -0,0 +1,6 @@
1
+ import ExpressiveTeaEngine from '../../classes/Engine';
2
+ export default class SocketIOEngine extends ExpressiveTeaEngine {
3
+ private io;
4
+ private ioSecure;
5
+ init(): Promise<void>;
6
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const socket_io_1 = require("socket.io");
4
+ const Engine_1 = require("../../classes/Engine");
5
+ const Metadata_1 = require("@expressive-tea/commons/classes/Metadata");
6
+ const constants_1 = require("../constants/constants");
7
+ class SocketIOEngine extends Engine_1.default {
8
+ async init() {
9
+ const commonConfig = {
10
+ path: '/exp-tea/',
11
+ transports: ['websocket', 'polling']
12
+ };
13
+ this.io = this.server && new socket_io_1.Server(this.server, Object.assign({}, commonConfig));
14
+ this.ioSecure = this.serverSecure && new socket_io_1.Server(this.serverSecure, Object.assign({}, commonConfig));
15
+ Metadata_1.default.set(constants_1.SOCKET_IO_INSTANCE_KEY, this.io, this.context);
16
+ Metadata_1.default.set(constants_1.SOCKET_IO_SECURE_INSTANCE_KEY, this.ioSecure, this.context);
17
+ }
18
+ }
19
+ exports.default = SocketIOEngine;
20
+ ;
@@ -1,10 +1,6 @@
1
- export default class TeacupEngine {
2
- private readonly settings;
3
- private readonly context;
4
- private readonly server;
5
- private readonly serverSecure?;
1
+ import ExpressiveTeaEngine from '../../classes/Engine';
2
+ export default class TeacupEngine extends ExpressiveTeaEngine {
6
3
  private teacupSettings;
7
- private isActive;
8
4
  private publicKey;
9
5
  private privateKey;
10
6
  private publicServerKey;
@@ -12,7 +8,6 @@ export default class TeacupEngine {
12
8
  private clientSignature;
13
9
  private client;
14
10
  private header;
15
- constructor(ctx: any, settings: any, server: any, serverSecure: any);
16
11
  private handshaked;
17
12
  private accepted;
18
13
  start(): Promise<void>;
@@ -10,7 +10,8 @@ const Metadata_1 = require("@expressive-tea/commons/classes/Metadata");
10
10
  const constants_1 = require("@expressive-tea/commons/constants");
11
11
  const teapot_helper_1 = require("../../helpers/teapot-helper");
12
12
  const object_helper_1 = require("@expressive-tea/commons/helpers/object-helper");
13
- let TeacupEngine = class TeacupEngine {
13
+ const Engine_1 = require("../../classes/Engine");
14
+ let TeacupEngine = class TeacupEngine extends Engine_1.default {
14
15
  header() {
15
16
  console.log(chalk.white.bold('Teacup Engine is initializing...'));
16
17
  console.log(chalk `
@@ -25,69 +26,53 @@ let TeacupEngine = class TeacupEngine {
25
26
  All Communication are encrypted to ensure intruder can not connected, however, please does not share any sensitive data like keys or passwords to avoid security issues.
26
27
  `);
27
28
  }
28
- constructor(ctx, settings, server, serverSecure) {
29
- this.server = server;
30
- this.serverSecure = serverSecure;
31
- this.settings = settings;
32
- this.context = ctx;
33
- this.teacupSettings = Metadata_1.default.get(constants_1.ASSIGN_TEACUP_KEY, (0, object_helper_1.getClass)(this.context));
34
- this.isActive = Metadata_1.default.get(constants_1.ASSIGN_TEACUP_KEY, (0, object_helper_1.getClass)(this.context), 'isTeacupActive');
35
- if (!this.isActive) {
36
- return;
37
- }
38
- const scheme = url.parse(this.teacupSettings.serverUrl);
39
- const { publicKey, privateKey } = teapot_helper_1.default.generateKeys(this.teacupSettings.clientKey);
40
- this.publicKey = publicKey;
41
- this.privateKey = privateKey;
42
- this.clientSignature = teapot_helper_1.default.sign(this.teacupSettings.clientKey, this.privateKey, this.teacupSettings.clientKey);
43
- this.client = (0, socket_io_client_1.io)(`http://${scheme.host}`, {
44
- path: '/teapot',
45
- reconnection: true,
46
- autoConnect: false
47
- });
48
- }
49
- handshaked(data) {
29
+ handshaked(key, signature, isSecure, cb) {
50
30
  try {
51
- console.log(chalk `{cyan.bold [TEACUP]} - [{magenta.bold ${this.client.id}}]: {yellow.bold Started Verification}`);
52
- const serverPublicKey = Buffer.from(data.key, 'base64').toString('ascii');
53
- const serverSignature = Buffer.from(data.signature, 'base64');
54
- if (teapot_helper_1.default.verify(this.teacupSettings.clientKey, serverPublicKey, serverSignature)) {
55
- console.log(chalk `{cyan.bold [TEACUP]} - [{magenta.bold ${this.client.id}}]: {green.bold Verified}`);
56
- this.publicServerKey = serverPublicKey;
57
- this.serverSignature = serverSignature;
58
- this.client.emit('handshake', {
59
- key: Buffer.from(this.publicKey).toString('base64'),
60
- signature: this.clientSignature.toString('base64')
61
- });
62
- return;
31
+ console.log(chalk `{cyan.bold [TEACUP]} - [{magenta.bold ${this.client.id}}]: {yellow.bold Server Verification Started}`);
32
+ if (!teapot_helper_1.default.verify(this.teacupSettings.clientKey, key.toString('ascii'), signature)) {
33
+ throw new Error('Fail to Verify Client on Teapod.');
63
34
  }
64
- throw new Error('Fail to Verify Client on Teapod.');
35
+ console.log(chalk `{cyan.bold [TEACUP]} - [{magenta.bold ${this.client.id}}]: {green.bold Server Has Been Verified}`);
36
+ this.publicServerKey = key;
37
+ this.serverSignature = signature;
38
+ cb(Buffer.from(this.publicKey), this.clientSignature);
65
39
  }
66
40
  catch (e) {
67
41
  console.error(chalk `{cyan.bold [TEACUP]} - {red.bold TEAPOD} {magenta.bold ${this.client.id}}: Failed with next message: ${e.message}`);
68
42
  this.client.disconnect();
69
43
  }
70
44
  }
71
- accepted() {
45
+ accepted(cb) {
72
46
  var _a;
73
47
  console.log(chalk `{cyan.bold [TEACUP]} - [{magenta.bold ${this.client.id}}]: {green.bold Registered} - {blue.bold <${this.teacupSettings.serverUrl}>} <-> {white.bold ${this.teacupSettings.mountTo}}`);
74
- this.client.emit('register', teapot_helper_1.default.encrypt({
48
+ const encryptedMessage = teapot_helper_1.default.encrypt({
75
49
  mountTo: this.teacupSettings.mountTo,
76
50
  address: this.teacupSettings.address
77
- }, this.serverSignature.slice(0, 32)));
51
+ }, this.serverSignature.slice(0, 32));
52
+ cb(encryptedMessage);
78
53
  const onClose = () => {
79
54
  try {
80
55
  this.client.close();
81
56
  }
82
- catch (_) { }
57
+ catch (_) {
58
+ }
83
59
  };
84
60
  this.server.on('close', onClose);
85
61
  (_a = this.serverSecure) === null || _a === void 0 ? void 0 : _a.on('close', onClose);
86
62
  }
87
63
  async start() {
88
- if (!this.isActive) {
89
- return;
90
- }
64
+ this.teacupSettings = Metadata_1.default.get(constants_1.ASSIGN_TEACUP_KEY, (0, object_helper_1.getClass)(this.context));
65
+ const scheme = url.parse(this.teacupSettings.serverUrl);
66
+ const { publicKey, privateKey } = teapot_helper_1.default.generateKeys(this.teacupSettings.clientKey);
67
+ const protocol = teapot_helper_1.default.httpSchema(scheme.protocol);
68
+ this.publicKey = publicKey;
69
+ this.privateKey = privateKey;
70
+ this.clientSignature = teapot_helper_1.default.sign(this.teacupSettings.clientKey, this.privateKey, this.teacupSettings.clientKey);
71
+ this.client = (0, socket_io_client_1.io)(`${protocol}//${scheme.host}/teapot`, {
72
+ path: '/exp-tea/',
73
+ reconnection: true,
74
+ autoConnect: false
75
+ });
91
76
  this.header();
92
77
  this.client.on('handshake', this.handshaked.bind(this));
93
78
  this.client.on('accepted', this.accepted.bind(this));
@@ -96,12 +81,6 @@ All Communication are encrypted to ensure intruder can not connected, however, p
96
81
  }
97
82
  };
98
83
  TeacupEngine = tslib_1.__decorate([
99
- (0, inversify_1.injectable)(),
100
- tslib_1.__param(0, (0, inversify_1.inject)('context')),
101
- tslib_1.__param(1, (0, inversify_1.inject)('settings')),
102
- tslib_1.__param(2, (0, inversify_1.inject)('server')),
103
- tslib_1.__param(3, (0, inversify_1.inject)('secureServer')),
104
- tslib_1.__param(3, (0, inversify_1.optional)()),
105
- tslib_1.__metadata("design:paramtypes", [Object, Object, Object, Object])
84
+ (0, inversify_1.injectable)()
106
85
  ], TeacupEngine);
107
86
  exports.default = TeacupEngine;
@@ -1,23 +1,19 @@
1
- export default class TeapotEngine {
2
- private readonly settings;
3
- private readonly context;
4
- private readonly server;
5
- private readonly serverSecure?;
1
+ import ExpressiveTeaEngine from '../../classes/Engine';
2
+ export default class TeapotEngine extends ExpressiveTeaEngine {
6
3
  private clients;
7
4
  private registeredRoute;
8
5
  private teapotSettings;
9
6
  private publicKey;
10
7
  private privateKey;
11
- private isActive;
12
8
  private serverSignature;
13
9
  private socketServer;
14
10
  private static header;
15
11
  private registerTeacup;
16
- private acceptedHandshake;
12
+ private clientVerification;
17
13
  private registered;
18
14
  private removeFromRoutes;
19
15
  private findClientInRoutes;
20
16
  private disconnected;
21
- constructor(ctx: any, server: any, serverSecure: any, settings: any);
17
+ init(): Promise<void>;
22
18
  start(): Promise<void>;
23
19
  }
@@ -4,11 +4,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const tslib_1 = require("tslib");
5
5
  const chalk = require("chalk");
6
6
  const inversify_1 = require("inversify");
7
- const ProxyRoute_1 = require("../../classes/ProxyRoute");
8
7
  const Metadata_1 = require("@expressive-tea/commons/classes/Metadata");
9
8
  const constants_1 = require("@expressive-tea/commons/constants");
9
+ const ProxyRoute_1 = require("../../classes/ProxyRoute");
10
+ const Engine_1 = require("../../classes/Engine");
10
11
  const teapot_helper_1 = require("../../helpers/teapot-helper");
11
- let TeapotEngine = TeapotEngine_1 = class TeapotEngine {
12
+ const constants_2 = require("../constants/constants");
13
+ let TeapotEngine = TeapotEngine_1 = class TeapotEngine extends Engine_1.default {
14
+ constructor() {
15
+ super(...arguments);
16
+ this.clients = new Map();
17
+ this.registeredRoute = new Map();
18
+ }
12
19
  static header(teapotSettings) {
13
20
  console.log(chalk.white.bold('Teapot Engine is initializing...'));
14
21
  console.log(chalk `
@@ -28,64 +35,44 @@ All Communication are encrypted to ensure intruder can not connected, however, p
28
35
  }
29
36
  registerTeacup(teacup) {
30
37
  console.log(chalk `{cyan.bold [TEAPOT]} - {blue TEACUP} [{magenta.bold ${teacup.id}}]: {grey.bold Connected}`);
31
- teacup.emit('handshake', {
32
- key: Buffer.from(this.publicKey).toString('base64'),
33
- signature: this.serverSignature.toString('base64')
34
- });
35
- teacup.on('handshake', this.acceptedHandshake.bind(teacup, this));
36
- teacup.on('register', this.registered.bind(teacup, this));
37
- teacup.on('disconnect', this.disconnected.bind(teacup, this));
38
+ teacup.emit('handshake', Buffer.from(this.publicKey), this.serverSignature, Boolean(this.serverSecure), this.clientVerification.bind(this, teacup));
39
+ teacup.on('disconnect', this.disconnected.bind(this, teacup));
38
40
  }
39
- acceptedHandshake(ctx, data) {
40
- const self = this;
41
+ clientVerification(teacup, userPublicKey, userSignature) {
42
+ console.log(chalk `{cyan.bold [TEAPOT]} - {blue TEACUP} [{magenta.bold ${teacup.id}}]: {yellow.bold Client Verification Started}`);
43
+ console.log('userKey', userPublicKey.toString('base64'));
44
+ console.log('userSignature', userSignature.toString('base64'));
41
45
  try {
42
- console.log(chalk `{cyan.bold [TEAPOT]} - {blue TEACUP} [{magenta.bold ${self.id}}]: {yellow.bold Start Verification}`);
43
- const clientPublicKey = Buffer.from(data.key, 'base64').toString('ascii');
44
- const clientSignature = Buffer.from(data.signature, 'base64');
45
- if (teapot_helper_1.default.verify(ctx.teapotSettings.clientKey, clientPublicKey, clientSignature)) {
46
- console.log(chalk `{cyan.bold [TEAPOT]} - {blue TEACUP} [{magenta.bold ${self.id}}]: {green.bold Verified correctly}`);
47
- ctx.clients.set(self.id, {
48
- publicKey: clientPublicKey,
49
- signature: clientSignature
50
- });
51
- self.emit('accepted', teapot_helper_1.default.encrypt({
52
- signature: ctx.serverSignature.toString('base64')
53
- }, clientSignature.slice(0, 32)));
54
- return;
46
+ if (!teapot_helper_1.default.verify(this.teapotSettings.clientKey, userPublicKey.toString('ascii'), userSignature)) {
47
+ console.log(chalk `{cyan.bold [TEAPOT]} - {red.bold TEACUP} [{magenta.bold ${teacup.id}}]: Failed to verify and will be disconnected...`);
48
+ return teacup.disconnect();
55
49
  }
56
- console.log(chalk `{cyan.bold [TEAPOT]} - {red.bold TEACUP} [{magenta.bold ${self.id}}]: Failed to verify and will be disconnected...`);
57
- self.disconnect();
50
+ this.clients.set(teacup.id, {
51
+ publicKey: userPublicKey,
52
+ signature: userSignature
53
+ });
54
+ teacup.emit('accepted', this.registered.bind(this, teacup));
55
+ console.log(chalk `{cyan.bold [TEAPOT]} - {blue TEACUP} [{magenta.bold ${teacup.id}}]: {green.bold Client Verified}`);
58
56
  }
59
57
  catch (e) {
60
- console.log(chalk `{cyan.bold [TEAPOT]} - {red.bold TEACUP} [{magenta.bold ${self.id}}]: Failed wiht next message: ${e.message}`);
61
- self.disconnect();
58
+ console.log(chalk `{cyan.bold [TEAPOT]} - {red.bold TEACUP} [{magenta.bold ${teacup.id}}]: Failed wiht next message: ${e.message}`);
59
+ teacup.disconnect();
62
60
  }
63
61
  }
64
- registered(ctx, data) {
65
- const self = this;
62
+ registered(teacup, encryptedMessage) {
66
63
  try {
67
- const message = teapot_helper_1.default.decrypt(data, ctx.serverSignature.slice(0, 32));
68
- let proxyRoute;
69
- if (ctx.registeredRoute.has(message.mountTo)) {
70
- proxyRoute = ctx.registeredRoute.get(message.mountTo);
71
- proxyRoute.registerServer(message.address, self.id);
64
+ const message = teapot_helper_1.default.decrypt(encryptedMessage, this.serverSignature.slice(0, 32));
65
+ const isRegistered = this.registeredRoute.has(message.mountTo);
66
+ const proxyRoute = isRegistered ? this.registeredRoute.get(message.mountTo) : new ProxyRoute_1.default(message.mountTo);
67
+ proxyRoute.registerServer(message.address, teacup.id);
68
+ if (!isRegistered) {
69
+ this.registeredRoute.set(message.mountTo, proxyRoute);
70
+ this.context.getApplication().use(message.mountTo, teapot_helper_1.default.proxyResponse.bind(this, proxyRoute));
72
71
  }
73
- else {
74
- proxyRoute = new ProxyRoute_1.default(message.mountTo);
75
- proxyRoute.registerServer(message.address, self.id);
76
- ctx.registeredRoute.set(message.mountTo, proxyRoute);
77
- ctx.context.getApplication().use(message.mountTo, (req, res, next) => {
78
- const router = proxyRoute.registerRoute();
79
- if (!proxyRoute.hasClients()) {
80
- return next();
81
- }
82
- return router(req, res, next);
83
- });
84
- }
85
- console.log(chalk `{cyan.bold [TEAPOT]} - {blue TEACUP} [{magenta.bold ${self.id}}] {blue.bold <${message.address}>} <--> {white.bold ${message.mountTo}}`);
72
+ console.log(chalk `{cyan.bold [TEAPOT]} - {blue TEACUP} [{magenta.bold ${teacup.id}}] {blue.bold <${message.address}>} <--> {white.bold ${message.mountTo}}`);
86
73
  }
87
74
  catch (e) {
88
- console.log(chalk `{cyan.bold [TEAPOT]} - {red.bold TEACUP} {magenta.bold ${self.id}}: Failed wiht next message: ${e.message}`);
75
+ console.log(chalk `{cyan.bold [TEAPOT]} - {red.bold TEACUP} {magenta.bold ${teacup.id}}: Failed wiht next message: ${e.message}`);
89
76
  }
90
77
  }
91
78
  removeFromRoutes(routes = [], id) {
@@ -103,54 +90,30 @@ All Communication are encrypted to ensure intruder can not connected, however, p
103
90
  });
104
91
  return routes;
105
92
  }
106
- disconnected(ctx, reason) {
107
- const self = this;
93
+ disconnected(teacup, reason) {
108
94
  try {
109
- const routes = ctx.findClientInRoutes(self.id);
110
- ctx.removeFromRoutes(routes, self.id);
111
- console.log(chalk `{cyan.bold [TEAPOT]} - {blue TEACUP} [{magenta.bold ${self.id}}]: Got disconnected by ${reason}`);
95
+ const routes = this.findClientInRoutes(teacup.id);
96
+ this.removeFromRoutes(routes, teacup.id);
97
+ console.log(chalk `{cyan.bold [TEAPOT]} - {blue TEACUP} [{magenta.bold ${teacup.id}}]: Got disconnected by ${reason}`);
112
98
  }
113
99
  catch (e) {
114
- console.log(chalk `{cyan.bold [TEAPOT]} - {red.bold TEACUP} {magenta.bold ${self.id}}: Failed wiht next message: ${e.message}`);
100
+ console.log(chalk `{cyan.bold [TEAPOT]} - {red.bold TEACUP} {magenta.bold ${teacup.id}}: Failed wiht next message: ${e.message}`);
115
101
  }
116
102
  }
117
- constructor(ctx, server, serverSecure, settings) {
118
- this.clients = new Map();
119
- this.registeredRoute = new Map();
120
- this.settings = settings;
121
- this.context = ctx;
122
- this.server = server;
123
- this.serverSecure = serverSecure;
124
- this.isActive = Metadata_1.default.get(constants_1.ASSIGN_TEAPOT_KEY, this.context, 'isTeapotActive');
103
+ async init() {
125
104
  this.teapotSettings = Metadata_1.default.get(constants_1.ASSIGN_TEAPOT_KEY, this.context);
126
- if (!this.isActive) {
127
- return;
128
- }
129
105
  const { publicKey, privateKey } = teapot_helper_1.default.generateKeys(this.teapotSettings.serverKey);
130
106
  this.publicKey = publicKey;
131
107
  this.privateKey = privateKey;
132
108
  this.serverSignature = teapot_helper_1.default.sign(this.teapotSettings.clientKey, privateKey, this.teapotSettings.serverKey);
133
- this.socketServer = require('socket.io')({
134
- path: '/teapot',
135
- cookie: false
136
- });
137
109
  }
138
110
  async start() {
139
- if (!this.isActive) {
140
- return;
141
- }
111
+ this.socketServer = Metadata_1.default.get(constants_2.SOCKET_IO_INSTANCE_KEY, this.context).of('/teapot');
142
112
  TeapotEngine_1.header(this.teapotSettings);
143
113
  this.socketServer.on('connection', this.registerTeacup.bind(this));
144
- this.socketServer.listen(this.server);
145
114
  }
146
115
  };
147
116
  TeapotEngine = TeapotEngine_1 = tslib_1.__decorate([
148
- (0, inversify_1.injectable)(),
149
- tslib_1.__param(0, (0, inversify_1.inject)('context')),
150
- tslib_1.__param(1, (0, inversify_1.inject)('server')),
151
- tslib_1.__param(2, (0, inversify_1.inject)('secureServer')),
152
- tslib_1.__param(2, (0, inversify_1.optional)()),
153
- tslib_1.__param(3, (0, inversify_1.inject)('settings')),
154
- tslib_1.__metadata("design:paramtypes", [Object, Object, Object, Object])
117
+ (0, inversify_1.injectable)()
155
118
  ], TeapotEngine);
156
119
  exports.default = TeapotEngine;
@@ -1,9 +1,6 @@
1
- export default class WebsocketEngine {
2
- private readonly settings;
3
- private readonly server;
4
- private readonly serverSecure?;
1
+ import ExpressiveTeaEngine from '../../classes/Engine';
2
+ export default class WebsocketEngine extends ExpressiveTeaEngine {
5
3
  canStart: boolean;
6
4
  isDetached: boolean;
7
- constructor(server: any, serverSecure: any, settings: any);
8
5
  init(): Promise<void>;
9
6
  }
@@ -4,17 +4,16 @@ const tslib_1 = require("tslib");
4
4
  const WebsocketService_1 = require("../../services/WebsocketService");
5
5
  const WebSocket = require("ws");
6
6
  const inversify_1 = require("inversify");
7
- let WebsocketEngine = class WebsocketEngine {
8
- constructor(server, serverSecure, settings) {
7
+ const Engine_1 = require("../../classes/Engine");
8
+ let WebsocketEngine = class WebsocketEngine extends Engine_1.default {
9
+ constructor() {
10
+ super(...arguments);
9
11
  this.canStart = false;
10
12
  this.isDetached = false;
11
- this.settings = settings;
12
- this.server = server;
13
- this.serverSecure = serverSecure;
14
- this.canStart = this.settings.get('startWebsocket');
15
- this.isDetached = this.settings.get('detachWebsocket');
16
13
  }
17
14
  async init() {
15
+ this.canStart = this.settings.get('startWebsocket');
16
+ this.isDetached = this.settings.get('detachWebsocket');
18
17
  if (this.canStart) {
19
18
  WebsocketService_1.default.init();
20
19
  WebsocketService_1.default.getInstance().setWebSocket(new WebSocket.Server(this.isDetached ? { noServer: true } : { server: this.server }));
@@ -27,11 +26,6 @@ let WebsocketEngine = class WebsocketEngine {
27
26
  }
28
27
  };
29
28
  WebsocketEngine = tslib_1.__decorate([
30
- (0, inversify_1.injectable)(),
31
- tslib_1.__param(0, (0, inversify_1.inject)('server')),
32
- tslib_1.__param(1, (0, inversify_1.inject)('secureServer')),
33
- tslib_1.__param(1, (0, inversify_1.optional)()),
34
- tslib_1.__param(2, (0, inversify_1.inject)('settings')),
35
- tslib_1.__metadata("design:paramtypes", [Object, Object, Object])
29
+ (0, inversify_1.injectable)()
36
30
  ], WebsocketEngine);
37
31
  exports.default = WebsocketEngine;
@@ -0,0 +1 @@
1
+ export declare function delay(ms: number): Promise<unknown>;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.delay = void 0;
4
+ async function delay(ms) {
5
+ return new Promise(resolve => setTimeout(resolve, ms));
6
+ }
7
+ exports.delay = delay;
@@ -2,8 +2,8 @@ import { NextFunction, Request, Response } from 'express';
2
2
  import { ExpressiveTeaAnnotations, ExpressiveTeaArgumentOptions } from '@expressive-tea/commons/interfaces';
3
3
  export declare function autoResponse(request: Request, response: Response, annotations: ExpressiveTeaAnnotations[], responseResult?: any): void;
4
4
  export declare function executeRequest(request: Request, response: Response, next: NextFunction): Promise<void>;
5
- export declare function mapArguments(decoratedArguments: ExpressiveTeaArgumentOptions[], request: Request, response: Response, next: NextFunction, introspectedArgs?: string[]): unknown[];
6
- export declare function extractParameters(target: unknown, args?: string | string[], propertyName?: string | symbol): any;
5
+ export declare function mapArguments(decoratedArguments: ExpressiveTeaArgumentOptions[], request: Request, response: Response, next: NextFunction, introspectedArgs?: string[]): any[];
6
+ export declare function extractParameters(target: unknown, args?: string | string[], propertyName?: string): any;
7
7
  export declare function generateRoute(route: string, verb: string, ...settings: any): (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => void;
8
8
  export declare function router(verb: string, route: string, target: any, handler: (...args: any[]) => void | any | Promise<any>, propertyKey: string | symbol, settings?: any): void;
9
9
  export declare function fileSettings(): any;
package/helpers/server.js CHANGED
@@ -22,7 +22,7 @@ async function executeRequest(request, response, next) {
22
22
  next(error);
23
23
  isNextUsed = true;
24
24
  };
25
- const result = await this.options.handler.apply(this.self, mapArguments(this.decoratedArguments, request, response, nextWrapper(), (0, object_helper_1.getOwnArgumentNames)(this.options.handler)));
25
+ const result = await this.options.handler.apply(this.self, mapArguments(this.decoratedArguments, request, response, nextWrapper(), this.options.introspectedArgs));
26
26
  if (!response.headersSent && !isNextUsed) {
27
27
  autoResponse(request, response, this.annotations, result);
28
28
  }
@@ -39,7 +39,6 @@ function mapArguments(decoratedArguments, request, response, next, introspectedA
39
39
  return (0, lodash_1.chain)(decoratedArguments)
40
40
  .sortBy('index')
41
41
  .map((argument) => {
42
- const argumentKey = (0, lodash_1.get)(introspectedArgs, argument.index);
43
42
  switch (argument.type) {
44
43
  case constants_1.ARGUMENT_TYPES.REQUEST:
45
44
  return request;
@@ -48,11 +47,11 @@ function mapArguments(decoratedArguments, request, response, next, introspectedA
48
47
  case constants_1.ARGUMENT_TYPES.NEXT:
49
48
  return next;
50
49
  case constants_1.ARGUMENT_TYPES.QUERY:
51
- return extractParameters(request.query, argument.arguments, argumentKey);
50
+ return extractParameters(request.query, argument.arguments, (0, lodash_1.get)(introspectedArgs, argument.index));
52
51
  case constants_1.ARGUMENT_TYPES.BODY:
53
- return extractParameters(request.body, argument.arguments, argumentKey);
52
+ return extractParameters(request.body, argument.arguments, (0, lodash_1.get)(introspectedArgs, argument.index));
54
53
  case constants_1.ARGUMENT_TYPES.GET_PARAM:
55
- return extractParameters(request.params, argument.arguments, argumentKey);
54
+ return extractParameters(request.params, argument.arguments, (0, lodash_1.get)(introspectedArgs, argument.index));
56
55
  default:
57
56
  return;
58
57
  }
@@ -82,8 +81,9 @@ function generateRoute(route, verb, ...settings) {
82
81
  }
83
82
  exports.generateRoute = generateRoute;
84
83
  function router(verb, route, target, handler, propertyKey, settings) {
84
+ const introspectedArgs = (0, object_helper_1.getOwnArgumentNames)(handler);
85
85
  const existedRoutesHandlers = Metadata_1.default.get(constants_1.ROUTER_HANDLERS_KEY, target) || [];
86
- existedRoutesHandlers.unshift({ verb, route, handler, target, propertyKey, settings });
86
+ existedRoutesHandlers.unshift({ verb, route, handler, target, propertyKey, settings, introspectedArgs });
87
87
  Metadata_1.default.set(constants_1.ROUTER_HANDLERS_KEY, existedRoutesHandlers, target);
88
88
  }
89
89
  exports.router = router;
@@ -1,6 +1,8 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
3
  import { KeyPairSyncResult } from 'crypto';
4
+ import { NextFunction, Request, Response } from 'express';
5
+ import ProxyRoute from '../classes/ProxyRoute';
4
6
  export interface EncryptedMessage {
5
7
  iv: string;
6
8
  message: string;
@@ -14,4 +16,6 @@ export default class TeaGatewayHelper {
14
16
  static sign(data: string, privateKey: string, passphrase: string): Buffer;
15
17
  static verify(data: string, publicKey: string, signature: Buffer): boolean;
16
18
  static generateKeys(passphrase: string): KeyPairSyncResult<any, any>;
19
+ static proxyResponse(proxyRoute: ProxyRoute, req: Request, res: Response, next: NextFunction): void;
20
+ static httpSchema(schema: string): "http:" | "https:";
17
21
  }
@@ -17,19 +17,19 @@ class TeaGatewayHelper {
17
17
  return JSON.parse(decrypted.toString());
18
18
  }
19
19
  static sign(data, privateKey, passphrase) {
20
- return crypto.sign('sha256', Buffer.from(data), {
20
+ return crypto.sign(null, Buffer.from(data), {
21
21
  key: privateKey,
22
22
  passphrase
23
23
  });
24
24
  }
25
25
  static verify(data, publicKey, signature) {
26
- return crypto.verify('sha256', Buffer.from(data), {
26
+ return crypto.verify(null, Buffer.from(data), {
27
27
  key: publicKey
28
28
  }, signature);
29
29
  }
30
30
  static generateKeys(passphrase) {
31
31
  const { generateKeyPairSync } = require('crypto');
32
- return generateKeyPairSync('rsa', {
32
+ return generateKeyPairSync('ed25519', {
33
33
  modulusLength: 2048,
34
34
  publicKeyEncoding: {
35
35
  type: 'spki',
@@ -43,5 +43,18 @@ class TeaGatewayHelper {
43
43
  }
44
44
  });
45
45
  }
46
+ static proxyResponse(proxyRoute, req, res, next) {
47
+ const router = proxyRoute.registerRoute();
48
+ if (!proxyRoute.hasClients())
49
+ return next();
50
+ return router(req, res, next);
51
+ }
52
+ static httpSchema(schema) {
53
+ if (schema.includes('teapot'))
54
+ return 'http:';
55
+ if (schema.includes('teapots'))
56
+ return 'https:';
57
+ throw new Error(`Invalid Schema: ${schema}`);
58
+ }
46
59
  }
47
60
  exports.default = TeaGatewayHelper;
@@ -0,0 +1,4 @@
1
+ import { ExpressiveTeaHandlerOptions } from '@expressive-tea/commons/interfaces';
2
+ export interface ExpressiveTeaHandlerOptionsWithInstrospectedArgs extends ExpressiveTeaHandlerOptions {
3
+ introspectedArgs: string[];
4
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,21 +1,21 @@
1
1
  {
2
2
  "name": "@zerooneit/expressive-tea",
3
- "version": "1.3.0-beta.4",
3
+ "version": "1.3.0-beta.5",
4
4
  "description": "A REST API over Express and Typescript",
5
5
  "main": "classes/Boot.js",
6
6
  "engines": {
7
- "node": ">=12.0.0"
7
+ "node": ">=16.0.0"
8
8
  },
9
9
  "scripts": {
10
- "test": "npm run linter && jest --clearCache && jest --coverage --ci --detectOpenHandles --forceExit --silent --runInBand",
11
- "test:dev": "npm run linter && jest --clearCache && jest --detectOpenHandles --forceExit",
10
+ "test": "yarn run linter && jest --clearCache && jest --coverage --ci --detectOpenHandles --forceExit --silent",
11
+ "test:dev": "yarn run linter && jest --clearCache && jest --detectOpenHandles --forceExit",
12
12
  "linter": "tslint -c tslint.json -p tsconfig.json",
13
13
  "build:dev": "tsc --project tsconfig.json --watch",
14
14
  "build": "tsc --project tsconfig.json",
15
15
  "clean:build": "trash '**/*.js' '**/*.d.ts' '**/*.js.map' '**/*.d.ts.map' '!node_modules/**/*' '!docs/**/*' '!coverage/**/*' '!gulpfile.js' '!tasks/*.js' '!jest.config.js' '!tools/**/*'",
16
- "publish:prepare": "npm run clean:build && npm run build",
17
- "postpublish": "npm run clean:build",
18
- "prepublishOnly": "npm test && npm run publish:prepare"
16
+ "publish:prepare": "yarn run clean:build && yarn run build",
17
+ "postpublish": "yarn run clean:build",
18
+ "prepublishOnly": "yarn test && yarn run publish:prepare"
19
19
  },
20
20
  "publishConfig": {
21
21
  "access": "public"
@@ -26,44 +26,41 @@
26
26
  "license": "Apache-2.0",
27
27
  "devDependencies": {
28
28
  "@expressive-tea/commons": "^1.0.1",
29
- "@expressive-tea/plugin": "1.0.2",
30
- "@types/bluebird": "3.5.38",
31
- "@types/express": "4.17.15",
29
+ "@expressive-tea/plugin": "1.0.3",
30
+ "@types/express": "4.17.17",
32
31
  "@types/express-http-proxy": "1.6.3",
33
- "@types/express-serve-static-core": "4.17.32",
34
- "@types/jest": "29.2.5",
35
- "@types/lodash": "4.14.191",
36
- "@types/node": "18.11.18",
32
+ "@types/express-serve-static-core": "4.17.34",
33
+ "@types/jest": "29.5.1",
34
+ "@types/lodash": "4.14.194",
35
+ "@types/node": "20.1.0",
37
36
  "@types/reflect-metadata": "0.1.0",
38
37
  "@types/socket.io": "3.0.2",
39
38
  "@types/socket.io-client": "3.0.0",
40
39
  "@types/ws": "8.5.4",
41
40
  "http-terminator": "3.2.0",
42
- "jest": "29.3.1",
41
+ "jest": "29.5.0",
43
42
  "jest-express": "1.12.0",
44
- "jest-junit": "15.0.0",
43
+ "jest-junit": "16.0.0",
45
44
  "reflect-metadata": "0.1.13",
46
- "rimraf": "4.0.5",
45
+ "rimraf": "5.0.0",
47
46
  "supertest": "6.3.3",
48
47
  "toast-jsdoc": "1.0.2",
49
48
  "trash-cli": "5.0.0",
50
- "ts-jest": "29.0.5",
49
+ "ts-jest": "29.1.0",
51
50
  "ts-node": "10.9.1",
52
51
  "tslint": "6.1.3",
53
- "typescript": "4.9.4"
52
+ "typescript": "5.0.4"
54
53
  },
55
54
  "dependencies": {
56
- "bluebird": "3.7.2",
57
- "eiows": "^4.1.2",
58
55
  "express": "4.18.2",
59
56
  "express-http-proxy": "1.6.3",
60
57
  "inversify": "6.0.1",
61
58
  "inversify-inject-decorators": "3.1.0",
62
59
  "lodash": "4.17.21",
63
- "socket.io": "4.5.4",
64
- "socket.io-client": "4.5.4",
60
+ "socket.io": "4.6.1",
61
+ "socket.io-client": "4.6.1",
65
62
  "url-scheme": "1.0.5",
66
- "ws": "8.12.0"
63
+ "ws": "8.13.0"
67
64
  },
68
65
  "repository": {
69
66
  "type": "git",
@@ -111,6 +108,8 @@
111
108
  },
112
109
  "resolutions": {
113
110
  "set-value": "4.1.0",
114
- "glob-parent": "6.0.2"
115
- }
111
+ "glob-parent": "6.0.2",
112
+ "engine.io": "6.4.2"
113
+ },
114
+ "packageManager": "yarn@3.5.1"
116
115
  }
@@ -1,58 +0,0 @@
1
- # Use the latest 2.1 version of CircleCI pipeline process engine.
2
- # See: https://circleci.com/docs/2.0/configuration-reference
3
- version: 2.1
4
-
5
- orbs:
6
- # The Node.js orb contains a set of prepackaged CircleCI configuration you can utilize
7
- # Orbs reduce the amount of configuration required for common tasks.
8
- # See the orb documentation here: https://circleci.com/developer/orbs/orb/circleci/node
9
- node: circleci/node@4.7
10
-
11
- jobs:
12
- # Below is the definition of your job to build and test your app, you can rename and customize it as you want.
13
- build-and-test:
14
- # These next lines define a Docker executor: https://circleci.com/docs/2.0/executor-types/
15
- # You can specify an image from Dockerhub or use one of our Convenience Images from CircleCI's Developer Hub.
16
- # A list of available CircleCI Docker Convenience Images are available here: https://circleci.com/developer/images/image/cimg/node
17
- docker:
18
- - image: cimg/node:16.10
19
- # Then run your tests!
20
- # CircleCI will report the results back to your VCS provider.
21
- steps:
22
- # Checkout the code as the first step.
23
- - checkout
24
- # Next, the node orb's install-packages step will install the dependencies from a package.json.
25
- # The orb install-packages step will also automatically cache them for faster future runs.
26
- - restore_cache:
27
- keys:
28
- - expressive-tea-{{ checksum "package.json" }}
29
- - expressive-tea-
30
-
31
- - node/install-packages:
32
- # If you are using yarn, change the line below from "npm" to "yarn"
33
- pkg-manager: yarn
34
- - save_cache:
35
- paths:
36
- - node_modules
37
- key: expressive-tea-{{ checksum "package.json" }}
38
- - run:
39
- name: Expressive Tea Tests
40
- command: npm test
41
- environment:
42
- JEST_JUNIT_OUTPUT_DIR: "./coverage"
43
- JUNIT_REPORT_NAME: "junit.xml"
44
- - store_test_results:
45
- path: ./coverage
46
- - store_artifacts:
47
- path: ./coverage
48
-
49
- workflows:
50
- # Below is the definition of your workflow.
51
- # Inside the workflow, you provide the jobs you want to run, e.g this workflow runs the build-and-test job above.
52
- # CircleCI will run this workflow on every commit.
53
- # For more details on extending your workflow, see the configuration docs: https://circleci.com/docs/2.0/configuration-reference/#workflows
54
- Testing:
55
- jobs:
56
- - build-and-test
57
- # For running simple node tests, you could optionally use the node/test job from the orb to replicate and replace the job above in fewer lines.
58
- # - node/test