diff --git a/packages/koa/package.json b/packages/koa/package.json index e45357d3ce9aef368ef77a1ca0d150b74225614c..f396fd2f2b2a735b703c1382696940183674a5ec 100644 --- a/packages/koa/package.json +++ b/packages/koa/package.json @@ -88,7 +88,7 @@ }, "devDependencies": { "ava": "^2.4.0", - "jsonql-ws-server": "^1.3.5", + "jsonql-ws-server": "^1.3.6", "jwt-decode": "^2.2.0", "koa-bodyparser": "^4.2.1", "nb-split-tasks": "^0.6.0", diff --git a/packages/node-client/README.md b/packages/node-client/README.md index 6185fd30da4bc3ecc610c349e413c812380e98dd..863767d5bf5cbbcd05b60769e36582a6c28f4e46 100755 --- a/packages/node-client/README.md +++ b/packages/node-client/README.md @@ -1,5 +1,11 @@ [![NPM](https://nodei.co/npm/jsonql-node-client.png?compact=true)](https://npmjs.org/package/jsonql-node-client) -# json:ql client using native node +# json:ql node.js client -This is intend to be a server to server client using node.js +This is the server to server client using node.js, all options identical to the browser client @jsonql/client + +--- + +ISC [jsonql](http://jsonql.org) + +[NB](http://newbran.ch) & [T1S](http://to1source.cn) diff --git a/packages/node-client/package.json b/packages/node-client/package.json index 925e9c301f0f7864dabfd0e2c45d77da873cfb89..2cc0f046c900a9e5fb8167c89a9f32b381209056 100755 --- a/packages/node-client/package.json +++ b/packages/node-client/package.json @@ -55,9 +55,9 @@ }, "devDependencies": { "ava": "^2.4.0", - "jsonql-contract": "^1.8.3", - "jsonql-koa": "^1.4.1", - "jsonql-ws-server": "^1.3.5", + "jsonql-contract": "^1.8.4", + "jsonql-koa": "^1.4.2", + "jsonql-ws-server": "^1.3.6", "nyc": "^14.1.1", "server-io-core": "^1.2.0", "superkoa": "^1.0.3" diff --git a/packages/node-client/tests/auth.test.js b/packages/node-client/tests/auth.test.js index 9d7ec5a9b802b82b51fb1874e877d54df171ba70..74fec7b88b72b5f4e64e56918746419e792810c6 100755 --- a/packages/node-client/tests/auth.test.js +++ b/packages/node-client/tests/auth.test.js @@ -50,7 +50,7 @@ test('Testing the login function', async (t) => { // t.truthy(result, 'verify the return token is what we expected') }) -test.only(`Test if the loggin client token is persist`, async t => { +test.only(`Test if the login client token is persist`, async t => { let client = t.context.client; let { getUser } = client.query; diff --git a/packages/ws-server/package.json b/packages/ws-server/package.json index 1bb2d31e08ff5d427033324e97dee0daeca29dd1..f9aab9d21868aceafd30738b03997d7f3f86dc46 100755 --- a/packages/ws-server/package.json +++ b/packages/ws-server/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-ws-server", - "version": "1.3.5", + "version": "1.3.6", "description": "Setup WebSocket server for the jsonql to run on the same host, automatic generate public / private channel using contract", "main": "index.js", "files": [ diff --git a/packages/ws-server/src/check-options/index.js b/packages/ws-server/src/check-options/index.js index 0e7a3439ea96085e0f00ad42b90f6322779dfcf5..f7c4af83a8df52b10d89eb14899ece10e73e7a30 100644 --- a/packages/ws-server/src/check-options/index.js +++ b/packages/ws-server/src/check-options/index.js @@ -1,8 +1,6 @@ // there is very limited options there const { join } = require('path') const fsx = require('fs-extra') -const getContract = require('../share/get-contract') - const { createConfig, checkConfigAsync, @@ -23,7 +21,9 @@ const { PEM_EXT, PUBLIC_KEY_NAME, PRIVATE_KEY_NAME, - DEFAULT_CONTRACT_FILE_NAME + DEFAULT_CONTRACT_FILE_NAME, + IO_HANDSHAKE_LOGIN, + IO_ROUNDTRIP_LOGIN } = require('jsonql-constants') const { SOCKET_IO, @@ -31,8 +31,10 @@ const { SECRET_MISSING_ERR } = require('../share/constants') -const HANDSHAKE_TYPE = 'handshake'; -const ROUNDTRIP_TYPE = 'roundtrip'; +const getContract = require('../share/get-contract') + +// const HANDSHAKE_TYPE = 'handshake'; +// const ROUNDTRIP_TYPE = 'roundtrip'; const { JsonqlValidationError } = require('jsonql-errors') @@ -60,7 +62,7 @@ const defaultOptions = { // we only want the keys directory then we read it back keysDir: createConfig(false, [STRING_TYPE]), socketIoAuthType: createConfig(false, [STRING_TYPE], { - [ENUM_KEY]: [HANDSHAKE_TYPE, ROUNDTRIP_TYPE] + [ENUM_KEY]: [IO_HANDSHAKE_LOGIN, IO_ROUNDTRIP_LOGIN] }) } diff --git a/packages/ws-server/src/core/ws-setup.js b/packages/ws-server/src/core/ws-setup.js index c70340480cdc68d1972db3e5352e2fd381160946..382768cfa913ef19634201e7272b24d07384652d 100644 --- a/packages/ws-server/src/core/ws-setup.js +++ b/packages/ws-server/src/core/ws-setup.js @@ -8,7 +8,7 @@ const { ERROR_TYPE, LOGOUT_NAME } = require('jsonql-constants') - +const WS_EXIT_ID = 1; const { getDebug, createWsReply, @@ -83,7 +83,7 @@ const callNspHandler = (ws, json, socketFns, opts, userdata = false) => { * @param {object} ws socket */ const handleLogout = ws => { - ws.close(1, LOGOUT_NAME) + ws.close(WS_EXIT_ID, LOGOUT_NAME) } /** diff --git a/packages/ws-server/src/share/get-contract.js b/packages/ws-server/src/share/get-contract.js index c43462f4c71c62d36160723ee7b8029f54115e8b..6d34396fd494449eae6091c446e94f71f501e834 100644 --- a/packages/ws-server/src/share/get-contract.js +++ b/packages/ws-server/src/share/get-contract.js @@ -5,20 +5,66 @@ const { DEFAULT_CONTRACT_FILE_NAME } = require('jsonql-constants') const { isContract } = require('jsonql-utils') const { JsonqlError } = require('jsonql-errors') const { CONTRACT_NOT_FOUND_ERR } = require('./constants') +const TIME_TO_WAIT = 3000; // 3 seconds + +/** + * actually checking and reading the files + * @param {string} contractDir contract directory + * @return {boolean|object} false when failed + */ +function readContract(contractDir) { + const file = join(contractDir, DEFAULT_CONTRACT_FILE_NAME) + if (fsx.existsSync(file)) { + let c = fsx.readJsonSync(file) + if (isContract(c)) { + return c; + } + } + return false; +} + +/** + * Try to read the contract from file, if failed then retry once after 3 seconds + * @param {object} config configuration + * @return {promise} resolve the contract if success + */ +function getContractFromFile(config) { + let c; + const { contractDir } = config; + return new Promise((resolver, rejecter) => { + c = readContract(contractDir) + if (!c) { + setTimeout(() => { + c = readContract(contractDir) + if (c) { + return resolver(c) + } + rejecter(CONTRACT_NOT_FOUND_ERR) + }, TIME_TO_WAIT) + } else { + resolver(c) + } + }) +} /** * get the contract with validation + * When we init the server together with koa middleware + * the contract might not be ready at this point, because it took 3 seconds to generate + * therefore we change this interface to a promise and give it a chance to retry once * @param {object} config configuration - * @return {object} config with the contract + * @return {promise} resolve the config with the contract as prop */ module.exports = function getContract(config) { - if (config.contract && isContract(config.contract)) { - return config; - } - let c = fsx.readJsonSync(join(config.contractDir, DEFAULT_CONTRACT_FILE_NAME)) - if (!isContract(c)) { - throw new JsonqlError(CONTRACT_NOT_FOUND_ERR) - } - config.contract = c; - return config; + return new Promise((resolver, rejecter) => { + if (config.contract && isContract(config.contract)) { + return resolver(config) + } + getContractFromFile(config) + .then(c => { + config.contract = c; + resolver(config) + }) + .catch(rejecter) + }) }