diff --git a/packages/@jsonql/vue/.gitignore b/packages/@jsonql/vue/.gitignore deleted file mode 100644 index a0dddc6fb8c6b3feeeffa6e29bedca338e483382..0000000000000000000000000000000000000000 --- a/packages/@jsonql/vue/.gitignore +++ /dev/null @@ -1,21 +0,0 @@ -.DS_Store -node_modules -/dist - -# local env files -.env.local -.env.*.local - -# Log files -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Editor directories and files -.idea -.vscode -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? diff --git a/packages/@jsonql/vue/README.md b/packages/@jsonql/vue/README.md deleted file mode 100644 index 608344471daca7744a433a6075935c038dfa228c..0000000000000000000000000000000000000000 --- a/packages/@jsonql/vue/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# vue - -## Project setup -``` -npm install -``` - -### Compiles and hot-reloads for development -``` -npm run serve -``` - -### Compiles and minifies for production -``` -npm run build -``` - -### Run your tests -``` -npm run test -``` - -### Lints and fixes files -``` -npm run lint -``` - -### Customize configuration -See [Configuration Reference](https://cli.vuejs.org/config/). diff --git a/packages/@jsonql/vue/babel.config.js b/packages/@jsonql/vue/babel.config.js deleted file mode 100644 index ba179669a123909a9728283fd9c004c65adb90c5..0000000000000000000000000000000000000000 --- a/packages/@jsonql/vue/babel.config.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - presets: [ - '@vue/app' - ] -} diff --git a/packages/@jsonql/vue/package.json b/packages/@jsonql/vue/package.json deleted file mode 100644 index c04e5a8eb7b3673d51a1d84a229223dbdcd92e04..0000000000000000000000000000000000000000 --- a/packages/@jsonql/vue/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "vue", - "version": "0.1.0", - "private": true, - "scripts": { - "serve": "vue-cli-service serve", - "build": "vue-cli-service build", - "lint": "vue-cli-service lint" - }, - "dependencies": { - "core-js": "^2.6.5", - "vue": "^2.6.10" - }, - "devDependencies": { - "@vue/cli-plugin-babel": "^3.11.0", - "@vue/cli-plugin-eslint": "^3.11.0", - "@vue/cli-service": "^3.11.0", - "babel-eslint": "^10.0.1", - "eslint": "^5.16.0", - "eslint-plugin-vue": "^5.0.0", - "vue-template-compiler": "^2.6.10" - }, - "eslintConfig": { - "root": true, - "env": { - "node": true - }, - "extends": [ - "plugin:vue/essential", - "eslint:recommended" - ], - "rules": {}, - "parserOptions": { - "parser": "babel-eslint" - } - }, - "postcss": { - "plugins": { - "autoprefixer": {} - } - }, - "browserslist": [ - "> 1%", - "last 2 versions" - ], - "homepage": "jsonql.org" -} diff --git a/packages/@jsonql/vue/public/favicon.ico b/packages/@jsonql/vue/public/favicon.ico deleted file mode 100644 index df36fcfb72584e00488330b560ebcf34a41c64c2..0000000000000000000000000000000000000000 Binary files a/packages/@jsonql/vue/public/favicon.ico and /dev/null differ diff --git a/packages/@jsonql/vue/public/index.html b/packages/@jsonql/vue/public/index.html deleted file mode 100644 index eac2e22b5d5bb3d10eec97faf17dc731147bd5db..0000000000000000000000000000000000000000 --- a/packages/@jsonql/vue/public/index.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - vue - - - -
- - - diff --git a/packages/@jsonql/vue/src/App.vue b/packages/@jsonql/vue/src/App.vue deleted file mode 100644 index fcc566279aef926ce288d41de2fd4d841a400705..0000000000000000000000000000000000000000 --- a/packages/@jsonql/vue/src/App.vue +++ /dev/null @@ -1,28 +0,0 @@ - - - - - diff --git a/packages/@jsonql/vue/src/assets/logo.png b/packages/@jsonql/vue/src/assets/logo.png deleted file mode 100644 index f3d2503fc2a44b5053b0837ebea6e87a2d339a43..0000000000000000000000000000000000000000 Binary files a/packages/@jsonql/vue/src/assets/logo.png and /dev/null differ diff --git a/packages/@jsonql/vue/src/components/HelloWorld.vue b/packages/@jsonql/vue/src/components/HelloWorld.vue deleted file mode 100644 index 879051a29739fdfb17ae82ed23b53fac251c2b7e..0000000000000000000000000000000000000000 --- a/packages/@jsonql/vue/src/components/HelloWorld.vue +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - diff --git a/packages/@jsonql/vue/src/main.js b/packages/@jsonql/vue/src/main.js deleted file mode 100644 index 63eb05f711c8cb5cda45128882fa69c351f105fb..0000000000000000000000000000000000000000 --- a/packages/@jsonql/vue/src/main.js +++ /dev/null @@ -1,8 +0,0 @@ -import Vue from 'vue' -import App from './App.vue' - -Vue.config.productionTip = false - -new Vue({ - render: h => h(App), -}).$mount('#app') diff --git a/packages/constants/README.md b/packages/constants/README.md index 1e6ac25d7cadbeb8c7403765d9b101afc9caa8f8..7d37789df3eae9e99d2811bf30912d184333181b 100755 --- a/packages/constants/README.md +++ b/packages/constants/README.md @@ -53,9 +53,10 @@ non-javascript to develop your tool. You can also use the included `constants.js - CHECKED_KEY - AUTH_TYPE - LOGIN_NAME -- ISSUER_NAME - LOGOUT_NAME - VALIDATOR_NAME +- DISCONNECT_FN_NAME +- SWITCH_USER_FN_NAME - AUTH_HEADER - AUTH_CHECK_HEADER - BEARER diff --git a/packages/constants/constants.json b/packages/constants/constants.json index 8dbe86cf8787fd147c07a7014be5b9ad8db7308d..397f4574292fbacf4443d6564c6aab250739de10 100644 --- a/packages/constants/constants.json +++ b/packages/constants/constants.json @@ -59,9 +59,10 @@ "CHECKED_KEY": "__checked__", "AUTH_TYPE": "auth", "LOGIN_NAME": "login", - "ISSUER_NAME": "login", "LOGOUT_NAME": "logout", "VALIDATOR_NAME": "validator", + "DISCONNECT_FN_NAME": "disconnect", + "SWITCH_USER_FN_NAME": "switch-user", "AUTH_HEADER": "Authorization", "AUTH_CHECK_HEADER": "authorization", "BEARER": "Bearer", diff --git a/packages/constants/main.js b/packages/constants/main.js index f9dfa41c834ffa8bc49ac4ca9975d75a0ac9b4a4..7106a1b6f883b6e049e2e24a719189156b5617a5 100644 --- a/packages/constants/main.js +++ b/packages/constants/main.js @@ -59,9 +59,10 @@ module.exports = { "CHECKED_KEY": "__checked__", "AUTH_TYPE": "auth", "LOGIN_NAME": "login", - "ISSUER_NAME": "login", "LOGOUT_NAME": "logout", "VALIDATOR_NAME": "validator", + "DISCONNECT_FN_NAME": "disconnect", + "SWITCH_USER_FN_NAME": "switch-user", "AUTH_HEADER": "Authorization", "AUTH_CHECK_HEADER": "authorization", "BEARER": "Bearer", diff --git a/packages/constants/module.js b/packages/constants/module.js index fec52a9d401d660020fd5720f947cc0ecb286124..1a9b9a0cd958df28e7d8cde2b3be6244b11ed0b0 100644 --- a/packages/constants/module.js +++ b/packages/constants/module.js @@ -62,13 +62,16 @@ export const ENUM_KEY = 'enumv' // need to change this because enum is a reserv export const ARGS_KEY = 'args' export const CHECKER_KEY = 'checker' export const ALIAS_KEY = 'alias' +// @TODO remove this later export const CHECKED_KEY = '__checked__' // author export const AUTH_TYPE = 'auth' export const LOGIN_NAME = 'login' -export const ISSUER_NAME = LOGIN_NAME // legacy issue need to replace them later +// export const ISSUER_NAME = LOGIN_NAME // legacy issue need to replace them later export const LOGOUT_NAME = 'logout' export const VALIDATOR_NAME = 'validator' +export const DISCONNECT_FN_NAME = 'disconnect' +export const SWITCH_USER_FN_NAME = 'switch-user' export const AUTH_HEADER = 'Authorization' export const AUTH_CHECK_HEADER = 'authorization' // this is for checking so it must be lowercase diff --git a/packages/constants/package.json b/packages/constants/package.json index 455b05e2723f932a0c501ba5ec58083e86f1e75e..67769c737bc43643b3d82c97bf8e350f76f2f179 100755 --- a/packages/constants/package.json +++ b/packages/constants/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-constants", - "version": "1.9.4", + "version": "1.9.5", "description": "All the share constants for json:ql tools", "main": "main.js", "module": "module.js", diff --git a/packages/ws-client-core/package.json b/packages/ws-client-core/package.json index 473230977f3701854d25468127e3f311589f3dc2..14e846d23150f9fd9618bbbaab00666389f997d0 100644 --- a/packages/ws-client-core/package.json +++ b/packages/ws-client-core/package.json @@ -53,7 +53,7 @@ "node": ">=8" }, "dependencies": { - "jsonql-constants": "^1.9.3", + "jsonql-constants": "^1.9.4", "jsonql-errors": "^1.1.10", "jsonql-params-validator": "^1.5.2", "jsonql-utils": "^1.0.0", @@ -64,7 +64,7 @@ "esm": "^3.2.25", "fs-extra": "^8.1.0", "jsonql-contract": "^1.8.7", - "jsonql-ws-server": "^1.6.2", + "jsonql-ws-server": "^1.6.3", "kefir": "^3.8.6", "ws": "^7.2.1" }, diff --git a/packages/ws-client-core/src/core/action-call.js b/packages/ws-client-core/src/core/action-call.js index b2d3491f23ca62aff1d6811f8d786978e33bd3df..1c7c1225cebb49551014a059cda6a2ef5d671824 100644 --- a/packages/ws-client-core/src/core/action-call.js +++ b/packages/ws-client-core/src/core/action-call.js @@ -1,5 +1,5 @@ // the actual trigger call method -import { ON_RESULT_PROP_NAME, EMIT_REPLY_TYPE } from 'jsonql-constants' +import { ON_RESULT_FN_NAME, EMIT_REPLY_TYPE } from 'jsonql-constants' import { createEvt, toArray } from '../utils' import { respondHandler } from './respond-handler' @@ -27,7 +27,7 @@ export function actionCall(ee, namespace, resolverName, args = [], log) { // this cause the onResult got the result back first // and it should be the promise resolve first ee.$on( - createEvt(namespace, resolverName, ON_RESULT_PROP_NAME), + createEvt(namespace, resolverName, ON_RESULT_FN_NAME), function actionCallResultHandler(result) { log(`got the first result`, result) diff --git a/packages/ws-client-core/src/core/resolver-methods.js b/packages/ws-client-core/src/core/resolver-methods.js index 4e9792fa76f23eae4b85e2ff2211d49b23c13d4b..e308e33da0c207ee25224e4cf64a613d6e9999bf 100644 --- a/packages/ws-client-core/src/core/resolver-methods.js +++ b/packages/ws-client-core/src/core/resolver-methods.js @@ -11,12 +11,16 @@ import { finalCatch } from 'jsonql-errors' import { validateAsync } from 'jsonql-params-validator' import { setupResolver } from './setup-resolver' import { actionCall } from './action-call' -import { createEvt, objDefineProps, isFunc, injectToFn } from '../utils' +import { + createEvt, + objDefineProps, + isFunc, + injectToFn +} from '../utils' import { - ON_ERROR_PROP_NAME, - ON_READY_PROP_NAME + ON_ERROR_FN_NAME, + ON_READY_FN_NAME } from 'jsonql-constants' -// import { CB_FN_NAME } from '../options/constants' /** * create the actual function to send message to server @@ -77,13 +81,13 @@ export function createNamespaceErrorHandler(obj, opts, ee, nspSet) { // using the onError as name // @TODO we should follow the convention earlier // make this a setter for the obj itself - objDefineProps(obj, ON_ERROR_PROP_NAME, function namespaceErrorCallbackHandler(namespaceErrorHandler) { + objDefineProps(obj, ON_ERROR_FN_NAME, function namespaceErrorCallbackHandler(namespaceErrorHandler) { if (isFunc(namespaceErrorHandler)) { - // please note ON_ERROR_PROP_NAME can add multiple listners + // please note ON_ERROR_FN_NAME can add multiple listners for (let namespace in nspSet) { // this one is very tricky, we need to make sure the trigger is calling // with the namespace as well as the error - ee.$on(createEvt(namespace, ON_ERROR_PROP_NAME), namespaceErrorHandler) + ee.$on(createEvt(namespace, ON_ERROR_FN_NAME), namespaceErrorHandler) } } }), @@ -101,10 +105,10 @@ export function createNamespaceErrorHandler(obj, opts, ee, nspSet) { */ export function createOnReadyHandler(obj, opts, ee) { return [ - objDefineProps(obj, ON_READY_PROP_NAME, function onReadyCallbackHandler(onReadyCallback) { + objDefineProps(obj, ON_READY_FN_NAME, function onReadyCallbackHandler(onReadyCallback) { if (isFunc(onReadyCallback)) { // reduce it down to just one flat level - ee.$on(ON_READY_PROP_NAME, onReadyCallback) + ee.$on(ON_READY_FN_NAME, onReadyCallback) } }), opts, diff --git a/packages/ws-client-core/src/core/setup-auth-methods.js b/packages/ws-client-core/src/core/setup-auth-methods.js index 9084479b49416922804bed6511169eb41b9841e3..d23fb914029a89a54d5cdcf122341288a0e62550 100644 --- a/packages/ws-client-core/src/core/setup-auth-methods.js +++ b/packages/ws-client-core/src/core/setup-auth-methods.js @@ -2,7 +2,7 @@ import { LOGIN_EVENT_NAME, LOGOUT_EVENT_NAME, - ON_LOGIN_PROP_NAME + ON_LOGIN_FN_NAME } from 'jsonql-constants' import { JsonqlValidationError } from 'jsonql-errors' import { injectToFn, chainFns, isString, objDefineProps, isFunc } from '../utils' @@ -56,10 +56,10 @@ const setupLogoutHandler = (obj, opts, ee) => [ * @return {array} [ obj, opts, ee] what comes in what goes out */ const createOnLoginhandler = (obj, opts, ee) => [ - objDefineProps(obj, ON_LOGIN_PROP_NAME, function onLoginCallbackHandler(onLoginCallback) { + objDefineProps(obj, ON_LOGIN_FN_NAME, function onLoginCallbackHandler(onLoginCallback) { if (isFunc(onLoginCallback)) { // only one callback can registered with it, TBC - ee.$only(ON_LOGIN_PROP_NAME, onLoginCallback) + ee.$only(ON_LOGIN_FN_NAME, onLoginCallback) } }), opts, diff --git a/packages/ws-client-core/src/core/setup-resolver.js b/packages/ws-client-core/src/core/setup-resolver.js index c80da042343142608db098daca9650697bf9b805..e8e78cf3e65fd1dd8308740b1e0701439facf76c 100644 --- a/packages/ws-client-core/src/core/setup-resolver.js +++ b/packages/ws-client-core/src/core/setup-resolver.js @@ -1,9 +1,9 @@ // break up the original setup resolver method here // import { JsonqlValidationError, finalCatch } from 'jsonql-errors' import { - ON_ERROR_PROP_NAME, - ON_MESSAGE_PROP_NAME, - ON_RESULT_PROP_NAME + ON_ERROR_FN_NAME, + ON_MESSAGE_FN_NAME, + ON_RESULT_FN_NAME } from 'jsonql-constants' // local import { MY_NAMESPACE } from '../options/constants' @@ -11,8 +11,6 @@ import { chainFns, objDefineProps, injectToFn, createEvt, isFunc } from '../util import { respondHandler } from './respond-handler' import { setupSend } from './setup-send' - - /** * The first one in the chain, just setup a namespace prop * the rest are passing through @@ -36,15 +34,15 @@ const setupNamespace = (fn, ee, namespace, resolverName, params, log) => [ * onResult handler */ const setupOnResult = (fn, ee, namespace, resolverName, params, log) => [ - objDefineProps(fn, ON_RESULT_PROP_NAME, function(resultCallback) { + objDefineProps(fn, ON_RESULT_FN_NAME, function(resultCallback) { if (isFunc(resultCallback)) { ee.$on( - createEvt(namespace, resolverName, ON_RESULT_PROP_NAME), + createEvt(namespace, resolverName, ON_RESULT_FN_NAME), function resultHandler(result) { respondHandler(result, resultCallback, (error) => { log(`Catch error: "${resolverName}"`, error) ee.$trigger( - createEvt(namespace, resolverName, ON_ERROR_PROP_NAME), + createEvt(namespace, resolverName, ON_ERROR_FN_NAME), error ) }) @@ -64,7 +62,7 @@ const setupOnResult = (fn, ee, namespace, resolverName, params, log) => [ * bi-directional data stream */ const setupOnMessage = (fn, ee, namespace, resolverName, params, log) => [ - objDefineProps(fn, ON_MESSAGE_PROP_NAME, function(messageCallback) { + objDefineProps(fn, ON_MESSAGE_FN_NAME, function(messageCallback) { // we expect this to be a function if (isFunc(messageCallback)) { // did that add to the callback @@ -72,14 +70,14 @@ const setupOnMessage = (fn, ee, namespace, resolverName, params, log) => [ respondHandler(args, messageCallback, (error) => { log(`Catch error: "${resolverName}"`, error) ee.$trigger( - createEvt(namespace, resolverName, ON_ERROR_PROP_NAME), + createEvt(namespace, resolverName, ON_ERROR_FN_NAME), error ) }) } // register the handler for this message event ee.$only( - createEvt(namespace, resolverName, ON_MESSAGE_PROP_NAME), + createEvt(namespace, resolverName, ON_MESSAGE_FN_NAME), onMessageCallback ) } @@ -92,14 +90,14 @@ const setupOnMessage = (fn, ee, namespace, resolverName, params, log) => [ ] /** - * ON_ERROR_PROP_NAME handler + * ON_ERROR_FN_NAME handler */ const setupOnError = (fn, ee, namespace, resolverName, params, log) => [ - objDefineProps(fn, ON_ERROR_PROP_NAME, function(resolverErrorHandler) { + objDefineProps(fn, ON_ERROR_FN_NAME, function(resolverErrorHandler) { if (isFunc(resolverErrorHandler)) { - // please note ON_ERROR_PROP_NAME can add multiple listners + // please note ON_ERROR_FN_NAME can add multiple listners ee.$only( - createEvt(namespace, resolverName, ON_ERROR_PROP_NAME), + createEvt(namespace, resolverName, ON_ERROR_FN_NAME), resolverErrorHandler ) } diff --git a/packages/ws-client-core/src/core/setup-send.js b/packages/ws-client-core/src/core/setup-send.js index e90ed62d47dbd656307c3eee7496b21ccf9979df..9a3fff7dab3da87cebe10b07e94a1fa6ba46dafb 100644 --- a/packages/ws-client-core/src/core/setup-send.js +++ b/packages/ws-client-core/src/core/setup-send.js @@ -1,15 +1,16 @@ +// setting up the send method import { JsonqlValidationError, finalCatch } from 'jsonql-errors' import { ERROR_KEY, - ON_ERROR_PROP_NAME, - SEND_MSG_PROP_NAME + ON_ERROR_FN_NAME, + SEND_MSG_FN_NAME } from 'jsonql-constants' import { validateAsync } from 'jsonql-params-validator' import { objDefineProps, createEvt, toArray } from '../utils' import { actionCall } from './action-call' /** - * pairing with the server vesrion SEND_MSG_PROP_NAME + * pairing with the server vesrion SEND_MSG_FN_NAME * last of the chain so only return the resolver (fn) * @param {function} fn the resolver function * @param {object} ee event emitter instance @@ -20,7 +21,7 @@ import { actionCall } from './action-call' * @return {function} return the resolver itself */ export const setupSend = (fn, ee, namespace, resolverName, params, log) => ( - objDefineProps(fn, SEND_MSG_PROP_NAME, function sendSetter(messagePayload) { + objDefineProps(fn, SEND_MSG_FN_NAME, function sendSetter(messagePayload) { // debugFn('got payload for', messagePayload) // @NOTE change from sync interface to async @ 1.0.0 // this way we will able to catch all the error(s) @@ -30,7 +31,7 @@ export const setupSend = (fn, ee, namespace, resolverName, params, log) => ( if (result[ERROR_KEY] && result[ERROR_KEY].length) { // debugFn(`got ERROR_KEY`, result[ERROR_KEY]) ee.$call( - createEvt(namespace, resolverName, ON_ERROR_PROP_NAME), + createEvt(namespace, resolverName, ON_ERROR_FN_NAME), [new JsonqlValidationError(resolverName, result[ERROR_KEY])] ) } else { @@ -41,7 +42,7 @@ export const setupSend = (fn, ee, namespace, resolverName, params, log) => ( .catch(err => { // debugFn(`error after validateAsync`, err) ee.$call( - createEvt(namespace, resolverName, ON_ERROR_PROP_NAME), + createEvt(namespace, resolverName, ON_ERROR_FN_NAME), [new JsonqlValidationError(resolverName, err)] ) }) diff --git a/packages/ws-client-core/src/options/constants.js b/packages/ws-client-core/src/options/constants.js index 733bd1531d07f2d02a21993f625ca0c9c46349c6..419e890b7a6a7667ec3de8d3521484e21394fd01 100644 --- a/packages/ws-client-core/src/options/constants.js +++ b/packages/ws-client-core/src/options/constants.js @@ -4,8 +4,8 @@ import { EMIT_REPLY_TYPE, JS_WS_SOCKET_IO_NAME, JS_WS_NAME, - ON_MESSAGE_PROP_NAME, - ON_RESULT_PROP_NAME + ON_MESSAGE_FN_NAME, + ON_RESULT_FN_NAME } from 'jsonql-constants' const SOCKET_IO = JS_WS_SOCKET_IO_NAME @@ -42,8 +42,8 @@ export { MISSING_PROP_ERR, UNKNOWN_CLIENT_ERR, EMIT_EVT, - ON_MESSAGE_PROP_NAME, - ON_RESULT_PROP_NAME, + ON_MESSAGE_FN_NAME, + ON_RESULT_FN_NAME, NAMESPACE_KEY, UNKNOWN_RESULT, NOT_ALLOW_OP, diff --git a/packages/ws-client-core/src/options/defaults.js b/packages/ws-client-core/src/options/defaults.js index 3a20e91dd686b17f4482c10ba09ed24001dc07e3..43b1f3331e21eb9942172a01809f4c503fafad83 100644 --- a/packages/ws-client-core/src/options/defaults.js +++ b/packages/ws-client-core/src/options/defaults.js @@ -9,7 +9,7 @@ import { ENUM_KEY, CHECKER_KEY, JSONQL_PATH, - ISSUER_NAME, + LOGIN_NAME, LOGOUT_NAME, IO_ROUNDTRIP_LOGIN, IO_HANDSHAKE_LOGIN, @@ -23,7 +23,7 @@ const AVAILABLE_METHODS = [IO_ROUNDTRIP_LOGIN, IO_HANDSHAKE_LOGIN] const wsBaseOptions = { debugOn: createConfig(false, [BOOLEAN_TYPE]), // useCallbackStyle: createConfig(false, [BOOLEAN_TYPE]), abandoned in 0.6.0 - loginHandlerName: createConfig(ISSUER_NAME, [STRING_TYPE]), + loginHandlerName: createConfig(LOGIN_NAME, [STRING_TYPE]), logoutHandlerName: createConfig(LOGOUT_NAME, [STRING_TYPE]), // this is for socket.io loginMethod: createConfig(IO_HANDSHAKE_LOGIN, [STRING_TYPE], {[ENUM_KEY]: AVAILABLE_METHODS}), diff --git a/packages/ws-client-core/src/options/index.js b/packages/ws-client-core/src/options/index.js index 606eed31c93b2c6f351d4acc8e35aac643d3e40a..d0aa7f61e6d3e87f811acffc992701e4df5a0d10 100644 --- a/packages/ws-client-core/src/options/index.js +++ b/packages/ws-client-core/src/options/index.js @@ -1,6 +1,13 @@ // create options -import { checkConfigAsync, checkConfig } from 'jsonql-params-validator' -import { wsCoreDefaultOptions, wsCoreConstProps, socketAppProps } from './defaults' +import { + checkConfigAsync, + checkConfig +} from 'jsonql-params-validator' +import { + wsCoreDefaultOptions, + wsCoreConstProps, + socketAppProps +} from './defaults' import { fixWss, getHostName, diff --git a/packages/ws-client-core/src/share/client-event-handler.js b/packages/ws-client-core/src/share/client-event-handler.js index 2920629f61ec45d98ea8e7541d3b9225d930ad81..c9aed47fbf8b4a18b5967ad9dfdd3d614936efa8 100644 --- a/packages/ws-client-core/src/share/client-event-handler.js +++ b/packages/ws-client-core/src/share/client-event-handler.js @@ -5,8 +5,8 @@ import { LOGOUT_EVENT_NAME, NOT_LOGIN_ERR_MSG, - ON_ERROR_PROP_NAME, - ON_RESULT_PROP_NAME + ON_ERROR_FN_NAME, + ON_RESULT_FN_NAME } from 'jsonql-constants' import { EMIT_EVT, SOCKET_IO } from '../options/constants' import { createEvt, clearMainEmitEvt } from '../utils' @@ -33,9 +33,9 @@ const notLoginWsHandler = (namespace, ee, opts) => { } // It should just throw error here and should not call the result // because that's channel for handling normal event not the fake one - ee.$call(createEvt(namespace, resolverName, ON_ERROR_PROP_NAME), [ error ]) + ee.$call(createEvt(namespace, resolverName, ON_ERROR_FN_NAME), [ error ]) // also trigger the result handler, but wrap inside the error key - ee.$call(createEvt(namespace, resolverName, ON_RESULT_PROP_NAME), [{ error }]) + ee.$call(createEvt(namespace, resolverName, ON_RESULT_FN_NAME), [{ error }]) } ) } @@ -49,6 +49,37 @@ const getPrivateNamespace = (namespaces) => ( namespaces.length > 1 ? namespaces[0] : false ) +/** + * Only when there is a private namespace then we bind to this event + * @param {object} nsps the available nsp(s) + * @param {array} namespaces available namespace + * @param {object} ee eventEmitter + * @param {object} opts configuration + * @return {void} + */ +const logoutEvtHandler = (nsps, namespaces, ee, opts) => { + // this will be available regardless enableAuth + // because the server can log the client out + ee.$on(LOGOUT_EVENT_NAME, function logoutEvtHandlerAction() { + opts.log('LOGOUT_EVENT_NAME') + // disconnect(nsps, opts.serverType) + // we need to issue error to all the namespace onError handler + triggerNamespacesOnError(ee, namespaces, LOGOUT_EVENT_NAME) + // rebind all of the handler to the fake one + namespaces.forEach( namespace => { + clearMainEmitEvt(ee, namespace) + // clear out the nsp + nsps[namespace] = null + // @TODO here is the problem, we clear out ALL the nsps + // but we should keep the public nsp, because logout doesn't mean + // disconnect everything right? + + // add a NOT LOGIN error if call + notLoginWsHandler(namespace, ee, opts) + }) + }) +} + /** * centralize all the comm in one place * @param {object} opts configuration @@ -64,6 +95,7 @@ export function clientEventHandler(opts, nspMap, ee, bindWsHandler, namespaces, // then we can use this prop to determine if we need to fire the ON_LOGIN_PROP_NAME event const privateNamespace = getPrivateNamespace(namespaces) let isPrivate = false + let hasPrivate = false const { log } = opts // loop // @BUG for io this has to be in order the one with auth need to get call first @@ -83,27 +115,14 @@ export function clientEventHandler(opts, nspMap, ee, bindWsHandler, namespaces, Reflect.apply(bindWsHandler, null, args) } else { // a dummy placeholder + // @TODO but it should be a not connect handler + // when it's not login (or fail) this should be handle differently notLoginWsHandler(namespace, ee, opts) } }) - // this will be available regardless enableAuth - // because the server can log the client out - ee.$on(LOGOUT_EVENT_NAME, function logoutEvtHandler() { - log('LOGOUT_EVENT_NAME') - // disconnect(nsps, opts.serverType) - // we need to issue error to all the namespace onError handler - triggerNamespacesOnError(ee, namespaces, LOGOUT_EVENT_NAME) - // rebind all of the handler to the fake one - namespaces.forEach( namespace => { - clearMainEmitEvt(ee, namespace) - // clear out the nsp - nsps[namespace] = null - // @TODO here is the problem, we clear out ALL the nsps - // but we should keep the public nsp, because logout doesn't mean - // disconnect everything right? - - // add a NOT LOGIN error if call - notLoginWsHandler(namespace, ee, opts) - }) - }) + // logout event handler + if (hasPrivate) { + logoutEvtHandler(nsps, namespaces, ee, opts) + } + // @TODO the INTERCOM event handlers } diff --git a/packages/ws-client-core/src/share/trigger-namespaces-on-error.js b/packages/ws-client-core/src/share/trigger-namespaces-on-error.js index 0145f5924c23141534a48abcb731372a9ffce3f8..3a6430bea097ca66cfdde4e821e3cffd2ea25c5a 100644 --- a/packages/ws-client-core/src/share/trigger-namespaces-on-error.js +++ b/packages/ws-client-core/src/share/trigger-namespaces-on-error.js @@ -1,5 +1,5 @@ // this use by client-event-handler -import { ON_ERROR_PROP_NAME } from 'jsonql-constants' +import { ON_ERROR_FN_NAME } from 'jsonql-constants' import { createEvt } from '../utils' /** @@ -12,7 +12,7 @@ import { createEvt } from '../utils' export function triggerNamespacesOnError(ee, namespaces, message) { namespaces.forEach( namespace => { ee.$trigger( - createEvt(namespace, ON_ERROR_PROP_NAME), + createEvt(namespace, ON_ERROR_FN_NAME), [{ message, namespace }] ) }) diff --git a/packages/ws-client-core/tests/auth.test.js b/packages/ws-client-core/tests/auth.test.js index 00c169e8545e4eb7a310d835ebdd0e15d613ed9b..b90556038f94712a81ced134db7bd985ec9a8a80 100644 --- a/packages/ws-client-core/tests/auth.test.js +++ b/packages/ws-client-core/tests/auth.test.js @@ -8,8 +8,8 @@ const { mockClient, log } = require('./fixtures/lib/mock-client') const { - ON_ERROR_PROP_NAME, - ON_LOGIN_PROP_NAME + ON_ERROR_FN_NAME, + ON_LOGIN_FN_NAME } = require('jsonql-constants') test.before(async t => { @@ -27,14 +27,14 @@ test.cb(`We should able to get a list of event register via the eventEmitter`, t t.truthy(client) // note it's one name onError that will listen to all the nsp errors - client[ON_ERROR_PROP_NAME] = function() { + client[ON_ERROR_FN_NAME] = function() { log(`OnError callback added`) } // there is only one onReady call now - client[ON_LOGIN_PROP_NAME] = function(msg) { - log(`${ON_LOGIN_PROP_NAME} callback added`, msg) + client[ON_LOGIN_FN_NAME] = function(msg) { + log(`${ON_LOGIN_FN_NAME} callback added`, msg) t.pass() t.end() } diff --git a/packages/ws-client-core/tests/fixtures/io-setup.js b/packages/ws-client-core/tests/fixtures/io-setup.js index 2b6c9555451a0a315e151e71a908e193e92b6d34..b02e144513dd28e33249c3dd6b2673c63f497a38 100644 --- a/packages/ws-client-core/tests/fixtures/io-setup.js +++ b/packages/ws-client-core/tests/fixtures/io-setup.js @@ -1,5 +1,5 @@ // const Koa = require('koa'); -const bodyparser = require('koa-bodyparser') +// const bodyparser = require('koa-bodyparser') const jsonqlWsServer = require('jsonql-ws-server') const config = require('./contract-config') const { join } = require('path') diff --git a/packages/ws-client-core/tests/fixtures/lib/fake-ws-client.js b/packages/ws-client-core/tests/fixtures/lib/fake-ws-client.js index bae790c47297a6e088899ec1d5c2926a4538dc74..93a42cbeaad7513db873d382340643fbd6f45666 100644 --- a/packages/ws-client-core/tests/fixtures/lib/fake-ws-client.js +++ b/packages/ws-client-core/tests/fixtures/lib/fake-ws-client.js @@ -3,8 +3,8 @@ import debug from 'debug' const log = debug('jsonql-ws-client:test:fake-client') import { - ON_READY_PROP_NAME, - ON_LOGIN_PROP_NAME + ON_READY_FN_NAME, + ON_LOGIN_FN_NAME } from 'jsonql-constants' function fakeWsClient(...args) { @@ -22,9 +22,9 @@ function fakeWsClient(...args) { // we fire the the onReady after 1/2 second setTimeout(() => { if (enableAuth) { - obj.ee.$trigger(ON_LOGIN_PROP_NAME, 'You are login') + obj.ee.$trigger(ON_LOGIN_FN_NAME, 'You are login') } else { - obj.ee.$trigger(ON_READY_PROP_NAME, 'fake!') + obj.ee.$trigger(ON_READY_FN_NAME, 'fake!') } }, 500) diff --git a/packages/ws-client-core/tests/fixtures/resolvers/socket/continuous.js b/packages/ws-client-core/tests/fixtures/resolvers/socket/continuous.js index 3d468bb97fbe076216fde1fa5137f6c2f0b58dc9..e83e373dd02bdba3ff79a5f58fe273e0e486a91d 100644 --- a/packages/ws-client-core/tests/fixtures/resolvers/socket/continuous.js +++ b/packages/ws-client-core/tests/fixtures/resolvers/socket/continuous.js @@ -1,6 +1,6 @@ // this will keep sending out message until received a terminate call -let timer; -let ctn = 0; +let timer +let ctn = 0 const debug = require('debug')('jsonql-ws-client:socket:continous') /** * @param {string} msg a message @@ -12,10 +12,10 @@ module.exports = function continuous(msg) { } // use the send setter instead timer = setInterval(() => { - continuous.send = msg + ` [${++ctn}] ${Date.now()}`; - }, 1000); + continuous.send = msg + ` [${++ctn}] ${Date.now()}` + }, 1000) // return result return new Promise((resolver) => { resolver(`start at ${Date.now()}`) - }); + }) } diff --git a/packages/ws-client-core/tests/fixtures/resolvers/socket/public/pinging.js b/packages/ws-client-core/tests/fixtures/resolvers/socket/public/pinging.js index 9aa000f382e1d934e32a32ebb709ef629664a3af..fc1e36ba4a9159dfdb15b04f3719cff0822ab923 100644 --- a/packages/ws-client-core/tests/fixtures/resolvers/socket/public/pinging.js +++ b/packages/ws-client-core/tests/fixtures/resolvers/socket/public/pinging.js @@ -1,7 +1,7 @@ // this is a public method always avaialble const debug = require('debug')('jsonql-ws-client:resolver:pinging') -let ctn = 0; +let ctn = 0 /** * @param {string} msg message * @return {string} reply message based on your message @@ -17,12 +17,12 @@ module.exports = function pinging(msg) { debug(`got a pong`) pinging.send = 'ping'; default: - return `Got your message ${msg}`; + return `Got your message ${msg}` //pinging.send = 'You lose!'; } return true; } ++ctn; debug(`Did return here`) - return 'connection established'; + return 'connection established' } diff --git a/packages/ws-client-core/tests/fixtures/resolvers/socket/send-extra-msg.js b/packages/ws-client-core/tests/fixtures/resolvers/socket/send-extra-msg.js index 9144b99adac8272955e4f636174093a38a184604..6b2d3547e63e4f8782b04706cf23cde184c50913 100644 --- a/packages/ws-client-core/tests/fixtures/resolvers/socket/send-extra-msg.js +++ b/packages/ws-client-core/tests/fixtures/resolvers/socket/send-extra-msg.js @@ -6,7 +6,7 @@ * @return {number} x + ? */ module.exports = function sendExtraMsg(x) { - sendExtraMsg.send = x + 2; + sendExtraMsg.send = x + 2 - return x + 1; + return x + 1 } diff --git a/packages/ws-client-core/tests/fixtures/resolvers/socket/simple.js b/packages/ws-client-core/tests/fixtures/resolvers/socket/simple.js index 61810eae68ed7c1c7c2442288d62843acdbd873c..a50a414016cb3b2a9507ba86cc2548525ebc25f3 100644 --- a/packages/ws-client-core/tests/fixtures/resolvers/socket/simple.js +++ b/packages/ws-client-core/tests/fixtures/resolvers/socket/simple.js @@ -5,5 +5,5 @@ * @return {number} a number + 1; */ module.exports = function(i) { - return ++i; + return ++i } diff --git a/packages/ws-client-core/tests/fixtures/resolvers/socket/throw-error.js b/packages/ws-client-core/tests/fixtures/resolvers/socket/throw-error.js index a7fcd6f4b4bce70b962a312f7abe1c5025852130..030e27a3fe5b1a8e84effddc80c4582a6a1dc08b 100644 --- a/packages/ws-client-core/tests/fixtures/resolvers/socket/throw-error.js +++ b/packages/ws-client-core/tests/fixtures/resolvers/socket/throw-error.js @@ -5,5 +5,5 @@ * @return {error} just throw */ module.exports = function() { - throw new Error('Shitty Shitty Bang Bang'); + throw new Error('Shitty Shitty Bang Bang') } diff --git a/packages/ws-client-core/tests/fixtures/server-setup.js b/packages/ws-client-core/tests/fixtures/server-setup.js index 348623043a7edb02e3ed61e8038e577a09249b44..92dc86d77db3e9ae889b5634400ca9b4f77001d6 100644 --- a/packages/ws-client-core/tests/fixtures/server-setup.js +++ b/packages/ws-client-core/tests/fixtures/server-setup.js @@ -1,8 +1,8 @@ const http = require('http') -const fsx = require('fs-extra') +// const fsx = require('fs-extra') const { join } = require('path') -const debug = require('debug')('jsonql-ws-client:fixtures:server') -const { JSONQL_PATH } = require('jsonql-constants') +// const debug = require('debug')('jsonql-ws-client:fixtures:server') +// const { JSONQL_PATH } = require('jsonql-constants') const resolverDir = join(__dirname, 'resolvers') const contractDir = join(__dirname, 'contract') diff --git a/packages/ws-client-core/tests/tbd.test.js b/packages/ws-client-core/tests/tbd.test.js index ba0f60425c6ab19af9cf6d068b8060400ce452dd..51a6088f217bfb1498475cc6e6f566af4a004c24 100644 --- a/packages/ws-client-core/tests/tbd.test.js +++ b/packages/ws-client-core/tests/tbd.test.js @@ -6,8 +6,8 @@ const { mockClient, log } = require('./fixtures/lib/mock-client') const { - ON_ERROR_PROP_NAME, - ON_READY_PROP_NAME + ON_ERROR_FN_NAME, + ON_READY_FN_NAME } = require('jsonql-constants') test.before(async t => { @@ -25,12 +25,12 @@ test.cb(`We should able to get a list of event register via the eventEmitter`, t t.truthy(client) // note it's one name onError that will listen to all the nsp errors - client[ON_ERROR_PROP_NAME] = function() { + client[ON_ERROR_FN_NAME] = function() { log(`OnError callback added`) } // there is only one onReady call now - client[ON_READY_PROP_NAME] = function(msg) { + client[ON_READY_FN_NAME] = function(msg) { log(`onError callback added`, msg) t.pass() t.end() diff --git a/packages/ws-server-core/index.js b/packages/ws-server-core/index.js index 3e2d1943434ea53a7e97430da1b99d9c6d2c9a02..935782f600dfdac6e8dd5dd6b715bfa1bea8e824 100644 --- a/packages/ws-server-core/index.js +++ b/packages/ws-server-core/index.js @@ -1,15 +1,13 @@ // Not going to use the koa-socket-2 due to it's lack of support namespace // which is completely useless for us if there is no namespace -const { JsonqlError } = require('jsonql-errors') const { // rename them wsServerDefaultOptions, wsServerConstProps, // rest of the exports - initWsServerOption, checkSocketServerType, - wsServerCheckConfiguration - + jsonqlWsServerCoreAction, + jsonqlWsServerCore } = require('./src') // we also need to export all the share methods here because they will get use // in the respective external methods @@ -24,50 +22,11 @@ const { getUserdata } = require('./src/share/helpers') const { resolveMethod } = require('./src/share/resolve-method') - +const { interComEventHandler } = require('./src/share/inter-com-handler') const debug = getDebug('main') // also report the constants const jsonqlWsCoreConstants = require('./src/options/constants') -/** - * @0.4.0 we breaking up the config and init server in two fn - * Then when we need to combine with other modules, we only use the init - * Also there might be a chance that we need to merge the contract? - * @param {object} obj combine several properties in one - * @param {object} obj.opts checked configuration options - * @param {object} obj.server the http server instance - * @param {object} obj.wsCreateServer reverse passing the wsCreateServer fn from outter module - * @param {object} obj.wsSetup a pre start up function pass from outter module - * @return {promise} checked config - */ -function jsonqlWsServerCoreAction({opts, server, wsCreateServer, wsSetup}) { - - return initWsServerOption(opts) - .then(_opts => { - const nspObj = wsCreateServer(_opts, server) - return Reflect.apply(wsSetup, null, [_opts, nspObj]) - }) - .catch(err => { - console.error('Init jsonql Web Socket server error', err) - throw new JsonqlError('jsonqlWsServer', err) - }) -} - -/** - * This will take the two methods and return a method to generate the web socket server - * This is for standalone server type which unlikely to get use often - * @param {function} wsCreateServer generate the base server - * @param {function} wsSetup the method that bind the events - * @return {function} the method that accept the config and server instance to run - */ -function jsonqlWsServerCore(wsCreateServer, wsSetup) { - - return (config, server) => ( - wsServerCheckConfiguration(config) - .then(opts => ({ opts, server, wsCreateServer, wsSetup })) - .then(jsonqlWsServerCoreAction) - ) -} // export every bits out then the downstream build as they want module.exports = { @@ -91,5 +50,7 @@ module.exports = { jsonqlWsCoreConstants, // the actual methods that create the server jsonqlWsServerCore, - jsonqlWsServerCoreAction + jsonqlWsServerCoreAction, + // @0.6.0 + interComEventHandler } diff --git a/packages/ws-server-core/package.json b/packages/ws-server-core/package.json index 9fe65801d889e9dc20cfe4323e73190029b1b550..dbf16e0100f511545244ea119b45cd88e80d5931 100644 --- a/packages/ws-server-core/package.json +++ b/packages/ws-server-core/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-ws-server-core", - "version": "0.5.0", + "version": "0.6.0", "description": "This is the core module that drive the Jsonql WS Socket server, not for direct use.", "main": "index.js", "files": [ @@ -26,7 +26,7 @@ "debug": "^4.1.1", "esm": "^3.2.25", "fs-extra": "^8.1.0", - "jsonql-constants": "^1.9.1", + "jsonql-constants": "^1.9.4", "jsonql-errors": "^1.1.10", "jsonql-jwt": "^1.3.9", "jsonql-params-validator": "^1.5.2", diff --git a/packages/ws-server-core/src/core.js b/packages/ws-server-core/src/core.js new file mode 100644 index 0000000000000000000000000000000000000000..dbd0a8f774f055fc0e2815c3b21bc4075b75b67b --- /dev/null +++ b/packages/ws-server-core/src/core.js @@ -0,0 +1,55 @@ +// These methods were inside the index.js +// which make it hard to understand why it's there +// these are the core functionality for the other module +// to create the actual Web Socket Server +const { JsonqlError } = require('jsonql-errors') +const { + initWsServerOption, + wsServerCheckConfiguration +} = require('./options') + +/** + * @0.4.0 we breaking up the config and init server in two fn + * Then when we need to combine with other modules, we only use the init + * Also there might be a chance that we need to merge the contract? + * @param {object} obj combine several properties in one + * @param {object} obj.opts checked configuration options + * @param {object} obj.server the http server instance + * @param {object} obj.wsCreateServer reverse passing the wsCreateServer fn from outter module + * @param {object} obj.wsSetup a pre start up function pass from outter module + * @return {promise} checked config + */ +function jsonqlWsServerCoreAction({opts, server, wsCreateServer, wsSetup}) { + + return initWsServerOption(opts) + .then(_opts => { + const nspObj = wsCreateServer(_opts, server) + return Reflect.apply(wsSetup, null, [_opts, nspObj]) + }) + .catch(err => { + console.error('Init jsonql Web Socket server error', err) + throw new JsonqlError('jsonqlWsServer', err) + }) +} + + +/** + * This will take the two methods and return a method to generate the web socket server + * This is for standalone server type which unlikely to get use often + * @param {function} wsCreateServer generate the base server + * @param {function} wsSetup the method that bind the events + * @return {function} the method that accept the config and server instance to run + */ +function jsonqlWsServerCore(wsCreateServer, wsSetup) { + + return (config, server) => ( + wsServerCheckConfiguration(config) + .then(opts => ({ opts, server, wsCreateServer, wsSetup })) + .then(jsonqlWsServerCoreAction) + ) +} + +module.exports = { + jsonqlWsServerCoreAction, + jsonqlWsServerCore +} \ No newline at end of file diff --git a/packages/ws-server-core/src/index.js b/packages/ws-server-core/src/index.js index d9d56174d485c803b529aedeeffb4a237208075e..b5cdb138a187a0ad69ef775d6d45750a433794bb 100644 --- a/packages/ws-server-core/src/index.js +++ b/packages/ws-server-core/src/index.js @@ -6,6 +6,10 @@ const { wsDefaultOptions, wsConstProps } = require('./options') +const { + jsonqlWsServerCoreAction, + jsonqlWsServerCore +} = require('./core') // rename it before export const wsServerDefaultOptions = wsDefaultOptions const wsServerConstProps = wsConstProps @@ -15,7 +19,10 @@ module.exports = { wsServerDefaultOptions, wsServerConstProps, // rest of the exports - initWsServerOption, checkSocketServerType, - wsServerCheckConfiguration + initWsServerOption, + wsServerCheckConfiguration, + // the two top level core methods to create the websocket server + jsonqlWsServerCoreAction, + jsonqlWsServerCore } diff --git a/packages/ws-server-core/src/options/index.js b/packages/ws-server-core/src/options/index.js index 985115d5de5a08f13b55b7dab00ef0a5ad64c99b..d3f5b2e97a9bb71236a4a2791774f1ed9df28b68 100644 --- a/packages/ws-server-core/src/options/index.js +++ b/packages/ws-server-core/src/options/index.js @@ -1,91 +1,26 @@ // WS options +// methods const { join } = require('path') const fsx = require('fs-extra') const { JsonqlValidationError } = require('jsonql-errors') const { - createConfig, checkConfig, checkConfigAsync, isString } = require('jsonql-params-validator') +const { getContract } = require('../share/get-contract') +// properties const { - HSA_ALGO, - ENUM_KEY, - ALIAS_KEY, - PUBLIC_KEY, - PRIVATE_KEY, - STRING_TYPE, - BOOLEAN_TYPE, - NUMBER_TYPE, PEM_EXT, PUBLIC_KEY_NAME, - PRIVATE_KEY_NAME, - IO_HANDSHAKE_LOGIN, - IO_ROUNDTRIP_LOGIN, - DEFAULT_RESOLVER_DIR, - DEFAULT_CONTRACT_DIR, - DEFAULT_KEYS_DIR, - SOCKET_TYPE_KEY, - SOCKET_TYPE_SERVER_ALIAS + PRIVATE_KEY_NAME } = require('jsonql-constants') - -const { - SOCKET_IO, - SECRET_MISSING_ERR -} = require('./constants') -const { getContract } = require('../share/get-contract') - -// const { getDebug } = require('../share/helpers') -// const debug = getDebug('options') - -const dirname = process.cwd() - -// base options -const wsBaseOptions = { - appDir: createConfig('', [STRING_TYPE]), // just matching the Koa but not in use at the moment - // @TODO this will be moving out shortly after the test done - // RS256 this will need to figure out how to distribute the key - algorithm: createConfig(HSA_ALGO, [STRING_TYPE]), - authTimeout: createConfig(15000, [NUMBER_TYPE]), - // we require the contract already generated and pass here - // contract: createConfig({}, [OBJECT_TYPE]), this been causing no end of problem, we don't need it! - enableAuth: createConfig(false, [BOOLEAN_TYPE]), - // this option now is only for passing the key - // this cause a bug because this option is always BOOLEAN and STRING TYPE! - useJwt: createConfig(true, [STRING_TYPE, BOOLEAN_TYPE]), // need to double check this - // update this options to match the jsonql-koa 1.4.10 - resolverDir: createConfig(join(dirname, DEFAULT_RESOLVER_DIR), [STRING_TYPE]), - contractDir: createConfig(join(dirname, DEFAULT_CONTRACT_DIR), [STRING_TYPE]), - keysDir: createConfig(join(dirname, DEFAULT_KEYS_DIR), [STRING_TYPE]), - - // this is for construct the namespace - publicMethodDir: createConfig(PUBLIC_KEY, [STRING_TYPE]), - // just try this with string type first - privateMethodDir: createConfig(PRIVATE_KEY, [STRING_TYPE, BOOLEAN_TYPE]), - // we only want the keys directory then we read it back - // keysDir: createConfig(false, [STRING_TYPE]), - socketIoAuthType: createConfig(false, [STRING_TYPE], { - [ENUM_KEY]: [IO_HANDSHAKE_LOGIN, IO_ROUNDTRIP_LOGIN] - }) -} -// we have to create a standlone prop to check if the user pass the socket server config first -const socketAppProps = { - [SOCKET_TYPE_KEY]: createConfig(SOCKET_IO, [STRING_TYPE], { - [ALIAS_KEY]: SOCKET_TYPE_SERVER_ALIAS - }) -} - -// merge this together for use -const wsDefaultOptions = Object.assign(wsBaseOptions, socketAppProps) - -const wsConstProps = { - contract: false, - publicKey: false, - privateKey: false, - secret: false, - publicNamespace: PUBLIC_KEY, - privateNamespace: PRIVATE_KEY -} +const { SECRET_MISSING_ERR } = require('./constants') +const { + wsDefaultOptions, + wsConstProps, + socketAppProps +} = require('./props') /** * We need this to find the socket server type diff --git a/packages/ws-server-core/src/options/props.js b/packages/ws-server-core/src/options/props.js new file mode 100644 index 0000000000000000000000000000000000000000..8dd7d77e284ecc626e5c339e29045773a1f158e9 --- /dev/null +++ b/packages/ws-server-core/src/options/props.js @@ -0,0 +1,81 @@ +// break out from the index.js to keep property in one place +// and methods in another +const { join } = require('path') +const { createConfig } = require('jsonql-params-validator') +const { + HSA_ALGO, + ENUM_KEY, + ALIAS_KEY, + PUBLIC_KEY, + PRIVATE_KEY, + STRING_TYPE, + BOOLEAN_TYPE, + NUMBER_TYPE, + IO_HANDSHAKE_LOGIN, + IO_ROUNDTRIP_LOGIN, + DEFAULT_RESOLVER_DIR, + DEFAULT_CONTRACT_DIR, + DEFAULT_KEYS_DIR, + SOCKET_TYPE_KEY, + SOCKET_TYPE_SERVER_ALIAS +} = require('jsonql-constants') +const { SOCKET_IO } = require('./constants') + +// const { getDebug } = require('../share/helpers') +// const debug = getDebug('options') + +const dirname = process.cwd() + +// base options +const wsBaseOptions = { + appDir: createConfig('', [STRING_TYPE]), // just matching the Koa but not in use at the moment + // @TODO this will be moving out shortly after the test done + // RS256 this will need to figure out how to distribute the key + algorithm: createConfig(HSA_ALGO, [STRING_TYPE]), + authTimeout: createConfig(15000, [NUMBER_TYPE]), + // we require the contract already generated and pass here + // contract: createConfig({}, [OBJECT_TYPE]), this been causing no end of problem, we don't need it! + enableAuth: createConfig(false, [BOOLEAN_TYPE]), + // this option now is only for passing the key + // this cause a bug because this option is always BOOLEAN and STRING TYPE! + useJwt: createConfig(true, [STRING_TYPE, BOOLEAN_TYPE]), // need to double check this + // update this options to match the jsonql-koa 1.4.10 + resolverDir: createConfig(join(dirname, DEFAULT_RESOLVER_DIR), [STRING_TYPE]), + contractDir: createConfig(join(dirname, DEFAULT_CONTRACT_DIR), [STRING_TYPE]), + keysDir: createConfig(join(dirname, DEFAULT_KEYS_DIR), [STRING_TYPE]), + // @0.6.0 expect this to be the path to the interComEventHandler to handle the INTER_COM_EVENT_NAMES + interComEventHandlerPath: createConfig(null, [STRING_TYPE]), + // this is for construct the namespace + publicMethodDir: createConfig(PUBLIC_KEY, [STRING_TYPE]), + // just try this with string type first + privateMethodDir: createConfig(PRIVATE_KEY, [STRING_TYPE, BOOLEAN_TYPE]), + // we only want the keys directory then we read it back + // keysDir: createConfig(false, [STRING_TYPE]), + socketIoAuthType: createConfig(false, [STRING_TYPE], { + [ENUM_KEY]: [IO_HANDSHAKE_LOGIN, IO_ROUNDTRIP_LOGIN] + }) +} +// we have to create a standlone prop to check if the user pass the socket server config first +const socketAppProps = { + [SOCKET_TYPE_KEY]: createConfig(SOCKET_IO, [STRING_TYPE], { + [ALIAS_KEY]: SOCKET_TYPE_SERVER_ALIAS + }) +} + +// merge this together for use +const wsDefaultOptions = Object.assign(wsBaseOptions, socketAppProps) + +const wsConstProps = { + contract: false, + publicKey: false, + privateKey: false, + secret: false, + publicNamespace: PUBLIC_KEY, + privateNamespace: PRIVATE_KEY +} + +module.exports = { + wsDefaultOptions, + wsConstProps, + socketAppProps +} \ No newline at end of file diff --git a/packages/ws-server-core/src/share/add-property.js b/packages/ws-server-core/src/share/add-property.js index 1039439965b2dda3aceafea48a48ce2f34c84ca1..a4771bd07e231c0853bc81212a235e2865112811 100644 --- a/packages/ws-server-core/src/share/add-property.js +++ b/packages/ws-server-core/src/share/add-property.js @@ -1,8 +1,7 @@ // add required properties to the resolver const { EMIT_REPLY_TYPE, - SEND_MSG_PROP_NAME, - // ON_MESSAGE_PROP_NAME, + SEND_MSG_FN_NAME, JS_WS_NAME, INIT_CLIENT_PROP_KEY } = require('jsonql-constants') @@ -13,16 +12,6 @@ const { injectNodeClient } = require('jsonql-resolver') const { nil, createWsReply, getDebug } = require('../share/helpers') const debug = getDebug(`addProperty`) -/* -@TODO is this necessary? -resolver = addHandlerProperty(resolver, ON_MESSAGE_PROP_NAME, function(handler) { - if (handler && typeof handler === 'function') { - - } - throw new JsonqlError(resolverName, {message: `Require ${ON_MESSAGE_PROP_NAME} to be a function!`}) -}, nil) -*/ - /** * using the serverType to provide different addProperty method to this * change to return a promise on 1.4.4 @@ -38,8 +27,9 @@ const addProperty = (fn, resolverName, ws, userdata, opts) => { .resolve(injectToFn(fn, JS_WS_NAME, ws)) // define the send method .then(resolver => { - debug(`add ${SEND_MSG_PROP_NAME} to ${resolverName}`) - return objDefineProps(fn, SEND_MSG_PROP_NAME, function(prop) { + // @NOTE this will add a `send` function to this resolver + debug(`add ${SEND_MSG_FN_NAME} to ${resolverName}`) + return objDefineProps(resolver, SEND_MSG_FN_NAME, function(prop) { // @TODO should this get validate as well? ws.send(createWsReply(EMIT_REPLY_TYPE, resolverName, prop)) }, nil) diff --git a/packages/ws-server-core/src/share/helpers.js b/packages/ws-server-core/src/share/helpers.js index a1ccc80bd181646dbca6babe6c560bb0cf7d46a5..cdeface71c643cd292a72718279998ddcbf414e2 100644 --- a/packages/ws-server-core/src/share/helpers.js +++ b/packages/ws-server-core/src/share/helpers.js @@ -105,6 +105,10 @@ const nil = function() { } /** + * get the userdata via the decoded jwt from the request object + * @TODO we need to create a hook that let developer to plug in their own + * implementation in the future, + * therefore they could store this in a database or whatever * @param {object} req the request object * @return {object} userdata */ diff --git a/packages/ws-server-core/src/share/inter-com-handler.js b/packages/ws-server-core/src/share/inter-com-handler.js new file mode 100644 index 0000000000000000000000000000000000000000..d1948dab18c85c9c9f2c04d8afb02ac863160415 --- /dev/null +++ b/packages/ws-server-core/src/share/inter-com-handler.js @@ -0,0 +1,44 @@ + +const { getDebug } = require('./helpers') +const debug = getDebug('inter-com-handler') +const fsx = require('fs-extra') + +/** + * Find the intercom handler and return it + * OK since the two event disconnect and switch user are in fact user related + * Therefore we could put them under socket/auth folder also the socket related + * login / logout can also put in there. @TODO + * @param {object} opts configuration + * @return {boolean|function} false on not found, or the actual function call + */ +function getHandler(opts) { + const { interComEventHandlerPath } = opts + // this is up to how the developer supply this option + if (interComEventHandlerPath !== null && fsx.existsSync(interComEventHandlerPath)) { + // @TODO we should use the getResolver method to search for the handler instead + return require(interComEventHandlerPath) + } + // just return a dummy + return () => {} +} + +/** + * This will be the new intercom event handler + * we expect the user to pass an absolute path to the file that is + * going to handle this type of events + * then whenever it gets call, it will get take over by this function + * @param {string} evtType the type of the intercom event + * @param {object} opts the configuration + * @param {array} args whatever argument we received + * @return {void} + */ +function interComEventHandler(evtType, opts, args) { + const handler = getHandler(opts) + + // just debug for the time being + debug(`Hear this ${evtName}`, args) + // also call the developer supply methods, add the eventName before the args + Reflect.apply(handler, null, [evtType].concat(args)) +} + +module.exports = { interComEventHandler } \ No newline at end of file diff --git a/packages/ws-server/index.js b/packages/ws-server/index.js index 20d45af88c8f1dbe57a319aa2e0634c9b4708dbe..5a0f105944250f11ef46eb450bb16b2645b1cf8b 100644 --- a/packages/ws-server/index.js +++ b/packages/ws-server/index.js @@ -1,41 +1,17 @@ // Not going to use the koa-socket-2 due to it's lack of support namespace // which is completely useless for us if there is no namespace -const { wsSetup, wsCreateServer } = require('./src') const { checkSocketServerType, - jsonqlWsServerCore, - jsonqlWsServerCoreAction, + // props export wsServerDefaultOptions, wsServerConstProps -} = require('jsonql-ws-server-core') -// require('../ws-server-core') - -/** - * This is the method that is the actual create server without the config check - * @param {object} opts the already checked configuration - * @param {object} server the http server instance - * @return {object} the jsonql ws server instance - */ -function jsonqlWsServerAction(opts, server) { - const params = { opts, server, wsCreateServer, wsSetup } - return jsonqlWsServerCoreAction(params) -} - -/** - * The main method - * @param {object} config this is now diverse from the middleware setup - * @param {string} config.serverType socket.io or ws in the background - * @param {object} config.options the actual options to pass to the underlying setups - * @param {object} config.server this is the http/s server that required to bind to the socket to run on the same connection - * @return {mixed} return the undelying socket server instance for further use - */ -function jsonqlWsServer(config, server) { - // @TODO check the options - const setupFn = jsonqlWsServerCore(wsCreateServer, wsSetup) - return setupFn(config, server) -} +} = require('./src/core/modules') +const { + jsonqlWsServer, + jsonqlWsServerAction +} = require('./src') -// breaking change we export it as a name module +// breaking change @1.6.0 we export it as a name module module.exports = { jsonqlWsServer, jsonqlWsServerAction, diff --git a/packages/ws-server/package.json b/packages/ws-server/package.json index 6fca8078b5754bd70bf61619507b4f4385b698fa..66d8aa896d221a0ec5eee33f3f769a553327ce5e 100755 --- a/packages/ws-server/package.json +++ b/packages/ws-server/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-ws-server", - "version": "1.6.2", + "version": "1.6.3", "description": "Setup WebSocket server for the jsonql to run on the same host, automatic generate public / private channel using contract", "main": "index.js", "files": [ @@ -8,7 +8,7 @@ "src" ], "scripts": { - "test": "ava ", + "test": "ava", "prepare": "npm run test", "test:ws": "DEBUG=jsonql-ws-server* ava ./tests/ws-connect.test.js", "test:error": "DEBUG=jsonql-ws-server* ava ./tests/ws-connect-error.test.js", @@ -27,7 +27,7 @@ "author": "Joel Chu ", "license": "MIT", "dependencies": { - "jsonql-ws-server-core": "^0.5.0", + "jsonql-ws-server-core": "^0.6.0", "ws": "^7.2.1" }, "devDependencies": { diff --git a/packages/ws-server/src/core/modules.js b/packages/ws-server/src/core/modules.js new file mode 100644 index 0000000000000000000000000000000000000000..4b8635e286fccc752250657ae7508e97088d7aa8 --- /dev/null +++ b/packages/ws-server/src/core/modules.js @@ -0,0 +1,30 @@ +// keep all the import from ws-server-core in one place +// for easy switching to debug +const { + checkSocketServerType, + jsonqlWsServerCore, + jsonqlWsServerCoreAction, + wsServerDefaultOptions, + wsServerConstProps, + getNamespace, + getDebug, + createWsReply, + getUserdata, + resolveMethod, + interComEventHandler +} = require('jsonql-ws-server-core') +// require('../../../ws-server-core') + +module.exports = { + checkSocketServerType, + jsonqlWsServerCore, + jsonqlWsServerCoreAction, + wsServerDefaultOptions, + wsServerConstProps, + getNamespace, + getDebug, + createWsReply, + getUserdata, + resolveMethod, + interComEventHandler +} \ No newline at end of file diff --git a/packages/ws-server/src/core/verify-client.js b/packages/ws-server/src/core/verify-client.js index df6051b872f833e7d35d3e45b8523ce8d5e5d376..5c99496465269ae494d2ddfb95c8145e01c4bc65 100644 --- a/packages/ws-server/src/core/verify-client.js +++ b/packages/ws-server/src/core/verify-client.js @@ -8,6 +8,15 @@ const { jwtDecode } = require('jsonql-jwt') const debug = require('debug')('jsonql-jwt:ws:verify-client') +/* +old method keep for reference +const params = query.split('&') +return params.filter(param => ( + param.indexOf(TOKEN_PARAM_NAME) > -1 + )) + .reduce((f, n) => n ? n.split('=')[1] : f, false) +*/ + /** * What the name said * @param {string} uri to decode @@ -20,13 +29,6 @@ function getTokenFromQuery(uri) { return params[TOKEN_PARAM_NAME] || false } return false - /* - const params = query.split('&') - return params.filter(param => ( - param.indexOf(TOKEN_PARAM_NAME) > -1 - )) - .reduce((f, n) => n ? n.split('=')[1] : f, false) - */ } /** diff --git a/packages/ws-server/src/core/ws-create-server.js b/packages/ws-server/src/core/ws-create-server.js index 74db01d4bf6704bd2e2e3d99451d6afc1a605273..aefa2dac4b234e5d0c3bc32c7c65aa7d4db16535 100644 --- a/packages/ws-server/src/core/ws-create-server.js +++ b/packages/ws-server/src/core/ws-create-server.js @@ -3,7 +3,7 @@ const url = require('url') const WebSocket = require('ws') // need to move the method back here const { createVerifyClient } = require('./verify-client') -const { getNamespace, getDebug } = require('jsonql-ws-server-core') +const { getNamespace, getDebug } = require('./modules') const debug = getDebug('ws-setup') /** diff --git a/packages/ws-server/src/core/ws-setup.js b/packages/ws-server/src/core/ws-setup.js index c4bd3d347fa267bfbc8c9e1174fd7a023c8d85a7..8159869662272b79eff048dec7fd49674ce36321 100644 --- a/packages/ws-server/src/core/ws-setup.js +++ b/packages/ws-server/src/core/ws-setup.js @@ -7,14 +7,16 @@ const { ACKNOWLEDGE_REPLY_TYPE, ERROR_TYPE, LOGOUT_NAME, - TIMESTAMP_PARAM_NAME + TIMESTAMP_PARAM_NAME, + INTER_COM_EVENT_NAME } = require('jsonql-constants') const { getDebug, createWsReply, getUserdata, - resolveMethod -} = require('jsonql-ws-server-core') + resolveMethod, + interComEventHandler +} = require('./modules') const WS_EXIT_ID = 1 const debug = getDebug('ws-setup') @@ -121,6 +123,11 @@ const wsSetup = (opts, nspObj) => { if (resolverName === LOGOUT_EVT_NAME) { return handleLogout(ws) } + // @TODO add a bunch of other new inter comm methods here as well + if (resolverName === INTER_COM_EVENT_NAME) { + // just throw everyt into it + return interComEventHandler(ws, req, json, socketFns, opts, getUserdata(req)) + } // only allow the method under that particular namespace if (methodsInNsp[resolverName]) { debug('methodsInNsp[resolverName]', methodsInNsp[resolverName]) diff --git a/packages/ws-server/src/index.js b/packages/ws-server/src/index.js index b1fcdd75e3ad2e5e7ae56b92a8a5ed7dd9b79e3b..5defcddf5f280b25f57aad857629cb163de82b8f 100644 --- a/packages/ws-server/src/index.js +++ b/packages/ws-server/src/index.js @@ -1,8 +1,39 @@ // re-export here const { wsCreateServer } = require('./core/ws-create-server') const { wsSetup } = require('./core/ws-setup') -// re-export +// move back from the root index.js +const { + jsonqlWsServerCore, + jsonqlWsServerCoreAction +} = require('./core/modules') + +/** + * This is the method that is the actual create server without the config check + * @param {object} opts the already checked configuration + * @param {object} server the http server instance + * @return {object} the jsonql ws server instance + */ +function jsonqlWsServerAction(opts, server) { + const params = { opts, server, wsCreateServer, wsSetup } + return jsonqlWsServerCoreAction(params) +} + +/** + * The main method + * @param {object} config this is now diverse from the middleware setup + * @param {string} config.serverType socket.io or ws in the background + * @param {object} config.options the actual options to pass to the underlying setups + * @param {object} config.server this is the http/s server that required to bind to the socket to run on the same connection + * @return {mixed} return the undelying socket server instance for further use + */ +function jsonqlWsServer(config, server) { + // @TODO check the options + const setupFn = jsonqlWsServerCore(wsCreateServer, wsSetup) + return setupFn(config, server) +} + + module.exports = { - wsSetup, - wsCreateServer + jsonqlWsServerAction, + jsonqlWsServer }