From 07041ea2d76d803540b32ba17e046c6ed5c96c84 Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 10 Mar 2020 14:40:01 +0800 Subject: [PATCH 1/7] code are in place, need to setup a new test env to test it --- packages/ws-server-core/index.js | 19 +----- packages/ws-server-core/package.json | 2 +- .../src/handles/get-socket-handler.js | 68 +++++++++++++++++-- .../src/handles/handle-nsp-resolvers.js | 56 ++++++++------- packages/ws-server-core/src/handles/index.js | 14 +--- packages/ws-server-core/src/share/helpers.js | 21 +++--- .../ws-server-core/src/share/run-resolver.js | 37 ---------- 7 files changed, 114 insertions(+), 103 deletions(-) delete mode 100644 packages/ws-server-core/src/share/run-resolver.js diff --git a/packages/ws-server-core/index.js b/packages/ws-server-core/index.js index 31e0bb53..f9ef9a3f 100644 --- a/packages/ws-server-core/index.js +++ b/packages/ws-server-core/index.js @@ -16,10 +16,6 @@ const { const { addProperty } = require('./src/share/add-property') const { getContract } = require('./src/share/get-contract') - -const { resolveSocketMethod } = require('./src/share/resolve-socket-method') -const { runResolver } = require('./src/share/run-resolver') - const { createWsReply, getDebug, @@ -37,11 +33,7 @@ const { const jsonqlWsCoreConstants = require('./src/options/constants') const { - handleInterCom, - handleLogout, - handleStandaloneLogin, - handleUnknownPayload, - handleNspResolvers + getSocketHandler } = require('./src/handles') // export every bits out then the downstream build as they want @@ -60,8 +52,7 @@ module.exports = { getUserdata, isUserdata, prepareUserdata, - resolveSocketMethod, - runResolver, + // just uniform until method, really should be in the jsonql-utils/node getDebug, getRainbowDebug, @@ -76,9 +67,5 @@ module.exports = { jsonqlWsServerCore, jsonqlWsServerCoreAction, // @0.6.0 - handleInterCom, - handleLogout, - handleStandaloneLogin, - handleUnknownPayload, - handleNspResolvers + getSocketHandler } diff --git a/packages/ws-server-core/package.json b/packages/ws-server-core/package.json index 0f5026fa..9188b1e8 100644 --- a/packages/ws-server-core/package.json +++ b/packages/ws-server-core/package.json @@ -34,7 +34,7 @@ "jsonql-jwt": "^1.3.9", "jsonql-params-validator": "^1.5.2", "jsonql-resolver": "^1.1.1", - "jsonql-utils": "^1.0.5", + "jsonql-utils": "^1.0.6", "lodash": "^4.17.15" }, "devDependencies": { diff --git a/packages/ws-server-core/src/handles/get-socket-handler.js b/packages/ws-server-core/src/handles/get-socket-handler.js index c4ca27e6..1e4f5d32 100644 --- a/packages/ws-server-core/src/handles/get-socket-handler.js +++ b/packages/ws-server-core/src/handles/get-socket-handler.js @@ -1,14 +1,74 @@ +const { + LOGOUT_EVENT_NAME, + SA_LOGIN_EVENT_NAME, + INTER_COM_EVENT_NAME +} = require('jsonql-constants') +const { SOCKET_STATE_KEY } = require('../options/constants') + const { handleInterCom } = require('./handle-intercom') const { handleLogout } = require('./handle-logout') const { handleStandaloneLogin } = require('./handle-standalone-login') -const { handleUnknownPayload } = require('./handle-unknown-payload') const { handleNspResolvers } = require('./handle-nsp-resolvers') +// @TBC do we need this const { handleUnknownPayload } = require('./handle-unknown-payload') +const { getRainbowDebug } = require('../share/helpers') + +const debug = getRainbowDebug('handles:get-socket-handler') + +/** + * Make sure the resolver is belongs to this namespace + * @param {string} resolverName calling from + * @param {string} namespace currently connected namespace + * @param {object} nspGroup namespace --> resolvers object map + * @return {*} false when not found, or the params from the resolver + */ +function matchResolverByNamespace(resolverName, namespace, nspGroup) { + const g = nspGroup[namespace] + if (g && g[resolverName]) { + return g[resolverName] + } + debug(`matchResolverByNamespace`, `${resolverName} is not in ${namespace}`) + // we fail this silencely for now and see what happen + return false + // throw new Error(`nspGroup does not have this group ${namespace}`) +} + + /** * This is the generic methods that will be wrap inside the on.message (for ws) * all it takes it how to delivery the message back * @param {object} config full configuration - * + * @param {object} ws The socket server instance for injection + * @param {function} deliverFn a wrapper method to deliver the message + * @param {object} req the request object + * @param {string} connectedNamespace which namespace is this calling from + * @param {object} payload from the message call + * @param {object|boolean} userdata if any + * @return {void} unless we throw an error */ -function getSocketHandler(config) { - +function getSocketHandler(config, ws, deliverFn, req, connectedNamespace, payload, userdata) { + const { nspInfo, enableAuth } = config + const { namespaces, publicNamespace, size, nspGroup } = nspInfo + const resolverName = getNameFromPayload(payload) + const args = payload[resolverName] + // it might be the special internal event? + switch (true) { + + case resolverName === LOGOUT_EVENT_NAME: + // we don't need to send anything back @TBC do we need the config + return handleLogout(ws, req, args, config) + + case resolverName === SA_LOGIN_EVENT_NAME: + return handleStandaloneLogin(deliverFn, ws, req, args, config) + + case resolverName === INTER_COM_EVENT_NAME: + // We don't need to send anything back // @TBC do we need the config + return handleInterCom(config, ws, req, args, userdata) + + default: + + const params = matchResolverByNamespace(resolverName, namespace, nspGroup) + + handleNspResolvers(deliverFn, ws, resolverName, args, params, config, userdata) + } + } diff --git a/packages/ws-server-core/src/handles/handle-nsp-resolvers.js b/packages/ws-server-core/src/handles/handle-nsp-resolvers.js index 69a087f9..6d133541 100644 --- a/packages/ws-server-core/src/handles/handle-nsp-resolvers.js +++ b/packages/ws-server-core/src/handles/handle-nsp-resolvers.js @@ -1,35 +1,41 @@ // make this more generic and share it to create resolver for each nsp // @TODO this property still not create correctly -const { TIMESTAMP_PARAM_NAME } = require('jsonql-constants') - -const { runResolver } = require('../share/run-resolver') -const { getDebug } = require('../share/helpers') - -const debug = getDebug('handle-nsp') +// const { TIMESTAMP_PARAM_NAME } = require('jsonql-constants') +// get the resolver to handle the request +const { validateInput, deliverMsg } = require('../share/resolver-methods') +const { resolveSocketMethod } = require('../share/resolve-socket-method') +const { getDebug } = require('./helpers') +const debug = getDebug('share:get-resolver') /** - * The default single nsp mapping to resolver + * handle resolvers * @param {function} deliverFn the final delivery message method - * @param {object} ws the socket instance inject to resolver as property - * @param {object} json data send from client - * @param {object} socketFns contract + * @param {object} ws the socket instance get add to the resolver as property + * @param {string} resolverName name of resolver + * @param {*} args from payload + * @param {object} params from contract.json * @param {object} opts configuration - * @param {*} [userdata=false] userdata if any - * @return {void} nothing - */ -const handleNspResolvers = (deliverFn, ws, json, socketFns, opts, userdata = false) => { - debug('TIMESTAMP_PARAM_NAME', json[TIMESTAMP_PARAM_NAME], TIMESTAMP_PARAM_NAME) + * @param {object} userdata userdata + * @return {promise} resolve the result + */ +const handleNspResolvers = (deliverFn, ws, resolverName, args, params, opts, userdata) => { + // debug('TIMESTAMP_PARAM_NAME', json[TIMESTAMP_PARAM_NAME], TIMESTAMP_PARAM_NAME) // const ts = json[TIMESTAMP_PARAM_NAME] // keep this for use later - for (let resolverName in json) { - if (resolverName !== TIMESTAMP_PARAM_NAME) { // dirty hack for now - debug('connection call', resolverName) - let payload = json[resolverName] - let params = socketFns[resolverName] - // we need to use the decoded token --> userdata - // and pass to the resolver - runResolver(deliverFn, ws, payload, resolverName, params, opts, userdata) - } - } + // @NOTE the params.params is from the contract + return validateInput(args, params) + .then(args => resolveSocketMethod( + deliverFn, + resolverName, + args, // this is the clean value from validateAsync + params, + opts, + ws, + userdata + ) + ) + .then( + result => deliveryMsg(deliverFn, result, resolverName) + ) } module.exports = { handleNspResolvers } diff --git a/packages/ws-server-core/src/handles/index.js b/packages/ws-server-core/src/handles/index.js index ce6a5289..7ce78d1e 100644 --- a/packages/ws-server-core/src/handles/index.js +++ b/packages/ws-server-core/src/handles/index.js @@ -1,15 +1,5 @@ // All these methods move from the ws-server // we need to make them all generic -const { handleInterCom } = require('./handle-intercom') -const { handleLogout } = require('./handle-logout') -const { handleStandaloneLogin } = require('./handle-standalone-login') -const { handleUnknownPayload } = require('./handle-unknown-payload') -const { handleNspResolvers } = require('./handle-nsp-resolvers') +const { getSocketHandler } = require('./get-socket-handler') -module.exports = { - handleInterCom, - handleLogout, - handleStandaloneLogin, - handleUnknownPayload, - handleNspResolvers // @0.6.2 rename from handleNsp make more sense -} +module.exports = { getSocketHandler } diff --git a/packages/ws-server-core/src/share/helpers.js b/packages/ws-server-core/src/share/helpers.js index b639e3f1..9ff343c0 100644 --- a/packages/ws-server-core/src/share/helpers.js +++ b/packages/ws-server-core/src/share/helpers.js @@ -6,7 +6,8 @@ const { WS_EVT_NAME, WS_DATA_NAME, SOCKET_CLIENT_ID_KEY, - SOCKET_CLIENT_TS_KEY + SOCKET_CLIENT_TS_KEY, + TIMESTAMP_PARAM_NAME } = require('jsonql-constants') const { MODULE_NAME, @@ -17,6 +18,7 @@ const { clientErrorsHandler } = require('jsonql-errors') const { + nil, // moved to the jsonql-utils toJson, isObjectHasKey, isFunc, @@ -37,6 +39,14 @@ const WS_KEYS = [ WS_DATA_NAME ] +// @TODO move this to jsonql-utils once its all test and done + +const getResolverFromPayload = payload => { + const keys = Object.keys(payload) + return keys.filter(key => key !== TIMESTAMP_PARAM_NAME)[0] +} + + /** * Create the debug instance @@ -112,11 +122,6 @@ const extractWsPayload = payload => { throw new JsonqlError('payload can not decoded', payload) } -// just an empty method for addProperty getter -function nil() { - return false -} - /** * Should this be elsewhere because this is * get the userdata via the decoded jwt from the request object @@ -159,13 +164,12 @@ function isUserdata(userdata) { /** * Take this out from the ws-setup because we need the same prop for the ws-create-server now + * @0.7.0 just a wrapper now but keep all the module import in one place * @param {object} opts configuration * @return {object} nspInfo */ function getNspInfo(opts) { return getNspInfoByConfig(opts) - // const { contract } = opts - // return groupByNamespace(contract) } @@ -185,5 +189,6 @@ module.exports = { nil, isFunc, + getResolverFromPayload, getNspInfo } diff --git a/packages/ws-server-core/src/share/run-resolver.js b/packages/ws-server-core/src/share/run-resolver.js deleted file mode 100644 index 29deb92a..00000000 --- a/packages/ws-server-core/src/share/run-resolver.js +++ /dev/null @@ -1,37 +0,0 @@ -// get the resolver to handle the request -const { validateInput, deliverMsg } = require('./resolver-methods') -const { resolveSocketMethod } = require('./resolve-socket-method') -const { getDebug } = require('./helpers') -const debug = getDebug('share:get-resolver') - -/** - * handle resolvers - * @param {function} deliverFn the final delivery message method - * @param {object} ws the socket instance get add to the resolver as property - * @param {object} payload args array - * @param {string} resolverName name of resolver - * @param {object} params from contract.json - * @param {object} opts configuration - * @param {object} userdata userdata - */ -function runResolver(deliverFn, ws, payload, resolverName, params, opts, userdata) { - // @NOTE the params.params is from the contract - return validateInput(payload.args, params.params) - .then(args => resolveSocketMethod( - deliverFn, - resolverName, - args, // this is the clean value from validateAsync - params, - opts, - ws, - userdata - ) - ) - .then(result => deliveryMsg(deliverFn, result, resolverName)) -} - -module.exports = { - runResolver - // deliveryMsg, - // validateInput -} -- Gitee From 20c339d4a19fce9b6fc1ae040e568b8f1baab19e Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 10 Mar 2020 14:51:44 +0800 Subject: [PATCH 2/7] add new files for test --- packages/contract-cli/package.json | 12 ++++++------ .../tests/fixtures/es/auth/login.js | 8 ++++++++ packages/contract-cli/tests/generator.test.js | 3 ++- .../tests/fixtures/jwt/contract.json | 2 +- .../tests/fixtures/resolvers/auth/login.js | 9 +++++++++ .../tests/fixtures/resolvers/auth/logout.js | 7 +++++++ .../resolvers/socket/auth/disconnect.js | 10 ++++++++++ .../fixtures/resolvers/socket/auth/login.js | 17 +++++++++++++++++ .../fixtures/resolvers/socket/auth/logout.js | 10 ++++++++++ .../fixtures/resolvers/socket/cause-error.js | 10 ++++++++++ .../fixtures/resolvers/socket/chatroom.js | 12 ++++++++++++ .../fixtures/resolvers/socket/delay-fn.js | 15 +++++++++++++++ .../socket/private/secret-chatroom.js | 14 ++++++++++++++ .../public/available-to-everyone/index.js | 9 +++++++++ .../fixtures/resolvers/socket/ws-handler.js | 18 ++++++++++++++++++ 15 files changed, 148 insertions(+), 8 deletions(-) create mode 100644 packages/contract-cli/tests/fixtures/es/auth/login.js create mode 100644 packages/ws-server-core/tests/fixtures/resolvers/auth/login.js create mode 100644 packages/ws-server-core/tests/fixtures/resolvers/auth/logout.js create mode 100644 packages/ws-server-core/tests/fixtures/resolvers/socket/auth/disconnect.js create mode 100644 packages/ws-server-core/tests/fixtures/resolvers/socket/auth/login.js create mode 100644 packages/ws-server-core/tests/fixtures/resolvers/socket/auth/logout.js create mode 100644 packages/ws-server-core/tests/fixtures/resolvers/socket/cause-error.js create mode 100644 packages/ws-server-core/tests/fixtures/resolvers/socket/chatroom.js create mode 100644 packages/ws-server-core/tests/fixtures/resolvers/socket/delay-fn.js create mode 100644 packages/ws-server-core/tests/fixtures/resolvers/socket/private/secret-chatroom.js create mode 100644 packages/ws-server-core/tests/fixtures/resolvers/socket/public/available-to-everyone/index.js create mode 100644 packages/ws-server-core/tests/fixtures/resolvers/socket/ws-handler.js diff --git a/packages/contract-cli/package.json b/packages/contract-cli/package.json index 47fa1311..7e6af26a 100755 --- a/packages/contract-cli/package.json +++ b/packages/contract-cli/package.json @@ -36,7 +36,7 @@ "nodejs", "node" ], - "author": "to1soure ", + "author": "to1soure ", "contributors": [ "Joel Chu " ], @@ -45,24 +45,24 @@ "jsonql-contract": "./cli.js" }, "dependencies": { - "acorn": "^7.1.0", + "acorn": "^7.1.1", "chokidar": "^3.3.1", "colors": "^1.4.0", "debug": "^4.1.1", "fs-extra": "^8.1.0", "glob": "^7.1.6", "jsdoc-api": "^5.0.4", - "jsonql-constants": "^1.8.14", + "jsonql-constants": "^1.9.8", "jsonql-errors": "^1.1.10", "jsonql-params-validator": "^1.5.2", - "jsonql-utils": "^0.9.7", + "jsonql-utils": "^1.0.6", "kefir": "^3.8.6", "lodash": "^4.17.15", "nb-split-tasks": "^0.6.0", - "yargs": "^15.1.0" + "yargs": "^15.3.0" }, "devDependencies": { - "ava": "^3.3.0", + "ava": "^3.5.0", "nyc": "^15.0.0" }, "ava": { diff --git a/packages/contract-cli/tests/fixtures/es/auth/login.js b/packages/contract-cli/tests/fixtures/es/auth/login.js new file mode 100644 index 00000000..61dceb16 --- /dev/null +++ b/packages/contract-cli/tests/fixtures/es/auth/login.js @@ -0,0 +1,8 @@ +/** + * @param {string} username username + * @param {string} password password + * @return {object} user object + */ +export default function login(username, password) { + return { username, ts: Date.now() } +} diff --git a/packages/contract-cli/tests/generator.test.js b/packages/contract-cli/tests/generator.test.js index 509b0f14..e593fd8e 100755 --- a/packages/contract-cli/tests/generator.test.js +++ b/packages/contract-cli/tests/generator.test.js @@ -24,7 +24,7 @@ const esContractDir = join(__dirname, 'fixtures', 'tmp', 'es') const esResolverDir = join(__dirname, 'fixtures', 'es') -const expired = Date.now() + 60*365*1000; +const expired = Date.now() + 60*365*1000 test.after(async t => { fsx.removeSync(contractDir) @@ -69,6 +69,7 @@ test.serial('Should able to create a public-contract.json', async t => { t.is(json.expired, expired) t.false(!!json.auth.validator) + // there is no auth in there t.true(json.auth.login !== undefined) // now check if certain method is public t.true(json.query.anyoneCanGetThis.public) diff --git a/packages/node-client/tests/fixtures/jwt/contract.json b/packages/node-client/tests/fixtures/jwt/contract.json index 136cadac..eb0a4f8e 100644 --- a/packages/node-client/tests/fixtures/jwt/contract.json +++ b/packages/node-client/tests/fixtures/jwt/contract.json @@ -102,7 +102,7 @@ ] } }, - "timestamp": 1582268247, + "timestamp": 1583822724, "sourceType": "script", "socket": { "gateway": { diff --git a/packages/ws-server-core/tests/fixtures/resolvers/auth/login.js b/packages/ws-server-core/tests/fixtures/resolvers/auth/login.js new file mode 100644 index 00000000..8aa25247 --- /dev/null +++ b/packages/ws-server-core/tests/fixtures/resolvers/auth/login.js @@ -0,0 +1,9 @@ + +/** + * create a login method for testing + * @param {string} username username + * @return {object} userdata + */ +module.exports = function login(username) { + return {name: username} +} diff --git a/packages/ws-server-core/tests/fixtures/resolvers/auth/logout.js b/packages/ws-server-core/tests/fixtures/resolvers/auth/logout.js new file mode 100644 index 00000000..b5957eb2 --- /dev/null +++ b/packages/ws-server-core/tests/fixtures/resolvers/auth/logout.js @@ -0,0 +1,7 @@ +/** + * testing the logout method call + * @return {boolean} true + */ +module.exports = function logout() { + return true; +} diff --git a/packages/ws-server-core/tests/fixtures/resolvers/socket/auth/disconnect.js b/packages/ws-server-core/tests/fixtures/resolvers/socket/auth/disconnect.js new file mode 100644 index 00000000..b6c7462c --- /dev/null +++ b/packages/ws-server-core/tests/fixtures/resolvers/socket/auth/disconnect.js @@ -0,0 +1,10 @@ +const debug = require('debug')('ws-client-core:fixtures:auth:disconnect') +/** + * Intercept the disconnect event + * @param {array} args + * @return {void} + */ +module.exports = function disconnect(...args) { + // @TODO + debug('intercept the disconnect event', args) +} \ No newline at end of file diff --git a/packages/ws-server-core/tests/fixtures/resolvers/socket/auth/login.js b/packages/ws-server-core/tests/fixtures/resolvers/socket/auth/login.js new file mode 100644 index 00000000..c95e24b9 --- /dev/null +++ b/packages/ws-server-core/tests/fixtures/resolvers/socket/auth/login.js @@ -0,0 +1,17 @@ +/** + * Standalone mode to allow using the socket server to login + * @param {string} username + * @param {string} password + * @return {object} a user object then package as jwt string (internal process) + */ +module.exports = function login(username, password) { + const users = [{name: 'joel', pass: '1234'} , {name: 'davided', pass: '5678'}] + const user = users.filter(user => username === user.name && password === user.pass) + .reduce((base, user) => { + return user + }, false) + if (user !== false) { + return user + } + throw new Error(`User not found!`) +} \ No newline at end of file diff --git a/packages/ws-server-core/tests/fixtures/resolvers/socket/auth/logout.js b/packages/ws-server-core/tests/fixtures/resolvers/socket/auth/logout.js new file mode 100644 index 00000000..354a5828 --- /dev/null +++ b/packages/ws-server-core/tests/fixtures/resolvers/socket/auth/logout.js @@ -0,0 +1,10 @@ +const debug = require('debug')('ws-client-core:fixtures:auth:logout') +/** + * Intercept the login event + * @param {array} args + * @return {void} + */ +module.exports = function logout(...args) { + // @TODO + debug(`Intercept the logout event`, args) +} \ No newline at end of file diff --git a/packages/ws-server-core/tests/fixtures/resolvers/socket/cause-error.js b/packages/ws-server-core/tests/fixtures/resolvers/socket/cause-error.js new file mode 100644 index 00000000..c49b9ab0 --- /dev/null +++ b/packages/ws-server-core/tests/fixtures/resolvers/socket/cause-error.js @@ -0,0 +1,10 @@ +// this method will throw an error + +/** + * @param {string} msg a message + * @return {string} a message but here we throw an error + */ +module.exports = function causeError(msg) { + causeError.send('something else') + throw new Error(msg) +} diff --git a/packages/ws-server-core/tests/fixtures/resolvers/socket/chatroom.js b/packages/ws-server-core/tests/fixtures/resolvers/socket/chatroom.js new file mode 100644 index 00000000..0b57676e --- /dev/null +++ b/packages/ws-server-core/tests/fixtures/resolvers/socket/chatroom.js @@ -0,0 +1,12 @@ +// a private method + +/** + * + * @param {string} msg message + * @param {number} timestamp for checking the time + * @return {string} reply + */ +module.exports = function(msg, timestamp) { + const d = Date.now() - timestamp; + return msg + ` took ${d} ms`; +} diff --git a/packages/ws-server-core/tests/fixtures/resolvers/socket/delay-fn.js b/packages/ws-server-core/tests/fixtures/resolvers/socket/delay-fn.js new file mode 100644 index 00000000..523ed5c1 --- /dev/null +++ b/packages/ws-server-core/tests/fixtures/resolvers/socket/delay-fn.js @@ -0,0 +1,15 @@ +// test this with a Promise return result +/** + * @param {string} msg a message + * @param {number} timestamp a timestamp + */ +module.exports = function delayFn(msg, timestamp) { + // also test the global socket instance + delayFn.send = 'I am calling from delayFn'; + + return new Promise(resolver => { + setTimeout(() => { + resolver(msg + (Date.now() - timestamp)) + }, 1000) + }) +} diff --git a/packages/ws-server-core/tests/fixtures/resolvers/socket/private/secret-chatroom.js b/packages/ws-server-core/tests/fixtures/resolvers/socket/private/secret-chatroom.js new file mode 100644 index 00000000..34ba0ac3 --- /dev/null +++ b/packages/ws-server-core/tests/fixtures/resolvers/socket/private/secret-chatroom.js @@ -0,0 +1,14 @@ +const { debug } = require('../../../../../src/utils') +/** + * @param {string} room room name + * @param {*} msg message to that room + * @return {*} depends + */ +module.exports = function secretChatroom(room, msg) { + + debug('secretChatroom.userdata', secretChatroom.userdata) + + let userdata = secretChatroom.userdata + // @TODO + return `send ${msg+''} to ${room} room from ${userdata.name}` +} diff --git a/packages/ws-server-core/tests/fixtures/resolvers/socket/public/available-to-everyone/index.js b/packages/ws-server-core/tests/fixtures/resolvers/socket/public/available-to-everyone/index.js new file mode 100644 index 00000000..16b326f9 --- /dev/null +++ b/packages/ws-server-core/tests/fixtures/resolvers/socket/public/available-to-everyone/index.js @@ -0,0 +1,9 @@ +// This method for testing the public call + +/** + * There is no parameter require for this call + * @return {string} a message + */ +module.exports = function availableToEveryone() { + return 'You get a public message'; +} diff --git a/packages/ws-server-core/tests/fixtures/resolvers/socket/ws-handler.js b/packages/ws-server-core/tests/fixtures/resolvers/socket/ws-handler.js new file mode 100644 index 00000000..7831c9cb --- /dev/null +++ b/packages/ws-server-core/tests/fixtures/resolvers/socket/ws-handler.js @@ -0,0 +1,18 @@ +// will test this one with the send property + +/** + * method just for testing the ws + * @param {string} msg message + * @param {number} timestamp timestamp + * @return {string} msg + time lapsed + */ +module.exports = function wsHandler(msg, timestamp) { + const ts = Date.now() + wsHandler.send('I am sending a message back from ws', ts) + + return new Promise(resolver => { + setTimeout(() => { + resolver(msg + ' - ' +(ts - timestamp)) + }, 1000) + }) +} -- Gitee From bc710d7591d3175fcb3dfb4487a757d0f65a04f9 Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 10 Mar 2020 15:08:50 +0800 Subject: [PATCH 3/7] ATOM hide the .gitignore files PIA --- packages/contract-cli/src/options.js | 10 ++++---- .../tests/fixtures/resolvers/auth/login.js | 2 +- packages/contract-cli/tests/generator.test.js | 24 ++++++++++--------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/packages/contract-cli/src/options.js b/packages/contract-cli/src/options.js index a0172116..749f4479 100644 --- a/packages/contract-cli/src/options.js +++ b/packages/contract-cli/src/options.js @@ -19,7 +19,7 @@ const { ENUM_KEY, RETURN_AS_FILE, RETURN_AS_ENUM, - ISSUER_NAME, + LOGIN_NAME, LOGOUT_NAME, VALIDATOR_NAME, DEFAULT_CONTRACT_FILE_NAME @@ -35,10 +35,10 @@ const constProps = { const defaultOptions = { // give the contract an expired time expired: createConfig(0, [NUMBER_TYPE]), - // passing extra props to the contract.json + // passing extra props to the contract.json extraContractProps: createConfig(false, [OBJECT_TYPE], {[OPTIONAL_KEY]: true}), - // Auth related props - loginHandlerName: createConfig(ISSUER_NAME, [STRING_TYPE]), + // Auth related props + loginHandlerName: createConfig(LOGIN_NAME, [STRING_TYPE]), logoutHandlerName: createConfig(LOGOUT_NAME, [STRING_TYPE]), validatorHandlerName: createConfig(VALIDATOR_NAME, [STRING_TYPE, BOOLEAN_TYPE]), @@ -73,7 +73,7 @@ const defaultOptions = { buildContractOnStart: constructConfig(false, [BOOLEAN_TYPE], true), // @1.8.x enable or disable the split tasks enableSplitTask: createConfig(false, [BOOLEAN_TYPE]), - // add 1.8.7 to determine if we clean out the contract folder or not + // add 1.8.7 to determine if we clean out the contract folder or not development: createConfig(false, [BOOLEAN_TYPE]) } // export it diff --git a/packages/contract-cli/tests/fixtures/resolvers/auth/login.js b/packages/contract-cli/tests/fixtures/resolvers/auth/login.js index 9ffab69d..fba911ac 100755 --- a/packages/contract-cli/tests/fixtures/resolvers/auth/login.js +++ b/packages/contract-cli/tests/fixtures/resolvers/auth/login.js @@ -5,5 +5,5 @@ * @return {boolean} result */ module.exports = function(username, password) { - return true; + return true } diff --git a/packages/contract-cli/tests/generator.test.js b/packages/contract-cli/tests/generator.test.js index e593fd8e..7adf0c8b 100755 --- a/packages/contract-cli/tests/generator.test.js +++ b/packages/contract-cli/tests/generator.test.js @@ -10,25 +10,25 @@ const { DEFAULT_RESOLVER_LIST_FILE_NAME, DEFAULT_RESOLVER_IMPORT_FILE_NAME } = require('jsonql-constants'); -const resolverDir = join(__dirname, 'fixtures', 'resolvers') -const contractDir = join(__dirname, 'fixtures', 'tmp', 'with-auth') + const debug = require('debug')('jsonql-contract:test:generator') const fsx = require('fs-extra') const generator = require('../index') +const resolverDir = join(__dirname, 'fixtures', 'resolvers') +const contractDir = join(__dirname, 'fixtures', 'tmp', 'with-auth') const baseContractFile = join(contractDir, DEFAULT_CONTRACT_FILE_NAME) const publicContractFile = join(contractDir, PUBLIC_CONTRACT_FILE_NAME) const esContractDir = join(__dirname, 'fixtures', 'tmp', 'es') const esResolverDir = join(__dirname, 'fixtures', 'es') - const expired = Date.now() + 60*365*1000 test.after(async t => { - fsx.removeSync(contractDir) - fsx.removeSync(esContractDir) + // fsx.removeSync(contractDir) + // fsx.removeSync(esContractDir) // remove the two generate files // @NOTE remove these two files in 1.7.21 // fsx.removeSync( join(esResolverDir, DEFAULT_RESOLVER_LIST_FILE_NAME) ) @@ -53,8 +53,8 @@ test.serial('There should be a contract.json output to the contractDir', async t }) t.is(true, fsx.existsSync( baseContractFile )) }) - -test.serial('Should able to create a public-contract.json', async t => { +// serial. +test.only('Should able to create a public-contract.json', async t => { const result = await generator({ resolverDir, contractDir, @@ -63,16 +63,18 @@ test.serial('Should able to create a public-contract.json', async t => { public: true }) + debug('public-contract.json', result) + t.true(fsx.existsSync(publicContractFile)) const json = fsx.readJsonSync(publicContractFile) - t.is(json.expired, expired) + t.is(json.expired, expired, 'Expired field should be the same as what is given') - t.false(!!json.auth.validator) + t.false(!!json.auth.validator, 'should not have a validator field') // there is no auth in there - t.true(json.auth.login !== undefined) + t.true(json.auth.login !== undefined, 'should have a login') // now check if certain method is public - t.true(json.query.anyoneCanGetThis.public) + t.true(json.query.anyoneCanGetThis.public, 'anyoneCanGetThis should be public') // now check if certain method in private folder is included // t.truthy(json.query.privateFn) // check for namespace -- Gitee From 851b83a15a27a9210ee1626b3ce28eb8d28c9477 Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 10 Mar 2020 16:35:18 +0800 Subject: [PATCH 4/7] add the user interceptor method for socket features --- .../tests/fixtures/resolvers/socket/auth/login.js | 9 +++++++++ .../tests/fixtures/resolvers/socket/auth/logout.js | 11 +++++++++++ packages/contract-cli/tests/socket.test.js | 6 ++++++ 3 files changed, 26 insertions(+) create mode 100644 packages/contract-cli/tests/fixtures/resolvers/socket/auth/login.js create mode 100644 packages/contract-cli/tests/fixtures/resolvers/socket/auth/logout.js create mode 100644 packages/contract-cli/tests/socket.test.js diff --git a/packages/contract-cli/tests/fixtures/resolvers/socket/auth/login.js b/packages/contract-cli/tests/fixtures/resolvers/socket/auth/login.js new file mode 100644 index 00000000..853afcc0 --- /dev/null +++ b/packages/contract-cli/tests/fixtures/resolvers/socket/auth/login.js @@ -0,0 +1,9 @@ +/** + * When the socket in standalone mode this should get take into the contract as well + * @param {string} username username + * @param {string} password password + * @return {object} userdata + */ +module.exports = function login(username, password) { + return { username, ts: Date.now() } +} diff --git a/packages/contract-cli/tests/fixtures/resolvers/socket/auth/logout.js b/packages/contract-cli/tests/fixtures/resolvers/socket/auth/logout.js new file mode 100644 index 00000000..81e94eae --- /dev/null +++ b/packages/contract-cli/tests/fixtures/resolvers/socket/auth/logout.js @@ -0,0 +1,11 @@ +/** + * logout interceptor + * @param {object} userdata the user that just logout + * @return {void} + */ +module.exports = function logout(userdata) { + // when user logout from the nsp, they will send one last call with their userdata + // to notify the server that this user has logout + // if this file presented then this interceptor will get call + console.log(userdata, 'just logout') +} diff --git a/packages/contract-cli/tests/socket.test.js b/packages/contract-cli/tests/socket.test.js new file mode 100644 index 00000000..209e8e84 --- /dev/null +++ b/packages/contract-cli/tests/socket.test.js @@ -0,0 +1,6 @@ +// develop the new socket auth feature for contract +const test = require('ava') +const { join } = require('path') +const fsx = require('fs-extra') + +const resolverDir = join(__dirname, 'fixtures', 'resolvers') -- Gitee From 679958628485f1840b2588b91ee1bc02116e776b Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 10 Mar 2020 16:44:10 +0800 Subject: [PATCH 5/7] move the options into its own folder and break up the prop into constants --- .../contract-cli/src/options/constants.js | 23 +++++++++ .../src/{options.js => options/index.js} | 47 +++++++++++++------ 2 files changed, 55 insertions(+), 15 deletions(-) create mode 100644 packages/contract-cli/src/options/constants.js rename packages/contract-cli/src/{options.js => options/index.js} (74%) diff --git a/packages/contract-cli/src/options/constants.js b/packages/contract-cli/src/options/constants.js new file mode 100644 index 00000000..cf8d1cf0 --- /dev/null +++ b/packages/contract-cli/src/options/constants.js @@ -0,0 +1,23 @@ +// take those inline value out and create constants here +// to keep the no magic value +const BASE_DIR = process.cwd() +const AUTH_ALIAS = 'auth' +const IN_DIR_ALIAS = 'inDir' +const OUT_DIR_ALIAS = 'outDir' +const WATCH_ALIAS = 'w' +const INTERVAL_ALIAS = 'i' +const CONFIG_FILE_ALIAS = 'c' +const TMP_DIR = 'tmp' +const STANDALONE_ALIAS = 'standaloneSocketMode' + +module.exports = { + BASE_DIR, + AUTH_ALIAS, + IN_DIR_ALIAS, + OUT_DIR_ALIAS, + WATCH_ALIAS, + INTERVAL_ALIAS, + CONFIG_FILE_ALIAS, + TMP_DIR, + STANDALONE_ALIAS +} diff --git a/packages/contract-cli/src/options.js b/packages/contract-cli/src/options/index.js similarity index 74% rename from packages/contract-cli/src/options.js rename to packages/contract-cli/src/options/index.js index 749f4479..8080c85b 100644 --- a/packages/contract-cli/src/options.js +++ b/packages/contract-cli/src/options/index.js @@ -1,8 +1,11 @@ // default options @TODO add in the next upgrade - -const { resolve, join } = require('path') const fs = require('fs') -const { checkConfigAsync, constructConfig, createConfig } = require('jsonql-params-validator') +const { resolve, join } = require('path') +const { + checkConfigAsync, + constructConfig, + createConfig +} = require('jsonql-params-validator') const { DEFAULT_RESOLVER_DIR, DEFAULT_CONTRACT_DIR, @@ -24,14 +27,24 @@ const { VALIDATOR_NAME, DEFAULT_CONTRACT_FILE_NAME } = require('jsonql-constants') +const { + BASE_DIR, + AUTH_ALIAS, + IN_DIR_ALIAS, + OUT_DIR_ALIAS, + WATCH_ALIAS, + INTERVAL_ALIAS, + CONFIG_FILE_ALIAS, + TMP_DIR, + STANDALONE_ALIAS +} = require('./constants') -const BASE_DIR = process.cwd() - +// injecter after check const constProps = { BASE_DIR, outputFilename: DEFAULT_CONTRACT_FILE_NAME } - +// base checking map const defaultOptions = { // give the contract an expired time expired: createConfig(0, [NUMBER_TYPE]), @@ -42,7 +55,7 @@ const defaultOptions = { logoutHandlerName: createConfig(LOGOUT_NAME, [STRING_TYPE]), validatorHandlerName: createConfig(VALIDATOR_NAME, [STRING_TYPE, BOOLEAN_TYPE]), - enableAuth: createConfig(false, BOOLEAN_TYPE, {[ALIAS_KEY]: 'auth'}), + enableAuth: createConfig(false, BOOLEAN_TYPE, {[ALIAS_KEY]: AUTH_ALIAS}), // file or json returnAs: createConfig(RETURN_AS_FILE, STRING_TYPE, {[ENUM_KEY]: RETURN_AS_ENUM}), // we need to force it to use useDoc = true for using jsdoc API now @@ -50,8 +63,8 @@ const defaultOptions = { // there will be cjs, es, ts for different parser jsType: constructConfig(CJS_TYPE , STRING_TYPE, false, ACCEPTED_JS_TYPES), // matching the name across the project - the above two will become alias to this - resolverDir: createConfig(resolve(join(BASE_DIR, DEFAULT_RESOLVER_DIR)) , STRING_TYPE, {[ALIAS_KEY]: 'inDir'}), - contractDir: createConfig(resolve(join(BASE_DIR, DEFAULT_CONTRACT_DIR)), STRING_TYPE, {[ALIAS_KEY]: 'outDir'}), + resolverDir: createConfig(resolve(join(BASE_DIR, DEFAULT_RESOLVER_DIR)) , STRING_TYPE, {[ALIAS_KEY]: IN_DIR_ALIAS}), + contractDir: createConfig(resolve(join(BASE_DIR, DEFAULT_CONTRACT_DIR)), STRING_TYPE, {[ALIAS_KEY]: OUT_DIR_ALIAS}), // show or hide the description field in the public contract // contractWithDesc: createConfig(false, [BOOLEAN_TYPE]), @1.7.6 move to Koa // remove the old one and always create a new one - useful during development @@ -63,18 +76,22 @@ const defaultOptions = { public: constructConfig(false, [BOOLEAN_TYPE]), banner: constructConfig(true, [BOOLEAN_TYPE]), // this are for the cmd mostly - watch: createConfig(false, [BOOLEAN_TYPE, STRING_TYPE, NUMBER_TYPE], {[OPTIONAL_KEY]: true, [ALIAS_KEY]: 'w'}), - interval: createConfig(10000, [NUMBER_TYPE, STRING_TYPE], {[OPTIONAL_KEY]: true, [ALIAS_KEY]: 'i'}), - configFile: createConfig(false, [STRING_TYPE], {[OPTIONAL_KEY]: true, [ALIAS_KEY]: 'c'}), - announceUrl: createConfig(false, [STRING_TYPE], {[OPTIONAL_KEY]: true, [ALIAS_KEY]: 'a'}), + watch: createConfig(false, [BOOLEAN_TYPE, STRING_TYPE, NUMBER_TYPE], {[OPTIONAL_KEY]: true, [ALIAS_KEY]: WATCH_ALIAS}), + interval: createConfig(10000, [NUMBER_TYPE, STRING_TYPE], {[OPTIONAL_KEY]: true, [ALIAS_KEY]: INTERVAL_ALIAS}), + configFile: createConfig(false, [STRING_TYPE], {[OPTIONAL_KEY]: true, [ALIAS_KEY]: CONFIG_FILE_ALIAS}), + // announceUrl: createConfig(false, [STRING_TYPE], {[OPTIONAL_KEY]: true, [ALIAS_KEY]: 'a'}), + logDirectory: constructConfig(false, [STRING_TYPE], true), - tmpDir: createConfig(join(BASE_DIR, 'tmp'), [STRING_TYPE]), + + tmpDir: createConfig(join(BASE_DIR, TMP_DIR), [STRING_TYPE]), // ported from jsonql-koa buildContractOnStart: constructConfig(false, [BOOLEAN_TYPE], true), // @1.8.x enable or disable the split tasks enableSplitTask: createConfig(false, [BOOLEAN_TYPE]), // add 1.8.7 to determine if we clean out the contract folder or not - development: createConfig(false, [BOOLEAN_TYPE]) + development: createConfig(false, [BOOLEAN_TYPE]), + standalone: createConfig(false, [BOOLEAN_TYPE], {[ALIAS_KEY]: STANDALONE_ALIAS}) } + // export it module.exports = config => checkConfigAsync(config, defaultOptions, constProps) -- Gitee From 19ff4968b6e54fa014efd1151869a81101bcce21 Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 10 Mar 2020 16:45:38 +0800 Subject: [PATCH 6/7] just add a todo to the contract test --- packages/contract-cli/tests/socket.test.js | 3 +++ packages/node-client/tests/fixtures/jwt/contract.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/contract-cli/tests/socket.test.js b/packages/contract-cli/tests/socket.test.js index 209e8e84..ec7ac4ae 100644 --- a/packages/contract-cli/tests/socket.test.js +++ b/packages/contract-cli/tests/socket.test.js @@ -4,3 +4,6 @@ const { join } = require('path') const fsx = require('fs-extra') const resolverDir = join(__dirname, 'fixtures', 'resolvers') + + +test.todo(`It should able to generate new entry when socket/auth has content`) diff --git a/packages/node-client/tests/fixtures/jwt/contract.json b/packages/node-client/tests/fixtures/jwt/contract.json index eb0a4f8e..b59ec20a 100644 --- a/packages/node-client/tests/fixtures/jwt/contract.json +++ b/packages/node-client/tests/fixtures/jwt/contract.json @@ -102,7 +102,7 @@ ] } }, - "timestamp": 1583822724, + "timestamp": 1583829857, "sourceType": "script", "socket": { "gateway": { -- Gitee From 8efb51f008158c8c67450b93ffd548436e2d0523 Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 10 Mar 2020 16:46:18 +0800 Subject: [PATCH 7/7] jsonql-contract to 1.8.8 --- packages/contract-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contract-cli/package.json b/packages/contract-cli/package.json index 7e6af26a..3d644b4f 100755 --- a/packages/contract-cli/package.json +++ b/packages/contract-cli/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-contract", - "version": "1.8.7", + "version": "1.8.8", "description": "JS API / command line tool to generate the contract.json for jsonql", "main": "index.js", "files": [ -- Gitee