Compare commits

..

104 Commits

Author SHA1 Message Date
09dec2071e 1.1.65 2020-09-29 19:42:38 +00:00
a1443deafe fix(core): update 2020-09-29 19:42:38 +00:00
9eac5ad336 1.1.64 2020-09-29 19:37:49 +00:00
cf607a79d5 fix(core): update 2020-09-29 19:37:49 +00:00
8426c976bf 1.1.63 2020-09-29 18:58:10 +00:00
1086065000 fix(core): update 2020-09-29 18:58:09 +00:00
72196ec383 1.1.62 2020-09-29 17:21:08 +00:00
c6ad490a6f fix(core): update 2020-09-29 17:21:08 +00:00
a40a83f0bf 1.1.61 2020-09-29 08:35:27 +00:00
82fa029d05 fix(core): update 2020-09-29 08:35:26 +00:00
0d76e7f577 1.1.60 2020-09-24 18:04:12 +00:00
57e6f058be fix(core): update 2020-09-24 18:04:11 +00:00
b0bf9d7c95 1.1.59 2020-09-24 18:03:02 +00:00
1fbc76ef30 fix(core): update 2020-09-24 18:03:01 +00:00
424d9cca91 1.1.58 2019-11-08 18:48:39 +01:00
d712270946 fix(core): update 2019-11-08 18:48:39 +01:00
f98c797ad8 1.1.57 2019-11-08 18:41:09 +01:00
a23e7349be fix(core): update 2019-11-08 18:41:08 +01:00
c390881a4e 1.1.56 2019-11-08 17:31:04 +01:00
5e64f4ca25 fix(core): update 2019-11-08 17:31:04 +01:00
765bc73197 1.1.55 2019-11-08 17:11:41 +01:00
105acaf97b fix(core): update 2019-11-08 17:11:41 +01:00
5139136af4 1.1.54 2019-11-07 00:26:47 +01:00
bcc4ce9a87 fix(core): update 2019-11-07 00:26:47 +01:00
20e7584eb9 1.1.53 2019-11-03 20:23:15 +01:00
59cbc343cc fix(core): update 2019-11-03 20:23:15 +01:00
75aa1f6f0d 1.1.52 2019-11-03 19:17:26 +01:00
3f073ab9b3 fix(core): update 2019-11-03 19:17:26 +01:00
08c1618ea8 1.1.51 2019-11-03 18:33:46 +01:00
eb181fa2f6 fix(core): update 2019-11-03 18:33:46 +01:00
c901ab75d3 1.1.50 2019-11-03 16:48:35 +01:00
075c59ed2c fix(core): update 2019-11-03 16:48:35 +01:00
8d358dd93d 1.1.49 2019-09-10 00:21:48 +02:00
e576d6058a fix(core): update 2019-09-10 00:21:47 +02:00
6546da2394 1.1.48 2019-09-09 23:58:32 +02:00
29597daba1 fix(core): update 2019-09-09 23:58:32 +02:00
c8b647d2fd 1.1.47 2019-09-09 16:20:43 +02:00
1fa4aca049 fix(core): update 2019-09-09 16:20:43 +02:00
2d4695de22 1.1.46 2019-09-01 18:07:53 +02:00
a3f4dcbc2a fix(core): update 2019-09-01 18:07:52 +02:00
d6e81288b4 1.1.45 2019-08-13 15:58:08 +02:00
c441d89596 fix(core): update 2019-08-13 15:58:08 +02:00
85b69e487a 1.1.44 2019-08-13 11:36:32 +02:00
0d94ed9345 fix(core): update 2019-08-13 11:36:31 +02:00
e188b18016 1.1.43 2019-08-13 09:37:23 +02:00
33c0fa3746 fix(core): update 2019-08-13 09:37:23 +02:00
52be1415ee 1.1.42 2019-08-12 22:46:57 +02:00
e75d5eabdb fix(core): update 2019-08-12 22:46:57 +02:00
fb99848df1 1.1.41 2019-08-12 22:45:58 +02:00
1bd39d0755 fix(core): update 2019-08-12 22:45:58 +02:00
d24c5f628c 1.1.40 2019-08-12 22:31:41 +02:00
33fbabdd72 fix(core): update 2019-08-12 22:31:40 +02:00
9d26fff986 1.1.39 2019-08-12 18:16:26 +02:00
41151e5436 fix(core): update 2019-08-12 18:16:25 +02:00
109c5197f3 1.1.38 2019-06-07 08:40:24 +02:00
c3d47c1f50 fix(core): update 2019-06-07 08:40:24 +02:00
1b45fb45e9 1.1.37 2019-06-06 23:11:03 +02:00
c22adc9b57 fix(core): update 2019-06-06 23:11:03 +02:00
35e87306dd 1.1.36 2019-05-02 11:46:36 +02:00
1b20aa5992 fix(core): update 2019-05-02 11:46:36 +02:00
a63f14da47 1.1.35 2019-04-26 17:35:15 +02:00
86cf94c5dc fix(core): update 2019-04-26 17:35:15 +02:00
0d39d6f237 1.1.34 2019-04-24 18:30:57 +02:00
1856ad5cfc fix(core): update 2019-04-24 18:30:56 +02:00
b5dab810e8 1.1.33 2019-04-24 17:57:17 +02:00
f145b85b1c fix(core): update 2019-04-24 17:57:16 +02:00
a8c647c5c7 1.1.32 2019-04-24 17:17:36 +02:00
22472e0adf fix(core): update 2019-04-24 17:17:36 +02:00
333ddb4d9c 1.1.31 2019-04-24 17:10:52 +02:00
126f020bf8 fix(core): update 2019-04-24 17:10:51 +02:00
7677b1bb48 1.1.30 2019-04-24 16:09:01 +02:00
114379c5b3 fix(core): update 2019-04-24 16:09:01 +02:00
79ae7d2039 1.1.29 2019-04-24 15:47:29 +02:00
d2cb6a3045 fix(core): update 2019-04-24 15:47:28 +02:00
963619b2ed 1.1.28 2019-04-23 17:28:46 +02:00
976abaaed7 fix(core): update 2019-04-23 17:28:46 +02:00
ef322c32ac 1.1.27 2019-01-31 02:32:52 +01:00
475911a968 fix(build): now building with tsbuild 2019-01-31 02:32:52 +01:00
5530e29da4 1.1.26 2019-01-31 00:54:40 +01:00
5f1d2c83c6 fix(core): update 2019-01-31 00:54:39 +01:00
b84dd36885 1.1.25 2019-01-31 00:46:42 +01:00
c2d64ba39a fix(readme): update 2019-01-31 00:46:42 +01:00
85a5d7cdaf 1.1.24 2019-01-30 10:55:52 +01:00
69380a2dbc fix(npmextra): adjust access level 2019-01-30 10:55:51 +01:00
fc292d83b9 1.1.23 2019-01-30 10:55:17 +01:00
b29961df95 fix(scope): switch to @pushrocks 2019-01-30 10:55:16 +01:00
f774a82ad5 1.1.22 2019-01-30 03:21:15 +01:00
5a45f4750b fix(package.json): private setting 2019-01-30 03:21:14 +01:00
fc6227ef96 1.1.21 2019-01-30 03:15:22 +01:00
873aba3e0b fix(snyk): add .snyk file 2019-01-30 03:15:21 +01:00
f9bed9da8a 1.1.20 2019-01-30 03:14:03 +01:00
d296064bfa fix(structure): update to latest standards 2019-01-30 03:14:02 +01:00
1b0922759a 1.1.19 2018-03-19 10:00:14 +01:00
aef4f9c591 now working as expected 2018-03-19 10:00:11 +01:00
abf546eec3 1.1.18 2018-03-18 17:50:39 +01:00
483cb38175 start transitioning to better SocketFunction handling 2018-03-18 17:50:37 +01:00
b2bd66a6a6 1.1.17 2018-03-18 16:40:42 +01:00
cfc3e8788d add @types/node 2018-03-18 16:40:40 +01:00
23c14c032c 1.1.16 2018-03-17 17:52:36 +01:00
c92dae809f format README 2018-03-17 17:52:31 +01:00
7200464e4b 1.1.15 2018-03-17 17:52:07 +01:00
eaa97f0598 update readme 2018-03-17 17:52:01 +01:00
cde8270313 1.1.14 2018-03-17 17:18:59 +01:00
1b073ac8f6 update readme 2018-03-17 17:18:53 +01:00
48 changed files with 12348 additions and 2056 deletions

18
.gitignore vendored
View File

@ -1,4 +1,20 @@
node_modules/
.nogit/
# artifacts
coverage/
public/
pages/
# installs
node_modules/
# caches
.yarn/
.cache/
.rpt2_cache
# builds
dist/
dist_*/
# custom

View File

@ -1,58 +1,62 @@
# gitzone standard
image: hosttoday/ht-docker-node:npmci
# gitzone ci_default
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
cache:
paths:
- .yarn/
key: "$CI_BUILD_STAGE"
- .npmci_cache/
key: '$CI_BUILD_STAGE'
stages:
- security
- test
- release
- trigger
- pages
- metadata
# ====================
# security stage
# ====================
mirror:
stage: security
script:
- npmci git mirror
only:
- tags
tags:
- lossless
- docker
- notpriv
snyk:
auditProductionDependencies:
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
stage: security
script:
- npmci command yarn global add snyk
- npmci command yarn install --ignore-scripts
- npmci command snyk test
- npmci npm prepare
- npmci command npm install --production --ignore-scripts
- npmci command npm config set registry https://registry.npmjs.org
- npmci command npm audit --audit-level=high --only=prod --production
tags:
- docker
testLEGACY:
stage: test
auditDevDependencies:
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
stage: security
script:
- npmci node install legacy
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
- npmci npm prepare
- npmci command npm install --ignore-scripts
- npmci command npm config set registry https://registry.npmjs.org
- npmci command npm audit --audit-level=high --only=dev
tags:
- docker
allow_failure: true
testLTS:
stage: test
script:
- npmci node install lts
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
# ====================
# test stage
# ====================
testSTABLE:
testStable:
stage: test
script:
- npmci npm prepare
- npmci node install stable
- npmci npm install
- npmci npm test
@ -60,36 +64,74 @@ testSTABLE:
tags:
- docker
testBuild:
stage: test
script:
- npmci npm prepare
- npmci node install stable
- npmci npm install
- npmci command npm run build
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
release:
stage: release
script:
- npmci npm prepare
- npmci node install stable
- npmci npm publish
only:
- tags
tags:
- lossless
- docker
- notpriv
# ====================
# metadata stage
# ====================
codequality:
stage: metadata
allow_failure: true
only:
- tags
script:
- npmci command npm install -g tslint typescript
- npmci npm prepare
- npmci npm install
- npmci command "tslint -c tslint.json ./ts/**/*.ts"
tags:
- lossless
- docker
- priv
trigger:
stage: trigger
stage: metadata
script:
- npmci trigger
only:
- tags
tags:
- lossless
- docker
- notpriv
pages:
image: hosttoday/ht-docker-node:npmci
stage: pages
stage: metadata
script:
- npmci command yarn global add npmpage
- npmci command npmpage
- npmci node install lts
- npmci command npm install -g @gitzone/tsdoc
- npmci npm prepare
- npmci npm install
- npmci command tsdoc
tags:
- lossless
- docker
- notpriv
only:
- tags
artifacts:
expire_in: 1 week
paths:
- public
allow_failure: true

13
.snyk Normal file
View File

@ -0,0 +1,13 @@
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
version: v1.13.5
# ignores vulnerabilities until expiry date; change duration by modifying expiry date
ignore:
SNYK-JS-JSYAML-173999:
- '@pushrocks/smartexpress > @pushrocks/smartfile > js-yaml':
reason: None given
expires: '2019-05-24T15:16:11.291Z'
SNYK-JS-JSYAML-174129:
- '@pushrocks/smartexpress > @pushrocks/smartfile > js-yaml':
reason: None given
expires: '2019-05-24T15:16:11.291Z'
patch: {}

29
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,29 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "current file",
"type": "node",
"request": "launch",
"args": [
"${relativeFile}"
],
"runtimeArgs": ["-r", "@gitzone/tsrun"],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"internalConsoleOptions": "openOnSessionStart"
},
{
"name": "test.ts",
"type": "node",
"request": "launch",
"args": [
"test/test.ts"
],
"runtimeArgs": ["-r", "@gitzone/tsrun"],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"internalConsoleOptions": "openOnSessionStart"
}
]
}

26
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,26 @@
{
"json.schemas": [
{
"fileMatch": ["/npmextra.json"],
"schema": {
"type": "object",
"properties": {
"npmci": {
"type": "object",
"description": "settings for npmci"
},
"gitzone": {
"type": "object",
"description": "settings for gitzone",
"properties": {
"projectType": {
"type": "string",
"enum": ["website", "element", "service", "npm", "wcc"]
}
}
}
}
}
}
]
}

View File

@ -1,33 +0,0 @@
# smartsocket
easy and secure websocket communication, TypeScript ready
## Availabililty
[![npm](https://pushrocks.gitlab.io/assets/repo-button-npm.svg)](https://www.npmjs.com/package/smartsocket)
[![git](https://pushrocks.gitlab.io/assets/repo-button-git.svg)](https://GitLab.com/pushrocks/smartsocket)
[![git](https://pushrocks.gitlab.io/assets/repo-button-mirror.svg)](https://github.com/pushrocks/smartsocket)
[![docs](https://pushrocks.gitlab.io/assets/repo-button-docs.svg)](https://pushrocks.gitlab.io/smartsocket/)
## Status for master
[![build status](https://GitLab.com/pushrocks/smartsocket/badges/master/build.svg)](https://GitLab.com/pushrocks/smartsocket/commits/master)
[![coverage report](https://GitLab.com/pushrocks/smartsocket/badges/master/coverage.svg)](https://GitLab.com/pushrocks/smartsocket/commits/master)
[![npm downloads per month](https://img.shields.io/npm/dm/smartsocket.svg)](https://www.npmjs.com/package/smartsocket)
[![Dependency Status](https://david-dm.org/pushrocks/smartsocket.svg)](https://david-dm.org/pushrocks/smartsocket)
[![bitHound Dependencies](https://www.bithound.io/github/pushrocks/smartsocket/badges/dependencies.svg)](https://www.bithound.io/github/pushrocks/smartsocket/master/dependencies/npm)
[![bitHound Code](https://www.bithound.io/github/pushrocks/smartsocket/badges/code.svg)](https://www.bithound.io/github/pushrocks/smartsocket)
[![TypeScript](https://img.shields.io/badge/TypeScript-2.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![node](https://img.shields.io/badge/node->=%206.x.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)
## Usage
Use TypeScript for best in class instellisense.
For further information read the linked docs at the top of this README.
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
> | By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy.html)
[![repo-footer](https://pushrocks.gitlab.io/assets/repo-footer.svg)](https://push.rocks)

5
dist/index.d.ts vendored
View File

@ -1,5 +0,0 @@
export * from './smartsocket.classes.smartsocket';
export * from './smartsocket.classes.smartsocketclient';
export * from './smartsocket.classes.socketfunction';
export * from './smartsocket.classes.socketrole';
export * from './smartsocket.classes.socketconnection';

13
dist/index.js vendored
View File

@ -1,13 +0,0 @@
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
// export main classes
__export(require("./smartsocket.classes.smartsocket"));
__export(require("./smartsocket.classes.smartsocketclient"));
// export further classes and objects
__export(require("./smartsocket.classes.socketfunction"));
__export(require("./smartsocket.classes.socketrole"));
__export(require("./smartsocket.classes.socketconnection"));
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUVBLHNCQUFzQjtBQUN0Qix1REFBa0Q7QUFDbEQsNkRBQXdEO0FBRXhELHFDQUFxQztBQUNyQywwREFBcUQ7QUFDckQsc0RBQWlEO0FBQ2pELDREQUF1RCJ9

View File

@ -1,42 +0,0 @@
/// <reference types="node" />
/// <reference types="socket.io" />
import * as plugins from './smartsocket.plugins';
import * as http from 'http';
import { SocketConnection } from './smartsocket.classes.socketconnection';
import { SocketRole } from './smartsocket.classes.socketrole';
import * as SocketIO from 'socket.io';
export interface ISmartsocketConstructorOptions {
port: number;
}
export declare class Smartsocket {
options: ISmartsocketConstructorOptions;
httpServer: http.Server;
io: SocketIO.Server;
openSockets: plugins.lik.Objectmap<SocketConnection>;
socketRoles: plugins.lik.Objectmap<SocketRole>;
constructor(optionsArg: ISmartsocketConstructorOptions);
/**
* starts listening to incoming sockets:
*/
startServer(): Promise<{}>;
/**
* starts the server with another server
*/
setServer(httpServerArg: http.Server): Promise<void>;
/**
* closes the server
*/
closeServer(): Promise<void>;
/**
* allows call to specific client.
*/
clientCall(functionNameArg: string, dataArg: any, targetSocketConnectionArg: SocketConnection): Promise<{}>;
/**
* adds socketRoles
*/
addSocketRoles(socketRolesArray: SocketRole[]): void;
/**
* the standard handler for new socket connections
*/
private _handleSocketConnection(socketArg);
}

View File

@ -1,118 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const plugins = require("./smartsocket.plugins");
const http = require("http");
// classes
const lik_1 = require("lik");
const smartsocket_classes_socketconnection_1 = require("./smartsocket.classes.socketconnection");
const smartsocket_classes_socketrequest_1 = require("./smartsocket.classes.socketrequest");
class Smartsocket {
constructor(optionsArg) {
this.openSockets = new lik_1.Objectmap();
this.socketRoles = new lik_1.Objectmap();
this.options = optionsArg;
}
/**
* starts listening to incoming sockets:
*/
startServer() {
return __awaiter(this, void 0, void 0, function* () {
let done = plugins.smartq.defer();
if (!this.httpServer) {
this.httpServer = new http.Server();
}
this.io = plugins.socketIo(this.httpServer);
this.io.on('connection', socketArg => {
this._handleSocketConnection(socketArg);
});
this.httpServer.listen(this.options.port, () => {
done.resolve();
});
return yield done.promise;
});
}
/**
* starts the server with another server
*/
setServer(httpServerArg) {
return __awaiter(this, void 0, void 0, function* () {
this.httpServer = httpServerArg;
});
}
/**
* closes the server
*/
closeServer() {
return __awaiter(this, void 0, void 0, function* () {
yield plugins.smartdelay.delayFor(1000);
this.openSockets.forEach((socketObjectArg) => {
plugins.beautylog.log(`disconnect socket with >>alias ${socketObjectArg.alias}`);
socketObjectArg.socket.disconnect();
});
this.openSockets.wipe();
this.io.close();
});
}
// communication
/**
* allows call to specific client.
*/
clientCall(functionNameArg, dataArg, targetSocketConnectionArg) {
let done = plugins.smartq.defer();
let socketRequest = new smartsocket_classes_socketrequest_1.SocketRequest({
side: 'requesting',
originSocketConnection: targetSocketConnectionArg,
shortId: plugins.shortid.generate(),
funcCallData: {
funcName: functionNameArg,
funcDataArg: dataArg
}
});
socketRequest.dispatch().then((dataArg) => {
done.resolve(dataArg.funcDataArg);
});
return done.promise;
}
/**
* adds socketRoles
*/
addSocketRoles(socketRolesArray) {
for (let socketRole of socketRolesArray) {
this.socketRoles.add(socketRole);
}
return;
}
/**
* the standard handler for new socket connections
*/
_handleSocketConnection(socketArg) {
let socketConnection = new smartsocket_classes_socketconnection_1.SocketConnection({
alias: undefined,
authenticated: false,
role: undefined,
side: 'server',
smartsocketHost: this,
socket: socketArg
});
plugins.beautylog.log('Socket connected. Trying to authenticate...');
this.openSockets.add(socketConnection);
socketConnection
.authenticate()
.then(() => {
return socketConnection.listenToFunctionRequests();
})
.catch(err => {
console.log(err);
});
}
}
exports.Smartsocket = Smartsocket;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzb2NrZXQuY2xhc3Nlcy5zbWFydHNvY2tldC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0c29ja2V0LmNsYXNzZXMuc21hcnRzb2NrZXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUFBLGlEQUFpRDtBQUdqRCw2QkFBNkI7QUFFN0IsVUFBVTtBQUNWLDZCQUFnQztBQUVoQyxpR0FBMEU7QUFDMUUsMkZBQW9FO0FBVXBFO0lBTUUsWUFBWSxVQUEwQztRQUZ0RCxnQkFBVyxHQUFHLElBQUksZUFBUyxFQUFvQixDQUFDO1FBQ2hELGdCQUFXLEdBQUcsSUFBSSxlQUFTLEVBQWMsQ0FBQztRQUV4QyxJQUFJLENBQUMsT0FBTyxHQUFHLFVBQVUsQ0FBQztJQUM1QixDQUFDO0lBRUQ7O09BRUc7SUFDRyxXQUFXOztZQUNmLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDbEMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztnQkFDckIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUN0QyxDQUFDO1lBQ0QsSUFBSSxDQUFDLEVBQUUsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUM1QyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsU0FBUyxDQUFDLEVBQUU7Z0JBQ25DLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUMxQyxDQUFDLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRTtnQkFDN0MsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2pCLENBQUMsQ0FBQyxD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

View File

@ -1,26 +0,0 @@
import { SocketConnection } from './smartsocket.classes.socketconnection';
/**
* interface for class SmartsocketClient
*/
export interface ISmartsocketClientOptions {
port: number;
url: string;
alias: string;
role: string;
password: string;
}
export declare class SmartsocketClient {
alias: string;
role: string;
socketConnection: SocketConnection;
serverUrl: string;
serverPort: number;
serverPassword: string;
constructor(optionsArg: ISmartsocketClientOptions);
/**
* connect the client to the server
*/
connect(): Promise<{}>;
disconnect(): Promise<{}>;
serverCall(functionNameArg: string, dataArg: any): Promise<{}>;
}

View File

@ -1,72 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const plugins = require("./smartsocket.plugins");
// import classes
const smartsocket_classes_socketconnection_1 = require("./smartsocket.classes.socketconnection");
const smartsocket_classes_socketrequest_1 = require("./smartsocket.classes.socketrequest");
class SmartsocketClient {
constructor(optionsArg) {
this.alias = optionsArg.alias;
this.role = optionsArg.role;
this.serverUrl = optionsArg.url;
this.serverPort = optionsArg.port;
this.serverPassword = optionsArg.password;
}
/**
* connect the client to the server
*/
connect() {
let done = plugins.smartq.defer();
plugins.beautylog.log('trying to connect...');
let socketUrl = `${this.serverUrl}:${this.serverPort}`;
this.socketConnection = new smartsocket_classes_socketconnection_1.SocketConnection({
alias: this.alias,
authenticated: false,
role: undefined,
side: 'client',
smartsocketHost: null,
socket: plugins.socketIoClient(socketUrl, { multiplex: false })
});
this.socketConnection.socket.on('requestAuth', () => {
console.log('server requested authentication');
this.socketConnection.socket.emit('dataAuth', {
role: this.role,
password: this.serverPassword,
alias: this.alias
});
this.socketConnection.socket.on('authenticated', () => {
console.log('client is authenticated');
this.socketConnection.authenticated = true;
this.socketConnection.listenToFunctionRequests();
done.resolve();
});
});
return done.promise;
}
disconnect() {
let done = plugins.smartq.defer();
this.socketConnection.socket.disconnect();
this.socketConnection = undefined;
plugins.beautylog.ok('disconnected!');
done.resolve();
return done.promise;
}
serverCall(functionNameArg, dataArg) {
let done = plugins.smartq.defer();
let socketRequest = new smartsocket_classes_socketrequest_1.SocketRequest({
side: 'requesting',
originSocketConnection: this.socketConnection,
shortId: plugins.shortid.generate(),
funcCallData: {
funcName: functionNameArg,
funcDataArg: dataArg
}
});
socketRequest.dispatch().then((dataArg) => {
done.resolve(dataArg.funcDataArg);
});
return done.promise;
}
}
exports.SmartsocketClient = SmartsocketClient;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzb2NrZXQuY2xhc3Nlcy5zbWFydHNvY2tldGNsaWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0c29ja2V0LmNsYXNzZXMuc21hcnRzb2NrZXRjbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxpREFBaUQ7QUFNakQsaUJBQWlCO0FBQ2pCLGlHQUEwRTtBQUUxRSwyRkFBb0U7QUFZcEU7SUFPRSxZQUFZLFVBQXFDO1FBQy9DLElBQUksQ0FBQyxLQUFLLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQztRQUM5QixJQUFJLENBQUMsSUFBSSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUM7UUFDNUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQztRQUNsQyxJQUFJLENBQUMsY0FBYyxHQUFHLFVBQVUsQ0FBQyxRQUFRLENBQUM7SUFDNUMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsT0FBTztRQUNMLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbEMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUM5QyxJQUFJLFNBQVMsR0FBRyxHQUFHLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ3ZELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLHVEQUFnQixDQUFDO1lBQzNDLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztZQUNqQixhQUFhLEVBQUUsS0FBSztZQUNwQixJQUFJLEVBQUUsU0FBUztZQUNmLElBQUksRUFBRSxRQUFRO1lBQ2QsZUFBZSxFQUFFLElBQUk7WUFDckIsTUFBTSxFQUFFLE9BQU8sQ0FBQyxjQUFjLENBQUMsU0FBUyxFQUFFLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDO1NBQ2hFLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxHQUFHLEVBQUU7WUFDbEQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO1lBQy9DLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRTtnQkFDNUMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO2dCQUNmLFFBQVEsRUFBRSxJQUFJLENBQUMsY0FBYztnQkFDN0IsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO2FBQ2xCLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLGVBQWUsRUFBRSxHQUFHLEVBQUU7Z0JBQ3BELE9BQU8sQ0FBQyxHQUFHLENBQUMseUJBQXlCLENBQUMsQ0FBQztnQkFDdkMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7Z0JBQzNDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO2dCQUNqRCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakIsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUNILE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ3RCLENBQUM7SUFFRCxVQUFVO1FBQ1IsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNsQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQzFDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxTQUFTLENBQUM7UUFDbEMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2YsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDdEIsQ0FBQztJQUVELFVBQVUsQ0FBQyxlQUF1QixFQUFFLE9BQVk7UUFDOUMsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNsQyxJQUFJLGFBQWEsR0FBRyxJQUFJLGlEQUFhLENBQUM7WUFDcEMsSUFBSSxFQUFFLFlBQVk7WUFDbEIsc0JBQXNCLEVBQUUsSUFBSSxDQUFDLGdCQUFnQjtZQUM3QyxPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUU7WUFDbkMsWUFBWSxFQUFFO2dCQUNaLFFBQVEsRUFBRSxlQUFlO2dCQUN6QixXQUFXLEVBQUUsT0FBTzthQUNyQjtTQUNGLENBQUMsQ0FBQztRQUNILGFBQWEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUE0QixFQUFFLEVBQUU7WUFDN0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDcEMsQ0FBQyxDQUFDLENBQUM7UUFDSCxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN0QixDQUFDO0NBQ0Y7QUF4RUQsOENBd0VDIn0=

View File

@ -1,50 +0,0 @@
/// <reference types="socket.io" />
/// <reference types="socket.io-client" />
import * as plugins from './smartsocket.plugins';
import { Smartsocket } from './smartsocket.classes.smartsocket';
import { SocketRole } from './smartsocket.classes.socketrole';
import * as SocketIO from 'socket.io';
/**
* defines is a SocketConnection is server or client side. Important for mesh setups.
*/
export declare type TSocketConnectionSide = 'server' | 'client';
/**
* interface for constructor of class SocketConnection
*/
export interface ISocketConnectionConstructorOptions {
alias: string;
authenticated: boolean;
role: SocketRole;
side: TSocketConnectionSide;
smartsocketHost: Smartsocket;
socket: SocketIO.Socket | SocketIOClient.Socket;
}
/**
* interface for authentication data
*/
export interface ISocketConnectionAuthenticationObject {
role: 'coreflowContainer';
password: 'somePassword';
alias: 'coreflow1';
}
export declare let allSocketConnections: plugins.lik.Objectmap<SocketConnection>;
/**
* class SocketConnection represents a websocket connection
*/
export declare class SocketConnection {
alias: string;
side: TSocketConnectionSide;
authenticated: boolean;
role: SocketRole;
smartsocketHost: Smartsocket;
socket: any;
constructor(optionsArg: ISocketConnectionConstructorOptions);
/**
* authenticate the socket
*/
authenticate(): Promise<{}>;
/**
* listen to function requests
*/
listenToFunctionRequests(): Promise<{}>;
}

View File

@ -1,100 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const plugins = require("./smartsocket.plugins");
const helpers = require("./smartsocket.helpers");
const lik_1 = require("lik");
const smartsocket_classes_socketrequest_1 = require("./smartsocket.classes.socketrequest");
// export classes
exports.allSocketConnections = new lik_1.Objectmap();
/**
* class SocketConnection represents a websocket connection
*/
class SocketConnection {
constructor(optionsArg) {
this.authenticated = false;
this.alias = optionsArg.alias;
this.authenticated = optionsArg.authenticated;
this.role = optionsArg.role;
this.side = optionsArg.side;
this.smartsocketHost = optionsArg.smartsocketHost;
this.socket = optionsArg.socket;
// standard behaviour that is always true
exports.allSocketConnections.add(this);
this.socket.on('disconnect', () => {
plugins.beautylog.info(`SocketConnection with >alias ${this.alias} on >side ${this.side} disconnected`);
this.socket.disconnect();
exports.allSocketConnections.remove(this);
});
}
// authenticating --------------------------
/**
* authenticate the socket
*/
authenticate() {
let done = plugins.smartq.defer();
this.socket.on('dataAuth', (dataArg) => {
plugins.beautylog.log('received authentication data. now hashing and comparing...');
this.socket.removeListener('dataAuth', () => { });
if (helpers.checkPasswordForRole(dataArg, this.smartsocketHost)) {
// TODO: authenticate password
this.alias = dataArg.alias;
this.authenticated = true;
this.role = helpers.getSocketRoleByName(dataArg.role, this.smartsocketHost);
this.socket.emit('authenticated');
plugins.beautylog.ok(`socket with >>alias ${this.alias} >>role ${this.role} is authenticated!`);
done.resolve(this);
}
else {
this.authenticated = false;
this.socket.disconnect();
done.reject('not authenticated');
}
});
this.socket.emit('requestAuth');
return done.promise;
}
// listening -------------------------------
/**
* listen to function requests
*/
listenToFunctionRequests() {
let done = plugins.smartq.defer();
if (this.authenticated) {
this.socket.on('function', (dataArg) => {
// check if requested function is available to the socket's scope
plugins.beautylog.log('function request received');
let referencedFunction = this.role.allowedFunctions.find(socketFunctionArg => {
return socketFunctionArg.name === dataArg.funcCallData.funcName;
});
if (referencedFunction !== undefined) {
plugins.beautylog.ok('function in access scope');
let localSocketRequest = new smartsocket_classes_socketrequest_1.SocketRequest({
side: 'responding',
originSocketConnection: this,
shortId: dataArg.shortId,
funcCallData: dataArg.funcCallData
});
localSocketRequest.createResponse(); // takes care of creating response and sending it back
}
else {
plugins.beautylog.warn('function not existent or out of access scope');
}
});
this.socket.on('functionResponse', (dataArg) => {
plugins.beautylog.info(`received response for request with id ${dataArg.shortId}`);
let targetSocketRequest = helpers.getSocketRequestById(dataArg.shortId);
targetSocketRequest.handleResponse(dataArg);
});
plugins.beautylog.log(`now listening to function requests for ${this.alias}`);
done.resolve(this);
}
else {
let errMessage;
plugins.beautylog.error(errMessage);
done.reject(errMessage);
}
return done.promise;
}
}
exports.SocketConnection = SocketConnection;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzb2NrZXQuY2xhc3Nlcy5zb2NrZXRjb25uZWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRzb2NrZXQuY2xhc3Nlcy5zb2NrZXRjb25uZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsaURBQWlEO0FBQ2pELGlEQUFpRDtBQUVqRCw2QkFBZ0M7QUFLaEMsMkZBSTZDO0FBa0M3QyxpQkFBaUI7QUFDTixRQUFBLG9CQUFvQixHQUFHLElBQUksZUFBUyxFQUFvQixDQUFDO0FBRXBFOztHQUVHO0FBQ0g7SUFPRSxZQUFZLFVBQStDO1FBSjNELGtCQUFhLEdBQVksS0FBSyxDQUFDO1FBSzdCLElBQUksQ0FBQyxLQUFLLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQztRQUM5QixJQUFJLENBQUMsYUFBYSxHQUFHLFVBQVUsQ0FBQyxhQUFhLENBQUM7UUFDOUMsSUFBSSxDQUFDLElBQUksR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDO1FBQzVCLElBQUksQ0FBQyxJQUFJLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQztRQUM1QixJQUFJLENBQUMsZUFBZSxHQUFHLFVBQVUsQ0FBQyxlQUFlLENBQUM7UUFDbEQsSUFBSSxDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDO1FBRWhDLHlDQUF5QztRQUN6Qyw0QkFBb0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDL0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLEdBQUcsRUFBRTtZQUNoQyxPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksQ0FDcEIsZ0NBQWdDLElBQUksQ0FBQyxLQUFLLGFBQWEsSUFBSSxDQUFDLElBQUksZUFBZSxDQUNoRixDQUFDO1lBQ0YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUN6Qiw0QkFBb0IsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFD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

View File

@ -1,44 +0,0 @@
import * as plugins from './smartsocket.plugins';
import { SocketRole } from './smartsocket.classes.socketrole';
/**
* interface of the contructor options of class SocketFunction
*/
export interface ISocketFunctionConstructorOptions {
funcName: string;
funcDef: any;
allowedRoles: SocketRole[];
}
/**
* interface of the Socket Function call, in other words the object that routes a call to a function
*/
export interface ISocketFunctionCall {
funcName: string;
funcDataArg: any;
}
/**
* interface for function definition of SocketFunction
*/
export interface IFuncDef {
(dataArg: any): PromiseLike<any>;
}
export declare let allSocketFunctions: plugins.lik.Objectmap<SocketFunction>;
/**
* class that respresents a function that can be transparently called using a SocketConnection
*/
export declare class SocketFunction {
name: string;
funcDef: IFuncDef;
roles: SocketRole[];
/**
* the constructor for SocketFunction
*/
constructor(optionsArg: ISocketFunctionConstructorOptions);
/**
* invokes the function of this SocketFunction
*/
invoke(dataArg: ISocketFunctionCall): Promise<any>;
/**
* notifies a role about access to this SocketFunction
*/
private _notifyRole(socketRoleArg);
}

View File

@ -1,52 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const plugins = require("./smartsocket.plugins");
// import classes
const lik_1 = require("lik");
// export objects
exports.allSocketFunctions = new lik_1.Objectmap();
// export classes
/**
* class that respresents a function that can be transparently called using a SocketConnection
*/
class SocketFunction {
/**
* the constructor for SocketFunction
*/
constructor(optionsArg) {
this.name = optionsArg.funcName;
this.funcDef = optionsArg.funcDef;
this.roles = optionsArg.allowedRoles;
for (let socketRoleArg of this.roles) {
this._notifyRole(socketRoleArg);
}
exports.allSocketFunctions.add(this); // map instance with Objectmap
}
/**
* invokes the function of this SocketFunction
*/
invoke(dataArg) {
let done = plugins.smartq.defer();
if (dataArg.funcName === this.name) {
this.funcDef(dataArg.funcDataArg).then((resultData) => {
let funcResponseData = {
funcName: this.name,
funcDataArg: resultData
};
done.resolve(funcResponseData);
});
}
else {
throw new Error("SocketFunction.name does not match the data argument's .name!");
}
return done.promise;
}
/**
* notifies a role about access to this SocketFunction
*/
_notifyRole(socketRoleArg) {
socketRoleArg.addSocketFunction(this);
}
}
exports.SocketFunction = SocketFunction;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzb2NrZXQuY2xhc3Nlcy5zb2NrZXRmdW5jdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0c29ja2V0LmNsYXNzZXMuc29ja2V0ZnVuY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxpREFBaUQ7QUFFakQsaUJBQWlCO0FBQ2pCLDZCQUFnQztBQTZCaEMsaUJBQWlCO0FBQ04sUUFBQSxrQkFBa0IsR0FBRyxJQUFJLGVBQVMsRUFBa0IsQ0FBQztBQUVoRSxpQkFBaUI7QUFFakI7O0dBRUc7QUFDSDtJQUtFOztPQUVHO0lBQ0gsWUFBWSxVQUE2QztRQUN2RCxJQUFJLENBQUMsSUFBSSxHQUFHLFVBQVUsQ0FBQyxRQUFRLENBQUM7UUFDaEMsSUFBSSxDQUFDLE9BQU8sR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDO1FBQ2xDLElBQUksQ0FBQyxLQUFLLEdBQUcsVUFBVSxDQUFDLFlBQVksQ0FBQztRQUNyQyxHQUFHLENBQUMsQ0FBQyxJQUFJLGFBQWEsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUNyQyxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ2xDLENBQUM7UUFDRCwwQkFBa0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyw4QkFBOEI7SUFDOUQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsTUFBTSxDQUFDLE9BQTRCO1FBQ2pDLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbEMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUNuQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFlLEVBQUUsRUFBRTtnQkFDekQsSUFBSSxnQkFBZ0IsR0FBd0I7b0JBQzFDLFFBQVEsRUFBRSxJQUFJLENBQUMsSUFBSTtvQkFDbkIsV0FBVyxFQUFFLFVBQVU7aUJBQ3hCLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ2pDLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUFDLElBQUksQ0FBQyxDQUFDO1lBQ04sTUFBTSxJQUFJLEtBQUssQ0FBQywrREFBK0QsQ0FBQyxDQUFDO1FBQ25GLENBQUM7UUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN0QixDQUFDO0lBRUQ7O09BRUc7SUFDSyxXQUFXLENBQUMsYUFBeUI7UUFDM0MsYUFBYSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3hDLENBQUM7Q0FDRjtBQTNDRCx3Q0EyQ0MifQ==

View File

@ -1,44 +0,0 @@
import * as plugins from './smartsocket.plugins';
import { ISocketFunctionCall } from './smartsocket.classes.socketfunction';
import { SocketConnection } from './smartsocket.classes.socketconnection';
export declare type TSocketRequestStatus = 'new' | 'pending' | 'finished';
export declare type TSocketRequestSide = 'requesting' | 'responding';
/**
* interface of constructor of class SocketRequest
*/
export interface SocketRequestConstructorOptions {
side: TSocketRequestSide;
originSocketConnection: SocketConnection;
shortId: string;
funcCallData?: ISocketFunctionCall;
}
/**
* request object that is sent initially and may or may not receive a response
*/
export interface ISocketRequestDataObject {
funcCallData: ISocketFunctionCall;
shortId: string;
responseTimeout?: number;
}
export declare let allSocketRequests: plugins.lik.Objectmap<SocketRequest>;
export declare class SocketRequest {
status: TSocketRequestStatus;
side: TSocketRequestSide;
shortid: string;
originSocketConnection: SocketConnection;
funcCallData: ISocketFunctionCall;
done: plugins.smartq.Deferred<{}>;
constructor(optionsArg: SocketRequestConstructorOptions);
/**
* dispatches a socketrequest from the requesting to the receiving side
*/
dispatch(): Promise<{}>;
/**
* handles the response that is received by the requesting side
*/
handleResponse(responseDataArg: ISocketRequestDataObject): void;
/**
* creates the response on the responding side
*/
createResponse(): void;
}

View File

@ -1,59 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const plugins = require("./smartsocket.plugins");
const helpers = require("./smartsocket.helpers");
// import classes
const lik_1 = require("lik");
// export objects
exports.allSocketRequests = new lik_1.Objectmap();
// export classes
class SocketRequest {
constructor(optionsArg) {
this.status = 'new';
this.done = plugins.smartq.defer();
this.side = optionsArg.side;
this.shortid = optionsArg.shortId;
this.funcCallData = optionsArg.funcCallData;
this.originSocketConnection = optionsArg.originSocketConnection;
exports.allSocketRequests.add(this);
}
// requesting --------------------------
/**
* dispatches a socketrequest from the requesting to the receiving side
*/
dispatch() {
let requestData = {
funcCallData: this.funcCallData,
shortId: this.shortid
};
this.originSocketConnection.socket.emit('function', requestData);
return this.done.promise;
}
/**
* handles the response that is received by the requesting side
*/
handleResponse(responseDataArg) {
plugins.beautylog.log('handling response!');
this.done.resolve(responseDataArg.funcCallData);
exports.allSocketRequests.remove(this);
}
// responding --------------------------
/**
* creates the response on the responding side
*/
createResponse() {
let targetSocketFunction = helpers.getSocketFunctionByName(this.funcCallData.funcName);
plugins.beautylog.info(`invoking ${targetSocketFunction.name}`);
targetSocketFunction.invoke(this.funcCallData).then(resultData => {
plugins.beautylog.log('got resultData. Sending it to requesting party.');
let requestData = {
funcCallData: resultData,
shortId: this.shortid
};
this.originSocketConnection.socket.emit('functionResponse', requestData);
exports.allSocketRequests.remove(this);
});
}
}
exports.SocketRequest = SocketRequest;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzb2NrZXQuY2xhc3Nlcy5zb2NrZXRyZXF1ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRzb2NrZXQuY2xhc3Nlcy5zb2NrZXRyZXF1ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsaURBQWlEO0FBQ2pELGlEQUFpRDtBQUtqRCxpQkFBaUI7QUFDakIsNkJBQWdDO0FBMkJoQyxpQkFBaUI7QUFDTixRQUFBLGlCQUFpQixHQUFHLElBQUksZUFBUyxFQUFpQixDQUFDO0FBRTlELGlCQUFpQjtBQUNqQjtJQU9FLFlBQVksVUFBMkM7UUFOdkQsV0FBTSxHQUF5QixLQUFLLENBQUM7UUFLckMsU0FBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFNUIsSUFBSSxDQUFDLElBQUksR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDO1FBQzVCLElBQUksQ0FBQyxPQUFPLEdBQUcsVUFBVSxDQUFDLE9BQU8sQ0FBQztRQUNsQyxJQUFJLENBQUMsWUFBWSxHQUFHLFVBQVUsQ0FBQyxZQUFZLENBQUM7UUFDNUMsSUFBSSxDQUFDLHNCQUFzQixHQUFHLFVBQVUsQ0FBQyxzQkFBc0IsQ0FBQztRQUNoRSx5QkFBaUIsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDOUIsQ0FBQztJQUVELHdDQUF3QztJQUV4Qzs7T0FFRztJQUNILFFBQVE7UUFDTixJQUFJLFdBQVcsR0FBNkI7WUFDMUMsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZO1lBQy9CLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztTQUN0QixDQUFDO1FBQ0YsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ2pFLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUMzQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxjQUFjLENBQUMsZUFBeUM7UUFDdEQsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDaEQseUJBQWlCLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFRCx3Q0FBd0M7SUFFeEM7O09BRUc7SUFDSCxjQUFjO1FBQ1osSUFBSSxvQkFBb0IsR0FBbUIsT0FBTyxDQUFDLHVCQUF1QixDQUN4RSxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FDM0IsQ0FBQztRQUNGLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFlBQVksb0JBQW9CLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNoRSxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRTtZQUMvRCxPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxpREFBaUQsQ0FBQyxDQUFDO1lBQ3pFLElBQUksV0FBVyxHQUE2QjtnQkFDMUMsWUFBWSxFQUFFLFVBQVU7Z0JBQ3hCLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTzthQUN0QixDQUFDO1lBQ0YsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDekUseUJBQWlCLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBMURELHNDQTBEQyJ9

View File

@ -1,19 +0,0 @@
import * as plugins from './smartsocket.plugins';
import { SocketFunction } from './smartsocket.classes.socketfunction';
/**
* interface for class SocketRole
*/
export interface SocketRoleOptions {
name: string;
passwordHash: string;
}
/**
* A socketrole defines access to certain routines.
*/
export declare class SocketRole {
name: string;
passwordHash: string;
allowedFunctions: plugins.lik.Objectmap<SocketFunction>;
constructor(optionsArg: SocketRoleOptions);
addSocketFunction(socketFunctionArg: SocketFunction): void;
}

View File

@ -1,19 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
// import classes
const lik_1 = require("lik");
/**
* A socketrole defines access to certain routines.
*/
class SocketRole {
constructor(optionsArg) {
this.allowedFunctions = new lik_1.Objectmap();
this.name = optionsArg.name;
this.passwordHash = optionsArg.passwordHash;
}
addSocketFunction(socketFunctionArg) {
this.allowedFunctions.add(socketFunctionArg);
}
}
exports.SocketRole = SocketRole;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzb2NrZXQuY2xhc3Nlcy5zb2NrZXRyb2xlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRzb2NrZXQuY2xhc3Nlcy5zb2NrZXRyb2xlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBRUEsaUJBQWlCO0FBQ2pCLDZCQUFnQztBQVdoQzs7R0FFRztBQUNIO0lBSUUsWUFBWSxVQUE2QjtRQUR6QyxxQkFBZ0IsR0FBRyxJQUFJLGVBQVMsRUFBa0IsQ0FBQztRQUVqRCxJQUFJLENBQUMsSUFBSSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUM7UUFDNUIsSUFBSSxDQUFDLFlBQVksR0FBRyxVQUFVLENBQUMsWUFBWSxDQUFDO0lBQzlDLENBQUM7SUFDRCxpQkFBaUIsQ0FBQyxpQkFBaUM7UUFDakQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQy9DLENBQUM7Q0FDRjtBQVhELGdDQVdDIn0=

View File

@ -1,15 +0,0 @@
import { Smartsocket } from './smartsocket.classes.smartsocket';
import { SocketFunction } from './smartsocket.classes.socketfunction';
import { ISocketConnectionAuthenticationObject } from './smartsocket.classes.socketconnection';
import { SocketRequest, TSocketRequestSide } from './smartsocket.classes.socketrequest';
import { SocketRole } from './smartsocket.classes.socketrole';
export declare let checkPasswordForRole: (dataArg: ISocketConnectionAuthenticationObject, referenceSmartsocket: Smartsocket) => boolean;
export declare let getSocketFunctionByName: (functionNameArg: string) => SocketFunction;
/**
* get corresponding Socketrequest instance by shortId
*/
export declare let getSocketRequestById: (shortIdArg: string, requestSide?: TSocketRequestSide) => SocketRequest;
/**
* get corresponding SocketRole instance by name
*/
export declare let getSocketRoleByName: (socketRoleNameArg: string, referenceSmartsocket: Smartsocket) => SocketRole;

View File

@ -1,36 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const plugins = require("./smartsocket.plugins");
const smartsocket_classes_socketfunction_1 = require("./smartsocket.classes.socketfunction");
const smartsocket_classes_socketrequest_1 = require("./smartsocket.classes.socketrequest");
// SocketConnection helpers
exports.checkPasswordForRole = (dataArg, referenceSmartsocket) => {
let targetPasswordHash = exports.getSocketRoleByName(dataArg.role, referenceSmartsocket).passwordHash;
let computedCompareHash = plugins.nodehash.sha256FromStringSync(dataArg.password);
return targetPasswordHash === computedCompareHash;
};
// SocketFunction helpers
exports.getSocketFunctionByName = (functionNameArg) => {
return smartsocket_classes_socketfunction_1.allSocketFunctions.find(socketFunctionArg => {
return socketFunctionArg.name === functionNameArg;
});
};
// SocketRequest helpers
/**
* get corresponding Socketrequest instance by shortId
*/
exports.getSocketRequestById = (shortIdArg, requestSide) => {
return smartsocket_classes_socketrequest_1.allSocketRequests.find(socketRequestArg => {
return socketRequestArg.shortid === shortIdArg;
});
};
// SocketRole helpers
/**
* get corresponding SocketRole instance by name
*/
exports.getSocketRoleByName = (socketRoleNameArg, referenceSmartsocket) => {
return referenceSmartsocket.socketRoles.find(socketRoleArg => {
return socketRoleArg.name === socketRoleNameArg;
});
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzb2NrZXQuaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0c29ja2V0LmhlbHBlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxpREFBaUQ7QUFJakQsNkZBQTBGO0FBSzFGLDJGQUk2QztBQUc3QywyQkFBMkI7QUFDaEIsUUFBQSxvQkFBb0IsR0FBRyxDQUNoQyxPQUE4QyxFQUM5QyxvQkFBaUMsRUFDeEIsRUFBRTtJQUNYLElBQUksa0JBQWtCLEdBQUcsMkJBQW1CLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxvQkFBb0IsQ0FBQyxDQUFDLFlBQVksQ0FBQztJQUM5RixJQUFJLG1CQUFtQixHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2xGLE1BQU0sQ0FBQyxrQkFBa0IsS0FBSyxtQkFBbUIsQ0FBQztBQUNwRCxDQUFDLENBQUM7QUFFRix5QkFBeUI7QUFDZCxRQUFBLHVCQUF1QixHQUFHLENBQUMsZUFBdUIsRUFBa0IsRUFBRTtJQUMvRSxNQUFNLENBQUMsdURBQWtCLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEVBQUU7UUFDakQsTUFBTSxDQUFDLGlCQUFpQixDQUFDLElBQUksS0FBSyxlQUFlLENBQUM7SUFDcEQsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUM7QUFFRix3QkFBd0I7QUFFeEI7O0dBRUc7QUFDUSxRQUFBLG9CQUFvQixHQUFHLENBQ2hDLFVBQWtCLEVBQ2xCLFdBQWdDLEVBQ2pCLEVBQUU7SUFDakIsTUFBTSxDQUFDLHFEQUFpQixDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFO1FBQy9DLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEtBQUssVUFBVSxDQUFDO0lBQ2pELENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDO0FBRUYscUJBQXFCO0FBRXJCOztHQUVHO0FBQ1EsUUFBQSxtQkFBbUIsR0FBRyxDQUMvQixpQkFBeUIsRUFDekIsb0JBQWlDLEVBQ3JCLEVBQUU7SUFDZCxNQUFNLENBQUMsb0JBQW9CLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFBRTtRQUMzRCxNQUFNLENBQUMsYUFBYSxDQUFDLElBQUksS0FBSyxpQkFBaUIsQ0FBQztJQUNsRCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyJ9

View File

@ -1,8 +0,0 @@
export import beautylog = require('beautylog');
export import lik = require('lik');
export import nodehash = require('nodehash');
export import smartdelay = require('smartdelay');
export import smartq = require('smartq');
export import shortid = require('shortid');
export import socketIo = require('socket.io');
export import socketIoClient = require('socket.io-client');

View File

@ -1,11 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.beautylog = require("beautylog");
exports.lik = require("lik");
exports.nodehash = require("nodehash");
exports.smartdelay = require("smartdelay");
exports.smartq = require("smartq");
exports.shortid = require("shortid");
exports.socketIo = require("socket.io");
exports.socketIoClient = require("socket.io-client");
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzb2NrZXQucGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0c29ja2V0LnBsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx5Q0FBK0M7QUFDL0MsNkJBQW1DO0FBQ25DLHVDQUE2QztBQUM3QywyQ0FBaUQ7QUFDakQsbUNBQXlDO0FBQ3pDLHFDQUEyQztBQUMzQyx3Q0FBOEM7QUFDOUMscURBQTJEIn0=

View File

@ -1,111 +0,0 @@
# smartsocket
easy and secure websocket communication, TypeScript ready
## Availabililty
[![npm](https://pushrocks.gitlab.io/assets/repo-button-npm.svg)](https://www.npmjs.com/package/smartsocket)
[![git](https://pushrocks.gitlab.io/assets/repo-button-git.svg)](https://GitLab.com/pushrocks/smartsocket)
[![git](https://pushrocks.gitlab.io/assets/repo-button-mirror.svg)](https://github.com/pushrocks/smartsocket)
[![docs](https://pushrocks.gitlab.io/assets/repo-button-docs.svg)](https://pushrocks.gitlab.io/smartsocket/)
## Status for master
[![build status](https://GitLab.com/pushrocks/smartsocket/badges/master/build.svg)](https://GitLab.com/pushrocks/smartsocket/commits/master)
[![coverage report](https://GitLab.com/pushrocks/smartsocket/badges/master/coverage.svg)](https://GitLab.com/pushrocks/smartsocket/commits/master)
[![npm downloads per month](https://img.shields.io/npm/dm/smartsocket.svg)](https://www.npmjs.com/package/smartsocket)
[![Dependency Status](https://david-dm.org/pushrocks/smartsocket.svg)](https://david-dm.org/pushrocks/smartsocket)
[![bitHound Dependencies](https://www.bithound.io/github/pushrocks/smartsocket/badges/dependencies.svg)](https://www.bithound.io/github/pushrocks/smartsocket/master/dependencies/npm)
[![bitHound Code](https://www.bithound.io/github/pushrocks/smartsocket/badges/code.svg)](https://www.bithound.io/github/pushrocks/smartsocket)
[![TypeScript](https://img.shields.io/badge/TypeScript-2.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![node](https://img.shields.io/badge/node->=%206.x.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)
## Usage
Use TypeScript for best in class instellisense.
Under the hood we use socket.io and shortid for managed data exchange.
### Serverside
```typescript
import * as smartsocket from 'smartsocket';
import * as q from q; // q is a promise library
// The "Smartsocket" listens on a port and can receive new "SocketConnection" requests.
let mySmartsocket = new smartsocket.Smartsocket({
port: 3000 // the port smartsocket will listen on
});
// A "SocketRole" can be referenced by "SocketFunction"s.
// All "SocketRequest"s carry authentication data for a specific "SocketRole".
// "SocketFunction"s know which "SocketRole"s are allowed to execute them
let mySocketRole = new smartsocket.SocketRole({
name: 'someRoleName',
passwordHash: 'someHashedString'
});
// A "SocketFunction" executes a referenced function and passes in any data of the corresponding "SocketRequest".
// The referenced function must return a promise and resolve with data of type any.
// Any "SocketRequest" carries a unique identifier. If the referenced function's promise resolved any passed on argument will be returned to the requesting party
let testSocketFunction1 = new smartsocket.SocketFunction({
funcName: 'testSocketFunction1',
funcDef: data => {
console.log('testSocketFunction1 executed successfully!');
},
allowedRoles: [mySocketRole] // all roles that have access to a specific function
});
// A "Smartsocket" exposes a .clientCall() that gets
// 1. the name of the "SocketFunction" on the client side
// 2. the data to pass in
// 3. And a target "SocketConnection" (there can be multiple connections at once)
// any unique id association is done internally
mySmartsocket.clientCall('restart', data, someTargetConnection).then(responseData => {});
```
#### Client side
```typescript
import * as smartsocket from 'smartsocket';
// A "SmartsocketClient" is different from a "Smartsocket" in that it doesn't expose any public address.
// Thus any new "SocketConnection"s must be innitiated from a "SmartsocketClient".
let testSmartsocketClient = new smartsocket.SmartsocketClient({
port: testConfig.port,
url: 'http://localhost',
password: 'testPassword',
alias: 'testClient1',
role: 'testRole1'
});
// You can .connect() and .disconnect() from a "Smartsocket"
testSmartsocketClient.connect().then(() => {
done();
});
// The client can also specify "SocketFunction"s. It can also specify "SocketRole"s in case a client connects to multiple servers at once
let testSocketFunction2 = new smartsocket.SocketFunction({
funcName: 'testSocketFunction2',
funcDef: data => {}, // the function to execute, has to return promise
allowedRoles: []
});
// A "SmartsocketClient" can call functions on the serverside using .serverCall() analog to the "Smartsocket"'s .clientCall method.
mySmartsocketClient.serverCall('function', functionCallData).then(functionResponseData => {
// the functionResponseData comes from the server... awesome, right?
});
```
> **NOTE:**
> you can easily chain dependent requests on either the server or client side with promises.
> `data` is always a js object that you can design for your specific needs.
> It supports buffers for large binary data network exchange.
For further information read the linked docs at the top of this README.
> MIT licensed | **&copy;** [Lossless GmbH](https://lossless.gmbh)
> | By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy.html)
[![repo-footer](https://pushrocks.gitlab.io/assets/repo-footer.svg)](https://push.rocks)

View File

@ -1,8 +1,18 @@
{
"npmts":{},
"gitzone": {
"projectType": "npm",
"module": {
"githost": "gitlab.com",
"gitscope": "pushrocks",
"gitrepo": "smartsocket",
"shortDescription": "easy and secure websocket communication",
"npmPackagename": "@pushrocks/smartsocket",
"license": "MIT",
"projectDomain": "push.rocks"
}
},
"npmci": {
"npmGlobalTools": [
"npmts"
]
"npmGlobalTools": [],
"npmAccessLevel": "public"
}
}

11315
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,12 @@
{
"name": "smartsocket",
"version": "1.1.13",
"description": "easy and secure websocket communication, TypeScript ready",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"name": "@pushrocks/smartsocket",
"version": "1.1.65",
"description": "easy and secure websocket communication",
"main": "dist_ts/index.js",
"typings": "dist_ts/index.d.ts",
"scripts": {
"test": "(npmts)"
"test": "(tstest test/)",
"build": "(tsbuild --web && tsbundle --from ./ts/index.ts --to dist_bundle/bundle.js)"
},
"repository": {
"type": "git",
@ -18,19 +19,45 @@
},
"homepage": "https://gitlab.com/pushrocks/smartsocket#README",
"dependencies": {
"@types/shortid": "0.0.29",
"@types/socket.io": "^1.4.32",
"@types/socket.io-client": "^1.4.32",
"beautylog": "^6.1.10",
"lik": "^2.0.5",
"nodehash": "^1.0.4",
"shortid": "^2.2.8",
"smartdelay": "^1.0.4",
"smartq": "^1.1.6",
"socket.io": "^2.0.4",
"socket.io-client": "^2.0.4"
"@apiglobal/typedrequest-interfaces": "^1.0.15",
"@pushrocks/isohash": "^1.0.2",
"@pushrocks/isounique": "^1.0.4",
"@pushrocks/lik": "^4.0.17",
"@pushrocks/smartdelay": "^2.0.10",
"@pushrocks/smartenv": "^4.0.15",
"@pushrocks/smartexpress": "^3.0.76",
"@pushrocks/smartlog": "^2.0.39",
"@pushrocks/smartpromise": "^3.0.6",
"@pushrocks/smartrx": "^2.0.19",
"@pushrocks/smarttime": "^3.0.35",
"@types/socket.io": "^2.1.11",
"@types/socket.io-client": "^1.4.33",
"socket.io": "^2.3.0",
"socket.io-client": "^2.3.0"
},
"devDependencies": {
"tapbundle": "^2.0.0"
}
"@gitzone/tsbuild": "^2.1.25",
"@gitzone/tsrun": "^1.2.12",
"@gitzone/tstest": "^1.0.48",
"@pushrocks/tapbundle": "^3.2.9",
"@types/node": "^14.11.2",
"tslint": "^6.1.3",
"tslint-config-prettier": "^1.18.0"
},
"private": false,
"files": [
"ts/**/*",
"ts_web/**/*",
"dist/**/*",
"dist_*/**/*",
"dist_ts/**/*",
"dist_ts_web/**/*",
"assets/**/*",
"cli.js",
"npmextra.json",
"readme.md"
],
"browserslist": [
"last 1 chrome versions"
]
}

1
test/common/test.ts Normal file
View File

@ -0,0 +1 @@
console.log('TODO');

104
test/test.expressserver.ts Normal file
View File

@ -0,0 +1,104 @@
// tslint:disable-next-line:no-implicit-dependencies
import { expect, tap } from '@pushrocks/tapbundle';
import * as smarthash from '@pushrocks/smarthash';
import * as smartpromise from '@pushrocks/smartpromise';
import * as smartexpress from '@pushrocks/smartexpress';
import socketIoClient = require('socket.io-client');
import smartsocket = require('../ts/index');
let testSmartsocket: smartsocket.Smartsocket;
let testSmartsocketClient: smartsocket.SmartsocketClient;
let testSocketRole1: smartsocket.SocketRole;
let testSocketFunction1: smartsocket.SocketFunction<any>;
let myseServer: smartexpress.Server;
const testConfig = {
port: 3000,
};
// class smartsocket
tap.test('should create a new smartsocket', async () => {
testSmartsocket = new smartsocket.Smartsocket({ port: testConfig.port });
expect(testSmartsocket).be.instanceOf(smartsocket.Smartsocket);
});
tap.test('Should accept an smartExpressServer as server', async () => {
myseServer = new smartexpress.Server({
cors: true,
forceSsl: false,
port: testConfig.port,
});
testSmartsocket.setExternalServer('smartexpress', myseServer);
await myseServer.start();
});
// class socketrole
tap.test('should add a socketrole', async () => {
testSocketRole1 = new smartsocket.SocketRole({
name: 'testRole1',
passwordHash: smarthash.sha256FromStringSync('testPassword'),
});
testSmartsocket.addSocketRoles([testSocketRole1]);
});
// class SocketFunction
tap.test('should register a new Function', async () => {
testSocketFunction1 = new smartsocket.SocketFunction({
allowedRoles: [testSocketRole1],
funcDef: async (dataArg, socketConnectionArg) => {
return dataArg;
},
funcName: 'testFunction1',
});
testSmartsocket.addSocketFunction(testSocketFunction1);
console.log(testSmartsocket.socketFunctions);
});
tap.test('should start listening when .started is called', async () => {
await testSmartsocket.start();
});
// class SmartsocketClient
tap.test('should react to a new websocket connection from client', async () => {
testSmartsocketClient = new smartsocket.SmartsocketClient({
port: testConfig.port,
url: 'http://localhost',
password: 'testPassword',
alias: 'testClient1',
role: 'testRole1',
});
testSmartsocketClient.addSocketFunction(testSocketFunction1);
console.log(testSmartsocketClient.socketFunctions);
await testSmartsocketClient.connect();
});
tap.test('client should disconnect and reconnect', async (tools) => {
await testSmartsocketClient.disconnect();
await tools.delayFor(100);
await testSmartsocketClient.connect();
});
tap.test('2 clients should connect in parallel', async () => {
// TODO: implement parallel test
});
tap.test('should be able to make a functionCall from client to server', async () => {
const response = await testSmartsocketClient.serverCall('testFunction1', {
value1: 'hello',
});
console.log(response);
});
tap.test('should be able to make a functionCall from server to client', async () => {});
// terminate
tap.test('should close the server', async () => {
await testSmartsocket.stop();
await myseServer.stop();
});
tap.start();

View File

@ -1,17 +1,41 @@
import { expect, tap } from 'tapbundle';
// tslint:disable-next-line:no-implicit-dependencies
import { expect, tap } from '@pushrocks/tapbundle';
import * as smarthash from '@pushrocks/smarthash';
import * as smartpromise from '@pushrocks/smartpromise';
import socketIoClient = require('socket.io-client');
import smartsocket = require('../ts/index');
import smartq = require('smartq');
import nodehash = require('nodehash');
let testSmartsocket: smartsocket.Smartsocket;
let testSmartsocketClient: smartsocket.SmartsocketClient;
let testSocketConnection: smartsocket.SocketConnection;
let testSocketRole1: smartsocket.SocketRole;
let testSocketFunction1: smartsocket.SocketFunction;
let testSocketFunctionForServer: smartsocket.SocketFunction<any>;
let testSocketFunctionClient: smartsocket.SocketFunction<any>;
let testConfig = {
port: 3000
export interface IReqResClient {
method: 'testFunction1';
request: {
value1: string;
};
response: {
value1: string;
};
}
export interface IReqResServer {
method: 'testFunction2';
request: {
hi: string;
};
response: {
hi: string;
};
}
const testConfig = {
port: 3000,
};
// class smartsocket
@ -20,101 +44,90 @@ tap.test('should create a new smartsocket', async () => {
expect(testSmartsocket).be.instanceOf(smartsocket.Smartsocket);
});
tap.test('should start listening when .started is called', async () => {
testSmartsocket.startServer();
});
// class socketrole
tap.test('should add a socketrole', async () => {
testSocketRole1 = new smartsocket.SocketRole({
name: 'testRole1',
passwordHash: nodehash.sha256FromStringSync('testPassword')
passwordHash: smarthash.sha256FromStringSync('testPassword'),
});
testSmartsocket.addSocketRoles([testSocketRole1]);
});
// class SocketFunction
tap.test('should register a new Function', async () => {
testSocketFunction1 = new smartsocket.SocketFunction({
funcName: 'testFunction1',
funcDef: async dataArg => {
testSocketFunctionForServer = new smartsocket.SocketFunction({
allowedRoles: [testSocketRole1],
funcDef: async (dataArg, socketConnectionArg) => {
return dataArg;
},
allowedRoles: [testSocketRole1]
funcName: 'testFunction1',
});
testSmartsocket.addSocketFunction(testSocketFunctionForServer);
testSocketFunctionClient = new smartsocket.SocketFunction({
allowedRoles: [],
funcDef: async (dataArg, socketConnectionArg) => {
return dataArg;
},
funcName: 'testFunction2',
});
testSmartsocket.addSocketFunction(testSocketFunctionForServer);
console.log(testSmartsocket.socketFunctions);
});
tap.test('should start listening when .started is called', async () => {
await testSmartsocket.start();
});
// class SmartsocketClient
tap.test('should react to a new websocket connection from client', async () => {
let done = smartq.defer();
testSmartsocketClient = new smartsocket.SmartsocketClient({
port: testConfig.port,
url: 'http://localhost',
password: 'testPassword',
alias: 'testClient1',
role: 'testRole1'
role: 'testRole1',
});
testSmartsocketClient.connect().then(() => {
done.resolve();
});
await done.promise;
});
tap.test('client should disconnect and reconnect', async () => {
let done = smartq.defer();
testSmartsocketClient
.disconnect()
.then(() => {
let done = smartq.defer();
setTimeout(() => {
testSmartsocketClient.connect().then(done.resolve);
}, 0);
return done.promise;
})
.then(() => {
done.resolve();
});
await done.promise;
testSmartsocketClient.addSocketFunction(testSocketFunctionClient);
console.log(testSmartsocketClient.socketFunctions);
await testSmartsocketClient.connect();
});
tap.test('2 clients should connect in parallel', async () => {
// nothing here
// TODO: implement parallel test
});
tap.test('should be able to make a functionCall from client to server', async () => {
let done = smartq.defer();
testSmartsocketClient
.serverCall('testFunction1', {
value1: 'hello'
})
.then(dataArg => {
console.log(dataArg);
done.resolve();
const response = await testSmartsocketClient.serverCall<IReqResClient>('testFunction1', {
value1: 'hello',
});
await done.promise;
console.log(response);
expect(response.value1).to.equal('hello');
});
tap.test('should be able to make a functionCall from server to client', async () => {
let done = smartq.defer();
let targetSocket = (() => {
return smartsocket.allSocketConnections.find(socketConnectionArg => {
return socketConnectionArg.alias === 'testClient1';
});
})();
testSmartsocket
.clientCall(
'testFunction1',
const response = await testSmartsocket.clientCall<IReqResServer>(
'testFunction2',
{
value1: 'helloFromServer'
hi: 'hi there from server',
},
targetSocket
)
.then(dataArg => {
console.log(dataArg);
done.resolve();
testSmartsocket.socketConnections.find((socketConnection) => {
return true;
})
);
console.log(response);
expect(response.hi).to.equal('hi there from server');
});
tap.test('client should disconnect and reconnect', async (tools) => {
await testSmartsocketClient.disconnect();
await tools.delayFor(100);
await testSmartsocketClient.connect();
});
// terminate
tap.test('should close the server', async () => {
await testSmartsocket.closeServer();
await testSmartsocket.stop();
});
tap.start();

View File

@ -1,5 +1,3 @@
import * as plugins from './smartsocket.plugins';
// export main classes
export * from './smartsocket.classes.smartsocket';
export * from './smartsocket.classes.smartsocketclient';

View File

@ -0,0 +1,10 @@
export interface IRequestAuthPayload {
serverShortId: string;
}
export type TConnectionStatus =
| 'new'
| 'connecting'
| 'connected'
| 'disconnecting'
| 'disconnected';

1
ts/interfaces/index.ts Normal file
View File

@ -0,0 +1 @@
export * from './connection';

View File

@ -1,68 +1,73 @@
import * as plugins from './smartsocket.plugins';
import * as helpers from './smartsocket.helpers';
import * as http from 'http';
import * as pluginsTyped from './smartsocket.pluginstyped';
// classes
import { Objectmap } from 'lik';
import { SocketFunction, ISocketFunctionCall } from './smartsocket.classes.socketfunction';
import { SocketConnection } from './smartsocket.classes.socketconnection';
import {
ISocketFunctionCallDataRequest,
SocketFunction,
ISocketFunctionCallDataResponse,
} from './smartsocket.classes.socketfunction';
import { SocketRequest } from './smartsocket.classes.socketrequest';
import { SocketRole } from './smartsocket.classes.socketrole';
import { SocketServer } from './smartsocket.classes.socketserver';
// socket.io
import * as SocketIO from 'socket.io';
import { logger } from './smartsocket.logging';
export interface ISmartsocketConstructorOptions {
port: number;
port?: number;
}
export class Smartsocket {
options: ISmartsocketConstructorOptions;
httpServer: http.Server;
io: SocketIO.Server;
openSockets = new Objectmap<SocketConnection>();
socketRoles = new Objectmap<SocketRole>();
/**
* a unique id to detect server restarts
*/
public shortId = plugins.isounique.uni();
public smartenv = new plugins.smartenv.Smartenv();
public options: ISmartsocketConstructorOptions;
public io: pluginsTyped.socketIo.Server;
public socketConnections = new plugins.lik.ObjectMap<SocketConnection>();
public socketRoles = new plugins.lik.ObjectMap<SocketRole>();
public socketFunctions = new plugins.lik.ObjectMap<SocketFunction<any>>();
public socketRequests = new plugins.lik.ObjectMap<SocketRequest<any>>();
private socketServer = new SocketServer(this);
constructor(optionsArg: ISmartsocketConstructorOptions) {
this.options = optionsArg;
}
/**
* starts listening to incoming sockets:
*/
async startServer() {
let done = plugins.smartq.defer();
if (!this.httpServer) {
this.httpServer = new http.Server();
// tslint:disable-next-line:member-ordering
public async setExternalServer(serverType: 'smartexpress', serverArg: any) {
await this.socketServer.setExternalServer(serverType, serverArg);
}
this.io = plugins.socketIo(this.httpServer);
this.io.on('connection', socketArg => {
/**
* starts smartsocket
*/
public async start() {
const socketIoModule = this.smartenv.getSafeNodeModule('socket.io');
this.io = socketIoModule(this.socketServer.getServerForSocketIo());
await this.socketServer.start();
this.io.on('connection', (socketArg) => {
this._handleSocketConnection(socketArg);
});
this.httpServer.listen(this.options.port, () => {
done.resolve();
});
return await done.promise;
}
/**
* starts the server with another server
* stops smartsocket
*/
async setServer(httpServerArg: http.Server) {
this.httpServer = httpServerArg;
}
/**
* closes the server
*/
async closeServer() {
public async stop() {
await plugins.smartdelay.delayFor(1000);
this.openSockets.forEach((socketObjectArg: SocketConnection) => {
plugins.beautylog.log(`disconnect socket with >>alias ${socketObjectArg.alias}`);
this.socketConnections.forEach((socketObjectArg: SocketConnection) => {
logger.log('info', `disconnect socket with >>alias ${socketObjectArg.alias}`);
socketObjectArg.socket.disconnect();
});
this.openSockets.wipe();
this.socketConnections.wipe();
this.io.close();
// stop the corresponging server
this.socketServer.stop();
}
// communication
@ -70,54 +75,54 @@ export class Smartsocket {
/**
* allows call to specific client.
*/
clientCall(functionNameArg: string, dataArg: any, targetSocketConnectionArg: SocketConnection) {
let done = plugins.smartq.defer();
let socketRequest = new SocketRequest({
side: 'requesting',
originSocketConnection: targetSocketConnectionArg,
shortId: plugins.shortid.generate(),
public async clientCall<T extends plugins.typedrequestInterfaces.ITypedRequest>(
functionNameArg: T['method'],
dataArg: T['request'],
targetSocketConnectionArg: SocketConnection
): Promise<T['response']> {
const socketRequest = new SocketRequest<T>(this, {
funcCallData: {
funcDataArg: dataArg,
funcName: functionNameArg,
funcDataArg: dataArg
}
},
originSocketConnection: targetSocketConnectionArg,
shortId: plugins.isounique.uni(),
side: 'requesting',
});
socketRequest.dispatch().then((dataArg: ISocketFunctionCall) => {
done.resolve(dataArg.funcDataArg);
});
return done.promise;
const response: ISocketFunctionCallDataResponse<T> = await socketRequest.dispatch();
const result = response.funcDataArg;
return result;
}
/**
* adds socketRoles
*/
addSocketRoles(socketRolesArray: SocketRole[]): void {
for (let socketRole of socketRolesArray) {
public addSocketRoles(socketRolesArray: SocketRole[]): void {
for (const socketRole of socketRolesArray) {
this.socketRoles.add(socketRole);
}
return;
}
public addSocketFunction(socketFunction: SocketFunction<any>) {
this.socketFunctions.add(socketFunction);
}
/**
* the standard handler for new socket connections
*/
private _handleSocketConnection(socketArg) {
let socketConnection: SocketConnection = new SocketConnection({
private async _handleSocketConnection(socketArg: pluginsTyped.socketIo.Socket) {
const socketConnection: SocketConnection = new SocketConnection({
alias: undefined,
authenticated: false,
role: undefined,
side: 'server',
smartsocketHost: this,
socket: socketArg
});
plugins.beautylog.log('Socket connected. Trying to authenticate...');
this.openSockets.add(socketConnection);
socketConnection
.authenticate()
.then(() => {
return socketConnection.listenToFunctionRequests();
})
.catch(err => {
console.log(err);
socket: socketArg,
});
logger.log('info', 'Socket connected. Trying to authenticate...');
this.socketConnections.add(socketConnection);
await socketConnection.authenticate();
await socketConnection.listenToFunctionRequests();
}
}

View File

@ -1,13 +1,16 @@
import * as plugins from './smartsocket.plugins';
import * as pluginsTyped from './smartsocket.pluginstyped';
import * as interfaces from './interfaces';
// import interfaces
import { ISocketFunctionCall } from './smartsocket.classes.socketfunction';
import { ISocketRequestDataObject } from './smartsocket.classes.socketrequest';
// import classes
import { SocketConnection } from './smartsocket.classes.socketconnection';
import { SocketFunction } from './smartsocket.classes.socketfunction';
import { SocketRequest } from './smartsocket.classes.socketrequest';
import {
ISocketFunctionCallDataRequest,
SocketFunction,
} from './smartsocket.classes.socketfunction';
import { ISocketRequestDataObject, SocketRequest } from './smartsocket.classes.socketrequest';
import { SocketRole } from './smartsocket.classes.socketrole';
import { logger } from './smartsocket.logging';
/**
* interface for class SmartsocketClient
*/
@ -17,78 +20,185 @@ export interface ISmartsocketClientOptions {
alias: string; // an alias makes it easier to identify this client in a multo client environment
role: string;
password: string; // by setting a password access to functions can be limited
autoReconnect?: boolean;
}
export class SmartsocketClient {
alias: string;
role: string;
socketConnection: SocketConnection;
serverUrl: string;
serverPort: number;
serverPassword: string;
// a unique id
public shortId = plugins.isounique.uni();
// the shortId of the remote we connect to
public remoteShortId: string = null;
public alias: string;
public socketRole: SocketRole;
public socketConnection: SocketConnection;
public serverUrl: string;
public serverPort: number;
public autoReconnect: boolean;
// status handling
public eventSubject = new plugins.smartrx.rxjs.Subject<interfaces.TConnectionStatus>();
public eventStatus: interfaces.TConnectionStatus = 'new';
public socketFunctions = new plugins.lik.ObjectMap<SocketFunction<any>>();
public socketRequests = new plugins.lik.ObjectMap<SocketRequest<any>>();
public socketRoles = new plugins.lik.ObjectMap<SocketRole>();
constructor(optionsArg: ISmartsocketClientOptions) {
this.alias = optionsArg.alias;
this.role = optionsArg.role;
this.serverUrl = optionsArg.url;
this.serverPort = optionsArg.port;
this.serverPassword = optionsArg.password;
this.socketRole = new SocketRole({
name: optionsArg.role,
passwordHash: optionsArg.password,
});
this.autoReconnect = optionsArg.autoReconnect;
}
public addSocketFunction(socketFunction: SocketFunction<any>) {
this.socketFunctions.add(socketFunction);
this.socketRole.allowedFunctions.add(socketFunction);
}
/**
* connect the client to the server
*/
connect() {
let done = plugins.smartq.defer();
plugins.beautylog.log('trying to connect...');
let socketUrl = `${this.serverUrl}:${this.serverPort}`;
public async connect() {
const done = plugins.smartpromise.defer();
const smartenvInstance = new plugins.smartenv.Smartenv();
const socketIoClient = await smartenvInstance.getEnvAwareModule({
nodeModuleName: 'socket.io-client',
webUrlArg: 'https://cdn.jsdelivr.net/npm/socket.io-client@2/dist/socket.io.js',
getFunction: () => {
return globalThis.io;
},
});
logger.log('info', 'trying to connect...');
const socketUrl = `${this.serverUrl}:${this.serverPort}`;
this.socketConnection = new SocketConnection({
alias: this.alias,
authenticated: false,
role: undefined,
role: this.socketRole,
side: 'client',
smartsocketHost: null,
socket: plugins.socketIoClient(socketUrl, { multiplex: false })
smartsocketHost: this,
socket: await socketIoClient.connect(socketUrl, {
multiplex: false,
reconnectionAttempts: 5,
}),
});
this.socketConnection.socket.on('requestAuth', () => {
console.log('server requested authentication');
this.socketConnection.socket.emit('dataAuth', {
role: this.role,
password: this.serverPassword,
alias: this.alias
const timer = new plugins.smarttime.Timer(5000);
timer.start();
timer.completed.then(() => {
logger.log('warn', 'connection to server timed out.');
this.disconnect();
});
// authentication flow
this.socketConnection.socket.on(
'requestAuth',
(requestAuthPayload: interfaces.IRequestAuthPayload) => {
timer.reset();
logger.log('info', 'server requested authentication');
// lets register the authenticated event
this.socketConnection.socket.on('authenticated', () => {
console.log('client is authenticated');
this.remoteShortId = requestAuthPayload.serverShortId;
logger.log('info', 'client is authenticated');
this.socketConnection.authenticated = true;
this.socketConnection.listenToFunctionRequests();
done.resolve();
});
// lets register the forbidden event
this.socketConnection.socket.on('forbidden', async () => {
logger.log('warn', `disconnecting due to being forbidden to use the ressource`);
await this.disconnect();
});
// lets provide the actual auth data
this.socketConnection.socket.emit('dataAuth', {
role: this.socketRole.name,
password: this.socketRole.passwordHash,
alias: this.alias,
});
}
);
// handle connection
this.socketConnection.socket.on('connect', async () => {
this.updateStatus('connected');
});
// handle disconnection and errors
this.socketConnection.socket.on('disconnect', async () => {
await this.disconnect();
});
this.socketConnection.socket.on('reconnect_failed', async () => {
await this.disconnect();
});
this.socketConnection.socket.on('connect_error', async () => {
await this.disconnect();
});
return done.promise;
}
disconnect() {
let done = plugins.smartq.defer();
this.socketConnection.socket.disconnect();
/**
* disconnect from the server
*/
public async disconnect() {
if (this.socketConnection) {
await this.socketConnection.disconnect();
this.socketConnection = undefined;
plugins.beautylog.ok('disconnected!');
done.resolve();
return done.promise;
logger.log('ok', 'disconnected!');
}
logger.log('warn', `disconnected from server ${this.remoteShortId}`);
this.remoteShortId = null;
this.updateStatus('disconnected');
if (this.autoReconnect) {
this.tryDebouncedReconnect();
}
}
serverCall(functionNameArg: string, dataArg: any) {
let done = plugins.smartq.defer();
let socketRequest = new SocketRequest({
/**
* try a reconnection
*/
public async tryDebouncedReconnect() {
await plugins.smartdelay.delayForRandom(10000, 60000);
await this.connect();
}
/**
* dispatches a server call
* @param functionNameArg
* @param dataArg
*/
public async serverCall<T extends plugins.typedrequestInterfaces.ITypedRequest>(
functionNameArg: T['method'],
dataArg: T['request']
): Promise<T['response']> {
const done = plugins.smartpromise.defer();
const socketRequest = new SocketRequest<T>(this, {
side: 'requesting',
originSocketConnection: this.socketConnection,
shortId: plugins.shortid.generate(),
shortId: plugins.isounique.uni(),
funcCallData: {
funcName: functionNameArg,
funcDataArg: dataArg
}
funcDataArg: dataArg,
},
});
socketRequest.dispatch().then((dataArg: ISocketFunctionCall) => {
done.resolve(dataArg.funcDataArg);
});
return done.promise;
const response = await socketRequest.dispatch();
const result = response.funcDataArg;
return result;
}
private updateStatus(statusArg: interfaces.TConnectionStatus) {
if (this.eventStatus !== statusArg) {
this.eventSubject.next(statusArg);
}
this.eventStatus = statusArg;
}
}

View File

@ -1,20 +1,16 @@
import * as plugins from './smartsocket.plugins';
import * as helpers from './smartsocket.helpers';
import { Objectmap } from 'lik';
import * as interfaces from './interfaces';
// import classes
import { Smartsocket } from './smartsocket.classes.smartsocket';
import { SocketFunction } from './smartsocket.classes.socketfunction';
import {
SocketRequest,
ISocketRequestDataObject,
allSocketRequests
} from './smartsocket.classes.socketrequest';
import { SocketRequest, ISocketRequestDataObject } from './smartsocket.classes.socketrequest';
import { SocketRole } from './smartsocket.classes.socketrole';
// socket.io
import * as SocketIO from 'socket.io';
import { SmartsocketClient } from './smartsocket.classes.smartsocketclient';
import { logger } from './smartsocket.logging';
// export interfaces
@ -31,7 +27,7 @@ export interface ISocketConnectionConstructorOptions {
authenticated: boolean;
role: SocketRole;
side: TSocketConnectionSide;
smartsocketHost: Smartsocket;
smartsocketHost: Smartsocket | SmartsocketClient;
socket: SocketIO.Socket | SocketIOClient.Socket;
}
@ -45,33 +41,43 @@ export interface ISocketConnectionAuthenticationObject {
}
// export classes
export let allSocketConnections = new Objectmap<SocketConnection>();
export let allSocketConnections = new plugins.lik.ObjectMap<SocketConnection>();
/**
* class SocketConnection represents a websocket connection
*/
export class SocketConnection {
alias: string;
side: TSocketConnectionSide;
authenticated: boolean = false;
role: SocketRole;
smartsocketHost: Smartsocket;
socket: any; // SocketIO.Socket | SocketIOClient.Socket
public alias: string;
public side: TSocketConnectionSide;
public authenticated: boolean = false;
public role: SocketRole;
public smartsocketRef: Smartsocket | SmartsocketClient;
public socket: SocketIO.Socket | SocketIOClient.Socket;
public eventSubject = new plugins.smartrx.rxjs.Subject<interfaces.TConnectionStatus>();
public eventStatus: interfaces.TConnectionStatus = 'new';
constructor(optionsArg: ISocketConnectionConstructorOptions) {
this.alias = optionsArg.alias;
this.authenticated = optionsArg.authenticated;
this.role = optionsArg.role;
this.side = optionsArg.side;
this.smartsocketHost = optionsArg.smartsocketHost;
this.smartsocketRef = optionsArg.smartsocketHost;
this.socket = optionsArg.socket;
// standard behaviour that is always true
allSocketConnections.add(this);
this.socket.on('disconnect', () => {
plugins.beautylog.info(
// handle connection
this.socket.on('connect', async () => {
this.updateStatus('connected');
});
this.socket.on('disconnect', async () => {
logger.log(
'info',
`SocketConnection with >alias ${this.alias} on >side ${this.side} disconnected`
);
this.socket.disconnect();
await this.disconnect();
allSocketConnections.remove(this);
});
}
@ -81,28 +87,29 @@ export class SocketConnection {
/**
* authenticate the socket
*/
authenticate() {
let done = plugins.smartq.defer();
this.socket.on('dataAuth', (dataArg: ISocketConnectionAuthenticationObject) => {
plugins.beautylog.log('received authentication data. now hashing and comparing...');
public authenticate() {
const done = plugins.smartpromise.defer();
this.socket.on('dataAuth', async (dataArg: ISocketConnectionAuthenticationObject) => {
logger.log('info', 'received authentication data. now hashing and comparing...');
this.socket.removeListener('dataAuth', () => {});
if (helpers.checkPasswordForRole(dataArg, this.smartsocketHost)) {
if (await SocketRole.checkPasswordForRole(dataArg, this.smartsocketRef)) {
// TODO: authenticate password
this.alias = dataArg.alias;
this.authenticated = true;
this.role = helpers.getSocketRoleByName(dataArg.role, this.smartsocketHost);
this.role = SocketRole.getSocketRoleByName(this.smartsocketRef, dataArg.role);
this.socket.emit('authenticated');
plugins.beautylog.ok(
`socket with >>alias ${this.alias} >>role ${this.role} is authenticated!`
);
logger.log('ok', `socket with >>alias ${this.alias} >>role ${this.role} is authenticated!`);
done.resolve(this);
} else {
this.authenticated = false;
this.socket.disconnect();
await this.disconnect();
done.reject('not authenticated');
}
});
this.socket.emit('requestAuth');
const requestAuthPayload: interfaces.IRequestAuthPayload = {
serverShortId: this.smartsocketRef.shortId,
};
this.socket.emit('requestAuth', requestAuthPayload);
return done.promise;
}
@ -111,44 +118,58 @@ export class SocketConnection {
/**
* listen to function requests
*/
listenToFunctionRequests() {
let done = plugins.smartq.defer();
public listenToFunctionRequests() {
const done = plugins.smartpromise.defer();
if (this.authenticated) {
this.socket.on('function', (dataArg: ISocketRequestDataObject) => {
this.socket.on('function', (dataArg: ISocketRequestDataObject<any>) => {
// check if requested function is available to the socket's scope
plugins.beautylog.log('function request received');
let referencedFunction: SocketFunction = this.role.allowedFunctions.find(
socketFunctionArg => {
// logger.log('info', 'function request received');
const referencedFunction: SocketFunction<any> = this.role.allowedFunctions.find(
(socketFunctionArg) => {
return socketFunctionArg.name === dataArg.funcCallData.funcName;
}
);
if (referencedFunction !== undefined) {
plugins.beautylog.ok!('function in access scope');
let localSocketRequest = new SocketRequest({
if (referencedFunction) {
// logger.log('ok', 'function in access scope');
const localSocketRequest = new SocketRequest(this.smartsocketRef, {
side: 'responding',
originSocketConnection: this,
shortId: dataArg.shortId,
funcCallData: dataArg.funcCallData
funcCallData: dataArg.funcCallData,
});
localSocketRequest.createResponse(); // takes care of creating response and sending it back
} else {
plugins.beautylog.warn('function not existent or out of access scope');
logger.log('warn', 'function not existent or out of access scope');
}
});
this.socket.on('functionResponse', (dataArg: ISocketRequestDataObject) => {
plugins.beautylog.info(`received response for request with id ${dataArg.shortId}`);
let targetSocketRequest = helpers.getSocketRequestById(dataArg.shortId);
this.socket.on('functionResponse', (dataArg: ISocketRequestDataObject<any>) => {
logger.log('info', `received response for request with id ${dataArg.shortId}`);
const targetSocketRequest = SocketRequest.getSocketRequestById(
this.smartsocketRef,
dataArg.shortId
);
targetSocketRequest.handleResponse(dataArg);
});
plugins.beautylog.log(`now listening to function requests for ${this.alias}`);
logger.log('info', `now listening to function requests for ${this.alias}`);
done.resolve(this);
} else {
let errMessage: 'socket needs to be authenticated first';
plugins.beautylog.error(errMessage);
const errMessage = 'socket needs to be authenticated first';
logger.log('error', errMessage);
done.reject(errMessage);
}
return done.promise;
}
// sending ----------------------
// disconnecting ----------------------
public async disconnect() {
this.socket.disconnect(true);
this.updateStatus('disconnected');
}
private updateStatus(statusArg: interfaces.TConnectionStatus) {
if (this.eventStatus !== statusArg) {
this.eventSubject.next(statusArg);
}
this.eventStatus = statusArg;
}
}

View File

@ -1,78 +1,101 @@
import * as plugins from './smartsocket.plugins';
// import classes
import { Objectmap } from 'lik';
import { SocketRole } from './smartsocket.classes.socketrole';
import { SocketConnection } from './smartsocket.classes.socketconnection';
import { Smartsocket } from './smartsocket.classes.smartsocket';
import { SmartsocketClient } from './smartsocket.classes.smartsocketclient';
// export interfaces
/**
* interface of the contructor options of class SocketFunction
*/
export interface ISocketFunctionConstructorOptions {
funcName: string;
funcDef: any;
export interface ISocketFunctionConstructorOptions<
T extends plugins.typedrequestInterfaces.ITypedRequest
> {
funcName: T['method'];
funcDef: TFuncDef<T>;
allowedRoles: SocketRole[]; // all roles that are allowed to execute a SocketFunction
}
/**
* interface of the Socket Function call, in other words the object that routes a call to a function
*/
export interface ISocketFunctionCall {
funcName: string;
funcDataArg: any;
export interface ISocketFunctionCallDataRequest<
T extends plugins.typedrequestInterfaces.ITypedRequest
> {
funcName: T['method'];
funcDataArg: T['request'];
}
/**
* interface of the Socket Function call, in other words the object that routes a call to a function
*/
export interface ISocketFunctionCallDataResponse<
T extends plugins.typedrequestInterfaces.ITypedRequest
> {
funcName: T['method'];
funcDataArg: T['response'];
}
/**
* interface for function definition of SocketFunction
*/
export interface IFuncDef {
(dataArg: any): PromiseLike<any>;
}
// export objects
export let allSocketFunctions = new Objectmap<SocketFunction>();
export type TFuncDef<T extends plugins.typedrequestInterfaces.ITypedRequest> = (
dataArg: T['request'],
connectionArg: SocketConnection
) => PromiseLike<T['response']>;
// export classes
/**
* class that respresents a function that can be transparently called using a SocketConnection
*/
export class SocketFunction {
name: string;
funcDef: IFuncDef;
roles: SocketRole[];
export class SocketFunction<T extends plugins.typedrequestInterfaces.ITypedRequest> {
// STATIC
public static getSocketFunctionByName<Q extends plugins.typedrequestInterfaces.ITypedRequest>(
smartsocketRefArg: Smartsocket | SmartsocketClient,
functionNameArg: string
): SocketFunction<Q> {
return smartsocketRefArg.socketFunctions.find((socketFunctionArg) => {
return socketFunctionArg.name === functionNameArg;
});
}
// INSTANCE
public name: string;
public funcDef: TFuncDef<T>;
public roles: SocketRole[];
/**
* the constructor for SocketFunction
*/
constructor(optionsArg: ISocketFunctionConstructorOptions) {
constructor(optionsArg: ISocketFunctionConstructorOptions<T>) {
this.name = optionsArg.funcName;
this.funcDef = optionsArg.funcDef;
this.roles = optionsArg.allowedRoles;
for (let socketRoleArg of this.roles) {
for (const socketRoleArg of this.roles) {
this._notifyRole(socketRoleArg);
}
allSocketFunctions.add(this); // map instance with Objectmap
}
/**
* invokes the function of this SocketFunction
*/
invoke(dataArg: ISocketFunctionCall): Promise<any> {
let done = plugins.smartq.defer();
public async invoke(
dataArg: ISocketFunctionCallDataRequest<T>,
socketConnectionArg: SocketConnection
): Promise<ISocketFunctionCallDataResponse<T>> {
if (dataArg.funcName === this.name) {
this.funcDef(dataArg.funcDataArg).then((resultData: any) => {
let funcResponseData: ISocketFunctionCall = {
const funcResponseData: ISocketFunctionCallDataResponse<T> = {
funcName: this.name,
funcDataArg: resultData
funcDataArg: await this.funcDef(dataArg.funcDataArg, socketConnectionArg),
};
done.resolve(funcResponseData);
});
return funcResponseData;
} else {
throw new Error("SocketFunction.name does not match the data argument's .name!");
}
return done.promise;
}
/**

View File

@ -1,13 +1,17 @@
import * as plugins from './smartsocket.plugins';
import * as helpers from './smartsocket.helpers';
// import interfaces
import { ISocketFunctionCall } from './smartsocket.classes.socketfunction';
import {
SocketFunction,
ISocketFunctionCallDataRequest,
ISocketFunctionCallDataResponse,
} from './smartsocket.classes.socketfunction';
// import classes
import { Objectmap } from 'lik';
import { SocketFunction } from './smartsocket.classes.socketfunction';
import { SocketConnection } from './smartsocket.classes.socketconnection';
import { logger } from './smartsocket.logging';
import { Smartsocket } from './smartsocket.classes.smartsocket';
import { SmartsocketClient } from './smartsocket.classes.smartsocketclient';
// export interfaces
export type TSocketRequestStatus = 'new' | 'pending' | 'finished';
@ -16,39 +20,56 @@ export type TSocketRequestSide = 'requesting' | 'responding';
/**
* interface of constructor of class SocketRequest
*/
export interface SocketRequestConstructorOptions {
export interface ISocketRequestConstructorOptions<
T extends plugins.typedrequestInterfaces.ITypedRequest
> {
side: TSocketRequestSide;
originSocketConnection: SocketConnection;
shortId: string;
funcCallData?: ISocketFunctionCall;
funcCallData?: ISocketFunctionCallDataRequest<T>;
}
/**
* request object that is sent initially and may or may not receive a response
*/
export interface ISocketRequestDataObject {
funcCallData: ISocketFunctionCall;
export interface ISocketRequestDataObject<T extends plugins.typedrequestInterfaces.ITypedRequest> {
funcCallData: ISocketFunctionCallDataRequest<T> | ISocketFunctionCallDataResponse<T>;
shortId: string;
responseTimeout?: number;
}
// export objects
export let allSocketRequests = new Objectmap<SocketRequest>();
// export classes
export class SocketRequest {
status: TSocketRequestStatus = 'new';
side: TSocketRequestSide;
shortid: string;
originSocketConnection: SocketConnection;
funcCallData: ISocketFunctionCall;
done = plugins.smartq.defer();
constructor(optionsArg: SocketRequestConstructorOptions) {
export class SocketRequest<T extends plugins.typedrequestInterfaces.ITypedRequest> {
// STATIC
public static getSocketRequestById(
smartsocketRef: Smartsocket | SmartsocketClient,
shortIdArg: string
): SocketRequest<any> {
return smartsocketRef.socketRequests.find((socketRequestArg) => {
return socketRequestArg.shortid === shortIdArg;
});
}
// INSTANCE
public status: TSocketRequestStatus = 'new';
public side: TSocketRequestSide;
public shortid: string;
public originSocketConnection: SocketConnection;
public funcCallData: ISocketFunctionCallDataRequest<T>;
public done = plugins.smartpromise.defer<ISocketFunctionCallDataResponse<T>>();
public smartsocketRef: Smartsocket | SmartsocketClient;
constructor(
smartsocketRefArg: Smartsocket | SmartsocketClient,
optionsArg: ISocketRequestConstructorOptions<T>
) {
this.smartsocketRef = smartsocketRefArg;
this.side = optionsArg.side;
this.shortid = optionsArg.shortId;
this.funcCallData = optionsArg.funcCallData;
this.originSocketConnection = optionsArg.originSocketConnection;
allSocketRequests.add(this);
this.smartsocketRef.socketRequests.add(this);
}
// requesting --------------------------
@ -56,10 +77,10 @@ export class SocketRequest {
/**
* dispatches a socketrequest from the requesting to the receiving side
*/
dispatch() {
let requestData: ISocketRequestDataObject = {
public dispatch(): Promise<ISocketFunctionCallDataResponse<T>> {
const requestData: ISocketRequestDataObject<T> = {
funcCallData: this.funcCallData,
shortId: this.shortid
shortId: this.shortid,
};
this.originSocketConnection.socket.emit('function', requestData);
return this.done.promise;
@ -68,10 +89,10 @@ export class SocketRequest {
/**
* handles the response that is received by the requesting side
*/
handleResponse(responseDataArg: ISocketRequestDataObject) {
plugins.beautylog.log('handling response!');
public async handleResponse(responseDataArg: ISocketRequestDataObject<T>) {
logger.log('info', 'handling response!');
this.done.resolve(responseDataArg.funcCallData);
allSocketRequests.remove(this);
this.smartsocketRef.socketRequests.remove(this);
}
// responding --------------------------
@ -79,19 +100,27 @@ export class SocketRequest {
/**
* creates the response on the responding side
*/
createResponse() {
let targetSocketFunction: SocketFunction = helpers.getSocketFunctionByName(
public async createResponse(): Promise<void> {
const targetSocketFunction: SocketFunction<T> = SocketFunction.getSocketFunctionByName(
this.smartsocketRef,
this.funcCallData.funcName
);
plugins.beautylog.info(`invoking ${targetSocketFunction.name}`);
targetSocketFunction.invoke(this.funcCallData).then(resultData => {
plugins.beautylog.log('got resultData. Sending it to requesting party.');
let requestData: ISocketRequestDataObject = {
if (!targetSocketFunction) {
logger.log('error', `There is no SocketFunction defined for ${this.funcCallData.funcName}`);
return;
}
logger.log('info', `invoking ${targetSocketFunction.name}`);
targetSocketFunction
.invoke(this.funcCallData, this.originSocketConnection)
.then((resultData) => {
logger.log('info', 'got resultData. Sending it to requesting party.');
const responseData: ISocketRequestDataObject<T> = {
funcCallData: resultData,
shortId: this.shortid
shortId: this.shortid,
};
this.originSocketConnection.socket.emit('functionResponse', requestData);
allSocketRequests.remove(this);
this.originSocketConnection.socket.emit('functionResponse', responseData);
this.smartsocketRef.socketRequests.remove(this);
});
}
}

View File

@ -1,13 +1,15 @@
import * as plugins from './smartsocket.plugins';
// import classes
import { Objectmap } from 'lik';
import { SocketFunction } from './smartsocket.classes.socketfunction';
import { Smartsocket } from './smartsocket.classes.smartsocket';
import { SmartsocketClient } from './smartsocket.classes.smartsocketclient';
import { ISocketConnectionAuthenticationObject } from './smartsocket.classes.socketconnection';
/**
* interface for class SocketRole
*/
export interface SocketRoleOptions {
export interface ISocketRoleOptions {
name: string;
passwordHash: string;
}
@ -16,14 +18,40 @@ export interface SocketRoleOptions {
* A socketrole defines access to certain routines.
*/
export class SocketRole {
name: string;
passwordHash: string;
allowedFunctions = new Objectmap<SocketFunction>();
constructor(optionsArg: SocketRoleOptions) {
// STATIC
public static getSocketRoleByName(
referenceSmartsocket: Smartsocket | SmartsocketClient,
socketRoleNameArg: string
): SocketRole {
return referenceSmartsocket.socketRoles.find((socketRoleArg) => {
return socketRoleArg.name === socketRoleNameArg;
});
}
public static async checkPasswordForRole(
dataArg: ISocketConnectionAuthenticationObject,
referenceSmartsocket: Smartsocket | SmartsocketClient
): Promise<boolean> {
const targetPasswordHash = SocketRole.getSocketRoleByName(referenceSmartsocket, dataArg.role)
.passwordHash;
const computedCompareHash = await plugins.isohash.sha256FromString(dataArg.password);
return targetPasswordHash === computedCompareHash;
}
// INSTANCE
public name: string;
public passwordHash: string;
public allowedFunctions = new plugins.lik.ObjectMap<SocketFunction<any>>();
constructor(optionsArg: ISocketRoleOptions) {
this.name = optionsArg.name;
this.passwordHash = optionsArg.passwordHash;
}
addSocketFunction(socketFunctionArg: SocketFunction) {
/**
* adds the socketfunction to the socketrole
* @param socketFunctionArg
*/
public addSocketFunction(socketFunctionArg: SocketFunction<any>) {
this.allowedFunctions.add(socketFunctionArg);
}
}

View File

@ -0,0 +1,82 @@
import * as plugins from './smartsocket.plugins';
import * as pluginsTyped from './smartsocket.pluginstyped';
// used in case no other server is supplied
import { Smartsocket } from './smartsocket.classes.smartsocket';
import { logger } from './smartsocket.logging';
/**
* class socketServer
* handles the attachment of socketIo to whatever server is in play
*/
export class SocketServer {
private smartsocket: Smartsocket;
private httpServer: pluginsTyped.http.Server | pluginsTyped.https.Server;
// wether httpServer is standalone
private standaloneServer = false;
private expressServer: any;
constructor(smartSocketInstance: Smartsocket) {
this.smartsocket = smartSocketInstance;
}
/**
* starts the server with another server
* also works with an express style server
*/
public async setExternalServer(
serverType: 'smartexpress',
serverArg: pluginsTyped.smartexpress.Server
) {
await serverArg.startedPromise;
this.httpServer = serverArg.httpServer;
}
/**
* gets the server for socket.io
*/
public getServerForSocketIo() {
if (this.httpServer) {
return this.httpServer;
} else {
const httpModule = this.smartsocket.smartenv.getSafeNodeModule('http');
this.httpServer = new httpModule.Server();
this.standaloneServer = true;
return this.httpServer;
}
}
/**
* starts listening to incoming sockets:
*/
public async start() {
const done = plugins.smartpromise.defer();
// handle http servers
// in case an external server has been set "this.standaloneServer" should be false
if (this.httpServer && this.standaloneServer) {
if (!this.smartsocket.options.port) {
logger.log('error', 'there should be a port specifed for smartsocket!');
throw new Error('there should be a port specified for smartsocket');
}
this.httpServer.listen(this.smartsocket.options.port, () => {
logger.log(
'success',
`Server started in standalone mode on ${this.smartsocket.options.port}`
);
done.resolve();
});
} else {
done.resolve();
}
// nothing else to do if express server is set
await done.promise;
return;
}
/**
* closes the server
*/
public async stop() {}
}

View File

@ -0,0 +1,3 @@
import * as plugins from './smartsocket.plugins';
export class SocketStats {}

View File

@ -1,60 +0,0 @@
import * as plugins from './smartsocket.plugins';
// classes
import { Smartsocket } from './smartsocket.classes.smartsocket';
import { SocketFunction, allSocketFunctions } from './smartsocket.classes.socketfunction';
import {
SocketConnection,
ISocketConnectionAuthenticationObject
} from './smartsocket.classes.socketconnection';
import {
SocketRequest,
allSocketRequests,
TSocketRequestSide
} from './smartsocket.classes.socketrequest';
import { SocketRole } from './smartsocket.classes.socketrole';
// SocketConnection helpers
export let checkPasswordForRole = (
dataArg: ISocketConnectionAuthenticationObject,
referenceSmartsocket: Smartsocket
): boolean => {
let targetPasswordHash = getSocketRoleByName(dataArg.role, referenceSmartsocket).passwordHash;
let computedCompareHash = plugins.nodehash.sha256FromStringSync(dataArg.password);
return targetPasswordHash === computedCompareHash;
};
// SocketFunction helpers
export let getSocketFunctionByName = (functionNameArg: string): SocketFunction => {
return allSocketFunctions.find(socketFunctionArg => {
return socketFunctionArg.name === functionNameArg;
});
};
// SocketRequest helpers
/**
* get corresponding Socketrequest instance by shortId
*/
export let getSocketRequestById = (
shortIdArg: string,
requestSide?: TSocketRequestSide
): SocketRequest => {
return allSocketRequests.find(socketRequestArg => {
return socketRequestArg.shortid === shortIdArg;
});
};
// SocketRole helpers
/**
* get corresponding SocketRole instance by name
*/
export let getSocketRoleByName = (
socketRoleNameArg: string,
referenceSmartsocket: Smartsocket
): SocketRole => {
return referenceSmartsocket.socketRoles.find(socketRoleArg => {
return socketRoleArg.name === socketRoleNameArg;
});
};

View File

@ -0,0 +1,3 @@
import * as plugins from './smartsocket.plugins';
export const logger = new plugins.smartlog.ConsoleLog();

View File

@ -1,8 +1,27 @@
export import beautylog = require('beautylog');
export import lik = require('lik');
export import nodehash = require('nodehash');
export import smartdelay = require('smartdelay');
export import smartq = require('smartq');
export import shortid = require('shortid');
export import socketIo = require('socket.io');
export import socketIoClient = require('socket.io-client');
// apiglobal scope
import * as typedrequestInterfaces from '@apiglobal/typedrequest-interfaces';
export { typedrequestInterfaces };
// pushrocks scope
import * as isohash from '@pushrocks/isohash';
import * as isounique from '@pushrocks/isounique';
import * as lik from '@pushrocks/lik';
import * as smartenv from '@pushrocks/smartenv';
import * as smartlog from '@pushrocks/smartlog';
import * as smartdelay from '@pushrocks/smartdelay';
import * as smartpromise from '@pushrocks/smartpromise';
import * as smarttime from '@pushrocks/smarttime';
import * as smartrx from '@pushrocks/smartrx';
export {
isohash,
isounique,
lik,
smartenv,
smartlog,
smartdelay,
smartpromise,
smarttime,
smartrx,
};

View File

@ -0,0 +1,16 @@
// node native
import type http from 'http';
import type https from 'https';
export { http, https };
// pushrocks scope
import type * as smartexpress from '@pushrocks/smartexpress';
export { smartexpress };
// third party scope
import type socketIo from 'socket.io';
import type socketIoClient from 'socket.io-client';
export { socketIo, socketIoClient };

View File

@ -1,3 +1,17 @@
{
"extends": "tslint-config-standard"
"extends": ["tslint:latest", "tslint-config-prettier"],
"rules": {
"semicolon": [true, "always"],
"no-console": false,
"ordered-imports": false,
"object-literal-sort-keys": false,
"member-ordering": {
"options":{
"order": [
"static-method"
]
}
}
},
"defaultSeverity": "warning"
}

729
yarn.lock
View File

@ -1,729 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@types/chai-as-promised@^7.1.0":
version "7.1.0"
resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.0.tgz#010b04cde78eacfb6e72bfddb3e58fe23c2e78b9"
dependencies:
"@types/chai" "*"
"@types/chai-string@^1.4.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@types/chai-string/-/chai-string-1.4.0.tgz#c8b78deb9ae53e86c05a446c256138faeaff53c1"
dependencies:
"@types/chai" "*"
"@types/chai@*", "@types/chai@^4.1.2":
version "4.1.2"
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.2.tgz#f1af664769cfb50af805431c407425ed619daa21"
"@types/lodash@^4.14.55", "@types/lodash@^4.14.97":
version "4.14.104"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.104.tgz#53ee2357fa2e6e68379341d92eb2ecea4b11bb80"
"@types/minimatch@^3.0.3":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
"@types/node@*":
version "9.4.7"
resolved "https://registry.yarnpkg.com/@types/node/-/node-9.4.7.tgz#57d81cd98719df2c9de118f2d5f3b1120dcd7275"
"@types/q@0.x.x":
version "0.0.37"
resolved "https://registry.yarnpkg.com/@types/q/-/q-0.0.37.tgz#7d6a934b35ee2f0ed0646d286eba559599021c9e"
"@types/shortid@0.0.29":
version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/shortid/-/shortid-0.0.29.tgz#8093ee0416a6e2bf2aa6338109114b3fbffa0e9b"
"@types/socket.io-client@^1.4.32":
version "1.4.32"
resolved "https://registry.yarnpkg.com/@types/socket.io-client/-/socket.io-client-1.4.32.tgz#988a65a0386c274b1c22a55377fab6a30789ac14"
"@types/socket.io@^1.4.32":
version "1.4.32"
resolved "https://registry.yarnpkg.com/@types/socket.io/-/socket.io-1.4.32.tgz#bf7bc4ea6991327f31672c05e237a8a28d7bfc30"
dependencies:
"@types/node" "*"
"@types/through2@0.x.x":
version "0.4.1"
resolved "https://registry.yarnpkg.com/@types/through2/-/through2-0.4.1.tgz#0f008e174c1dc5f1cc7e00eb2d132b2cb67f7bd2"
dependencies:
"@types/node" "*"
accepts@~1.3.4:
version "1.3.5"
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2"
dependencies:
mime-types "~2.1.18"
negotiator "0.6.1"
after@0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
ansi-256-colors@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/ansi-256-colors/-/ansi-256-colors-1.1.0.tgz#910de50efcc7c09e3d82f2f87abd6b700c18818a"
ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
dependencies:
color-convert "^1.9.0"
arraybuffer.slice@~0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675"
assertion-error@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b"
async-limiter@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8"
backo2@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947"
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
base64-arraybuffer@0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8"
base64id@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6"
beautycolor@^1.0.7:
version "1.0.11"
resolved "https://registry.yarnpkg.com/beautycolor/-/beautycolor-1.0.11.tgz#71c5568d5a7ed5c144d3a54f753ad1b08862aea5"
dependencies:
ansi-256-colors "^1.1.0"
typings-global "^1.0.14"
beautylog@^6.1.10:
version "6.1.10"
resolved "https://registry.yarnpkg.com/beautylog/-/beautylog-6.1.10.tgz#9c27e566937684cb689f9372d98cfa5415d50b72"
dependencies:
"@types/lodash" "^4.14.55"
beautycolor "^1.0.7"
figlet "^1.2.0"
lodash "^4.17.4"
ora "^1.1.0"
smartenv "^2.0.0"
smartq "^1.1.1"
typings-global "^1.0.14"
better-assert@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522"
dependencies:
callsite "1.0.0"
bindings@^1.2.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.0.tgz#b346f6ecf6a95f5a815c5839fc7cdb22502f1ed7"
blob@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.4.tgz#bcf13052ca54463f30f9fc7e95b9a47630a94921"
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
callsite@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20"
chai-as-promised@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0"
dependencies:
check-error "^1.0.2"
chai-string@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/chai-string/-/chai-string-1.4.0.tgz#359140c051d36a4e4b1a5fc6b910152f438a8d49"
chai@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/chai/-/chai-4.1.2.tgz#0f64584ba642f0f2ace2806279f4f06ca23ad73c"
dependencies:
assertion-error "^1.0.1"
check-error "^1.0.1"
deep-eql "^3.0.0"
get-func-name "^2.0.0"
pathval "^1.0.0"
type-detect "^4.0.0"
chalk@^2.0.1, chalk@^2.1.0:
version "2.3.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65"
dependencies:
ansi-styles "^3.2.1"
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
check-error@^1.0.1, check-error@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
cli-cursor@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
dependencies:
restore-cursor "^2.0.0"
cli-spinners@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.1.0.tgz#f1847b168844d917a671eb9d147e3df497c90d06"
color-convert@^1.9.0:
version "1.9.1"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed"
dependencies:
color-name "^1.1.1"
color-name@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
component-bind@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1"
component-emitter@1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
component-inherit@0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
cookie@0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
debug@~2.6.4, debug@~2.6.6:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
dependencies:
ms "2.0.0"
debug@~3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
dependencies:
ms "2.0.0"
deep-eql@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df"
dependencies:
type-detect "^4.0.0"
define-properties@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94"
dependencies:
foreach "^2.0.5"
object-keys "^1.0.8"
early@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/early/-/early-2.1.1.tgz#841e23254ea5dc54d8afaeee82f5ab65c00ee23c"
dependencies:
beautycolor "^1.0.7"
smartq "^1.1.1"
typings-global "^1.0.16"
engine.io-client@~3.1.0:
version "3.1.6"
resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.1.6.tgz#5bdeb130f8b94a50ac5cbeb72583e7a4a063ddfd"
dependencies:
component-emitter "1.2.1"
component-inherit "0.0.3"
debug "~3.1.0"
engine.io-parser "~2.1.1"
has-cors "1.1.0"
indexof "0.0.1"
parseqs "0.0.5"
parseuri "0.0.5"
ws "~3.3.1"
xmlhttprequest-ssl "~1.5.4"
yeast "0.1.2"
engine.io-parser@~2.1.0, engine.io-parser@~2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.1.2.tgz#4c0f4cff79aaeecbbdcfdea66a823c6085409196"
dependencies:
after "0.8.2"
arraybuffer.slice "~0.0.7"
base64-arraybuffer "0.1.5"
blob "0.0.4"
has-binary2 "~1.0.2"
engine.io@~3.1.0:
version "3.1.5"
resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.1.5.tgz#0e7ef9d690eb0b35597f1d4ad02a26ca2dba3845"
dependencies:
accepts "~1.3.4"
base64id "1.0.0"
cookie "0.3.1"
debug "~3.1.0"
engine.io-parser "~2.1.0"
ws "~3.3.1"
optionalDependencies:
uws "~9.14.0"
es-abstract@^1.5.1:
version "1.10.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864"
dependencies:
es-to-primitive "^1.1.1"
function-bind "^1.1.1"
has "^1.0.1"
is-callable "^1.1.3"
is-regex "^1.0.4"
es-to-primitive@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d"
dependencies:
is-callable "^1.1.1"
is-date-object "^1.0.1"
is-symbol "^1.0.1"
es6-error@^4.0.2:
version "4.1.1"
resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
escape-string-regexp@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
figlet@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/figlet/-/figlet-1.2.0.tgz#6c46537378fab649146b5a6143dda019b430b410"
foreach@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
function-bind@^1.0.2, function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
get-func-name@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
has-binary2@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.2.tgz#e83dba49f0b9be4d026d27365350d9f03f54be98"
dependencies:
isarray "2.0.1"
has-cors@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39"
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
has@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28"
dependencies:
function-bind "^1.0.2"
indexof@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d"
inherits@~2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
is-callable@^1.1.1, is-callable@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2"
is-date-object@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16"
is-regex@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
dependencies:
has "^1.0.1"
is-symbol@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572"
isarray@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e"
isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
leakage@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/leakage/-/leakage-0.3.0.tgz#15d698abdc76bbc6439601f4f3020e77e2d50c39"
dependencies:
es6-error "^4.0.2"
left-pad "^1.1.3"
memwatch-next "^0.3.0"
minimist "^1.2.0"
pretty-bytes "^4.0.2"
left-pad@^1.1.3:
version "1.2.0"
resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.2.0.tgz#d30a73c6b8201d8f7d8e7956ba9616087a68e0ee"
lik@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/lik/-/lik-2.0.5.tgz#1338a3201828b557fa91a5b8a6013743ff720e10"
dependencies:
"@types/lodash" "^4.14.97"
"@types/minimatch" "^3.0.3"
lodash "^4.17.4"
minimatch "^3.0.4"
smartq "^1.1.6"
symbol-tree "^3.2.2"
lodash@^4.17.4:
version "4.17.5"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511"
log-symbols@^2.1.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a"
dependencies:
chalk "^2.0.1"
memwatch-next@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/memwatch-next/-/memwatch-next-0.3.0.tgz#2111050f9a906e0aa2d72a4ec0f0089c78726f8f"
dependencies:
bindings "^1.2.1"
nan "^2.3.2"
mime-db@~1.33.0:
version "1.33.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db"
mime-types@~2.1.18:
version "2.1.18"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8"
dependencies:
mime-db "~1.33.0"
mimic-fn@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
dependencies:
brace-expansion "^1.1.7"
minimist@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
nan@^2.3.2:
version "2.9.2"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.9.2.tgz#f564d75f5f8f36a6d9456cca7a6c4fe488ab7866"
negotiator@0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
nodehash@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/nodehash/-/nodehash-1.0.4.tgz#fd733397a0925b9b4bc19726f3c0e68850206e7f"
dependencies:
"@types/q" "0.x.x"
"@types/through2" "0.x.x"
q "^1.4.1"
through2 "^2.0.1"
typings-global "^1.0.6"
object-component@0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291"
object-keys@^1.0.8:
version "1.0.11"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d"
object.getownpropertydescriptors@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16"
dependencies:
define-properties "^1.1.2"
es-abstract "^1.5.1"
onetime@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
dependencies:
mimic-fn "^1.0.0"
ora@^1.1.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/ora/-/ora-1.4.0.tgz#884458215b3a5d4097592285f93321bb7a79e2e5"
dependencies:
chalk "^2.1.0"
cli-cursor "^2.1.0"
cli-spinners "^1.0.1"
log-symbols "^2.1.0"
parseqs@0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d"
dependencies:
better-assert "~1.0.0"
parseuri@0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a"
dependencies:
better-assert "~1.0.0"
pathval@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0"
pretty-bytes@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9"
process-nextick-args@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
q@^1.4.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
readable-stream@^2.1.5:
version "2.3.5"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.5.tgz#b4f85003a938cbb6ecbce2a124fb1012bd1a838d"
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.3"
isarray "~1.0.0"
process-nextick-args "~2.0.0"
safe-buffer "~5.1.1"
string_decoder "~1.0.3"
util-deprecate "~1.0.1"
restore-cursor@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
dependencies:
onetime "^2.0.0"
signal-exit "^3.0.2"
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
shortid@^2.2.8:
version "2.2.8"
resolved "https://registry.yarnpkg.com/shortid/-/shortid-2.2.8.tgz#033b117d6a2e975804f6f0969dbe7d3d0b355131"
signal-exit@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
smartchai@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/smartchai/-/smartchai-2.0.1.tgz#d20f17221f0e3c6c3473600b78ddfba0ab0ea762"
dependencies:
"@types/chai" "^4.1.2"
"@types/chai-as-promised" "^7.1.0"
"@types/chai-string" "^1.4.0"
chai "^4.1.2"
chai-as-promised "^7.1.1"
chai-string "^1.4.0"
smartdelay@^1.0.3, smartdelay@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/smartdelay/-/smartdelay-1.0.4.tgz#791c1a4ee6770494064c10b1d2d2b8e6f3105b82"
dependencies:
smartq "^1.1.1"
typings-global "^1.0.16"
smartenv@^2.0.0:
version "2.0.6"
resolved "https://registry.yarnpkg.com/smartenv/-/smartenv-2.0.6.tgz#b38c679b0c151b9af548f68c3a072c29d1417e8d"
dependencies:
lodash "^4.17.4"
smartq "^1.1.1"
typings-global "^1.0.14"
smartq@^1.1.1, smartq@^1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/smartq/-/smartq-1.1.6.tgz#0c1ff4336d95e95b4f1fdd8ccd7e2c5a323b8412"
dependencies:
typings-global "^1.0.19"
util.promisify "^1.0.0"
socket.io-adapter@~1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz#2a805e8a14d6372124dd9159ad4502f8cb07f06b"
socket.io-client@2.0.4, socket.io-client@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.0.4.tgz#0918a552406dc5e540b380dcd97afc4a64332f8e"
dependencies:
backo2 "1.0.2"
base64-arraybuffer "0.1.5"
component-bind "1.0.0"
component-emitter "1.2.1"
debug "~2.6.4"
engine.io-client "~3.1.0"
has-cors "1.1.0"
indexof "0.0.1"
object-component "0.0.3"
parseqs "0.0.5"
parseuri "0.0.5"
socket.io-parser "~3.1.1"
to-array "0.1.4"
socket.io-parser@~3.1.1:
version "3.1.3"
resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.1.3.tgz#ed2da5ee79f10955036e3da413bfd7f1e4d86c8e"
dependencies:
component-emitter "1.2.1"
debug "~3.1.0"
has-binary2 "~1.0.2"
isarray "2.0.1"
socket.io@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.0.4.tgz#c1a4590ceff87ecf13c72652f046f716b29e6014"
dependencies:
debug "~2.6.6"
engine.io "~3.1.0"
socket.io-adapter "~1.1.0"
socket.io-client "2.0.4"
socket.io-parser "~3.1.1"
string_decoder@~1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab"
dependencies:
safe-buffer "~5.1.0"
supports-color@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0"
dependencies:
has-flag "^3.0.0"
symbol-tree@^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"
tapbundle@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/tapbundle/-/tapbundle-2.0.0.tgz#79fce68ff185c786fabaf6eb589a4afc7d2714b7"
dependencies:
early "^2.1.1"
leakage "^0.3.0"
smartchai "^2.0.0"
smartdelay "^1.0.3"
smartq "^1.1.1"
through2@^2.0.1:
version "2.0.3"
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be"
dependencies:
readable-stream "^2.1.5"
xtend "~4.0.1"
to-array@0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890"
type-detect@^4.0.0:
version "4.0.8"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
typings-global@^1.0.14, typings-global@^1.0.16, typings-global@^1.0.19, typings-global@^1.0.6:
version "1.0.28"
resolved "https://registry.yarnpkg.com/typings-global/-/typings-global-1.0.28.tgz#e28cc965476564cbc00e438739e0aa0735d323d4"
ultron@~1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c"
util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
util.promisify@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030"
dependencies:
define-properties "^1.1.2"
object.getownpropertydescriptors "^2.0.3"
uws@~9.14.0:
version "9.14.0"
resolved "https://registry.yarnpkg.com/uws/-/uws-9.14.0.tgz#fac8386befc33a7a3705cbd58dc47b430ca4dd95"
ws@~3.3.1:
version "3.3.3"
resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2"
dependencies:
async-limiter "~1.0.0"
safe-buffer "~5.1.0"
ultron "~1.1.0"
xmlhttprequest-ssl@~1.5.4:
version "1.5.5"
resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e"
xtend@~4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
yeast@0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"