From decbe7d641de796e888743937ef8b3a31b7cdeab Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 2 Mar 2020 15:24:03 +0800 Subject: [PATCH 1/8] update the read me first --- packages/koa/README.md | 48 ++++++++++--------- packages/koa/package.json | 6 +-- packages/koa/src/contracts/helpers.js | 14 +++--- .../koa/src/contracts/process-contract.js | 4 +- .../src/middlewares/contract-middleware.js | 6 +-- packages/koa/src/options/index.js | 9 ++-- packages/koa/src/options/options.js | 5 +- 7 files changed, 49 insertions(+), 43 deletions(-) diff --git a/packages/koa/README.md b/packages/koa/README.md index a39ead37..17bd29ea 100644 --- a/packages/koa/README.md +++ b/packages/koa/README.md @@ -5,7 +5,9 @@ > This is the jsonql middleware previously published as jsonql-koa, and completely rewritten with ES6 -## BREAKING CHANGE @ V1.3.10 +## BREAKING CHANGE + +### @ V1.3.10 The module use named export `jsonqlKoa`, this will affect all existing code base. Please change accordingly. @@ -15,6 +17,12 @@ import { jsonqlKoa } from 'jsonql-koa' Please change all your code accordingly. +### @ V1.6.0 + +We add a new property to the configuration call `appDir`, and from now on, we will expect all the code will be under +this directory (instead of spread around different places). The default name of this property is `jsonql`. +This will be a required field, and validate during start up time. + ## Installation ```sh @@ -31,10 +39,10 @@ $ yarn add jsonql-koa | Name | Description | Expected Type | Default value | | ----------- |:----------------------| :------------:| :--------------| -| resolversDir | Where the resolvers is | `String` | `join(process.cwd(), 'resolvers')` | -| contractDir | Where to store the contract | `String` | `join(process.cwd(), 'contract')` | +| resolversDir | Where the resolvers is | `String` | `join(process.cwd(), appDir, 'resolvers')` | +| contractDir | Where to store the contract | `String` | `join(process.cwd(), appDir, 'contract')` | | enableAuth | if you need to use jwt authorisation | `Boolean` | `false` | - +| appDir | The name of your project, the above `resolverDir` and `contractDir` will under this directory | `String` | `jsonql` | More options to come later @@ -176,10 +184,10 @@ Query can have as many arguments as you want. ```js /** - * @param {number} a - * @param {number} b - * @param {number} c - * @param {number} [d=10] + * @param {number} a prop + * @param {number} b prop + * @param {number} c prop + * @param {number} [d=10] prop default 10 * @return {number} sum of them */ module.exports = function(a, b, c, d=10) { @@ -187,11 +195,7 @@ module.exports = function(a, b, c, d=10) { } ``` -The follow is no longer valid, we will provide you with a `CURRENT_LOGIN_USER` global object. - -~~And when this application is using the `auth` option (lock down mode). After you have successfully login and obtain the -authorisation token, every time after the successfully auth call, you will received the return value from your `validator` -method as your arguments + 1, so the above method in fact will become:~~ +*TBC: How to get the userdata* --- @@ -223,7 +227,7 @@ module.exports = function(payload, conditions) { There are only two authorisation methods -1. `issuer` - basically what you do to login +1. `login` - basically what you do to login 2. `validator` - every time the client request your API, this method will get call and validator against the token in the header. 3. `logout` - it does what it said on the tin. @@ -240,26 +244,24 @@ This require out other module `jsonql-ws-server` to setup. More coming soon. **BREAKING CHANAGE** -We will start using the jsdoc to capture your parameter and returns type. Therefore from V.1 release onward it will be **REQUIRED** to write correct jsdoc. This is important because +We will start using the jsdoc to capture your parameter and returns type. Therefore from V.1 release onward it will be **REQUIRED** to write correct `jsdoc`. This is important because the client side will be expecting correct type information for -the validation to work correctly. Also this solve a problem of -unable to pass default parameter to pass the resolver. - -__And the typescript port currently under development will able to work with the standard JS server side, ,as well as the Typescript version__ +the validation to work. Also this solve a problem of +unable to pass default parameter pass to the resolver. --- Contracts are generate automatically when you start up your application. We have a separate tool [jsonql-contract](https://www.npmjs.com/package/jsonql-contract) to generate the contract file (it just a json file contain information about your applications). For internal user, the file is call `contract.json` it will located in the `contractDir` -you specify when you config the middleware, default location will be `~/project/contracts`. +you specify when you config the middleware, default location will be `~/project/jsonql/contracts`. There is another contract that is for your client to consume, which is name `public-contract.json`. It has the same structure but without some of the sensitive information, such as the `file` field (where your code located) and the `validator` field. -If you are not using `auth:true` option, then even if you implement the `auth/issuer.js` method, it will get remove as well. +If you are not using `auth:true` option, then even if you implement the `auth/login.js` method, it will get remove as well. Also whenever the client request the contract. It will look for additional json file in the same folder. -For instance, your `NODE_ENV=development` therefore, it will search for `~/project/contracts/development.json` and this will +For instance, your `NODE_ENV=development` therefore, it will search for `~/project/jsonql/contracts/development.json` and this will get merge with the stock `public-contract.json`. Therefore you can overwrite information (but not remove) or add additional information, such as change the return field, and write a auto validator based on the result you received. @@ -268,5 +270,7 @@ object. --- +Main website: [jsonql.org](https://jsonql.org) + MIT (c) 2019 [to1source China](https://to1source.cn) in collaboration with [NEWBRAN LTD UK](https://newbran.ch) diff --git a/packages/koa/package.json b/packages/koa/package.json index cd73b6c2..0e21c1cd 100644 --- a/packages/koa/package.json +++ b/packages/koa/package.json @@ -80,7 +80,7 @@ "jsonql-contract": "^1.8.7", "jsonql-errors": "^1.1.10", "jsonql-jwt": "^1.3.8", - "jsonql-node-client": "^1.2.12", + "jsonql-node-client": "^1.3.0", "jsonql-params-validator": "^1.5.2", "jsonql-resolver": "^1.0.9", "jsonql-utils": "^0.9.7", @@ -89,7 +89,7 @@ "lodash": "^4.17.15" }, "devDependencies": { - "ava": "^3.3.0", + "ava": "^3.5.0", "jsonql-ws-server": "^1.5.3", "jwt-decode": "^2.2.0", "koa": "^2.11.0", @@ -97,7 +97,7 @@ "nb-split-tasks": "^0.6.0", "nyc": "^15.0.0", "request": "^2.88.2", - "server-io-core": "^1.2.0", + "server-io-core": "^1.3.1", "superkoa": "^1.0.3" } } diff --git a/packages/koa/src/contracts/helpers.js b/packages/koa/src/contracts/helpers.js index 0cce4f7d..40c22997 100644 --- a/packages/koa/src/contracts/helpers.js +++ b/packages/koa/src/contracts/helpers.js @@ -28,14 +28,14 @@ export const removeDesc = (showDesc, contract) => { for (let fn in c[type]) { // debug(c[type][fn]) if (isObjectHasKey(c[type][fn], keyword)) { - delete c[type][fn].description; + delete c[type][fn].description if (c[type][fn].returns && isObjectHasKey(c[type][fn].returns, keyword)) { - delete c[type][fn].returns.description; + delete c[type][fn].returns.description } } } } - return c; + return c } /** @@ -76,7 +76,7 @@ export const searchContractAuth = function(ctx, contractKeyName) { */ export const contractAuth = function(ctx, opts) { if (opts.contractKey !== false && opts.contractKeyName !== false) { - const { contractKey, contractKeyName } = opts; + const { contractKey, contractKeyName } = opt // debug('Received this for auth', contractKeyName, contractKey); // @2019-05-08 we change from url query to header // const keyValueFromClient = trim(ctx.query[contractKeyName]); @@ -86,13 +86,13 @@ export const contractAuth = function(ctx, opts) { switch (true) { case typeof contractKey === 'string': // debug('compare this two', keyValueFromClient, contractKey); - return keyValueFromClient === contractKey; + return keyValueFromClient === contractKey break; default: // @TODO what if we want to read the header? debug('Unsupported contract auth type method', typeof contractKey) - return false; + return false } } - return true; + return true } diff --git a/packages/koa/src/contracts/process-contract.js b/packages/koa/src/contracts/process-contract.js index 90039028..f1fb2fad 100644 --- a/packages/koa/src/contracts/process-contract.js +++ b/packages/koa/src/contracts/process-contract.js @@ -35,11 +35,11 @@ export default function processContract(ctx, opts) { debug('calling the initContract to get the contract', c) // disable the cache for the time being // setter('contract', c) - return c; + return c }) } throw new JsonqlError('Unable to get the contract!') } - return c; + return c }) } diff --git a/packages/koa/src/middlewares/contract-middleware.js b/packages/koa/src/middlewares/contract-middleware.js index 09806ab3..8101df51 100644 --- a/packages/koa/src/middlewares/contract-middleware.js +++ b/packages/koa/src/middlewares/contract-middleware.js @@ -16,7 +16,7 @@ export default function contractMiddleware(opts) { // export return async function(ctx, next) { // this will only handle certain methods - const { isReq, resolverType } = ctx.state.jsonql; + const { isReq, resolverType } = ctx.state.jsonql // @2019-05-24 We need to make sure the call is actually a jsonql call // because when http access happen it could make multiple call to the // server and contract generator just run multiple times on a very short time @@ -25,12 +25,12 @@ export default function contractMiddleware(opts) { // now is this request asking for the public contract if (resolverType === CONTRACT_NAME) { if (contractAuth(ctx, opts)) { - let publicContractJson = ctx.state.jsonql.publicContract; + let publicContractJson = ctx.state.jsonql.publicContract if (!publicContractJson) { debug(`call the get public contract here`, opts.name) // This should be a one off event publicContractJson = await getContract(opts, true) - ctx.state.jsonql.publicContract = publicContractJson; + ctx.state.jsonql.publicContract = publicContractJson } // debug('call handle public contract method here'); // this is a public contract diff --git a/packages/koa/src/options/index.js b/packages/koa/src/options/index.js index 7d53dcb6..8df87edb 100644 --- a/packages/koa/src/options/index.js +++ b/packages/koa/src/options/index.js @@ -15,6 +15,7 @@ import { preConfigCheck as jsonqlUtilsPreConfigCheck } from 'jsonql-utils' import { appProps, constProps, jwtProcessKey } from './options' import { isContract, chainFns, getDebug, inArray, injectToFn, objHasProp } from '../utils' import { getContract } from '../contracts' + const debug = getDebug('config-check') /** @@ -56,7 +57,7 @@ const applyGetContract = function(config) { } /** - * @TODO move to jsonql-utils because when we start express will need this + * @TODO move to jsonql-utils because when we start express will need this * we need an extra step to cache some of the auth related configuration data * @param {object} config configuration * @return {object} config with extra property @@ -81,7 +82,7 @@ const applyAuthOptions = function(config) { config[jwtProcessKey] = rsaPemKeys(config.rsaModulusLength, config.keysDir) } } - return config; + return config } /** @@ -96,7 +97,7 @@ const initNodeClient = function(config) { debug(`create the clients config at the options level`) config[INIT_CLIENT_PROP_KEY] = clientsGenerator(clientConfigs) } - return config; + return config } /** @@ -109,7 +110,7 @@ export function configCheck(config = {}) { let time; if ((time = objHasProp(config, CHECKED_KEY)) !== undefined) { // @TODO we could check the time if we want ... debug(`config already checked, pass it through`, time, now - time) - return config; + return config } // @TODO should take this bit out for re-use const fn = chainFns(checkConfig, applyGetContract, applyAuthOptions, initNodeClient) diff --git a/packages/koa/src/options/options.js b/packages/koa/src/options/options.js index 828be098..90a7c9ee 100644 --- a/packages/koa/src/options/options.js +++ b/packages/koa/src/options/options.js @@ -32,7 +32,8 @@ import { createConfig, constructConfig } from 'jsonql-params-validator' -const DEFAULT_APP_DIR = 'app' +const DEFAULT_APP_DIR = JSONQL_PATH +const DEFAULT_APP_NAME = [JSONQL_PATH, 'koa'].join('-') // const NodeCache from 'node-cache'); // const mcache = new NodeCache; // @BUG when we deploy it in docker, or using systemd the workingDirectory affect the @@ -53,7 +54,7 @@ const constProps = { } const appProps = { - name: createConfig('jsonql-koa', [STRING_TYPE]), // this is for ID which one is which when use as ms + name: createConfig(DEFAULT_APP_NAME, [STRING_TYPE]), // this is for ID which one is which when use as ms expired: createConfig(0, [NUMBER_TYPE]), appDir: createConfig(join(dirname, DEFAULT_APP_DIR), [STRING_TYPE]), // allow user to change their auth type methods name -- Gitee From 92c5b29d771c43d14fc1ae190288cc148c908f4c Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 2 Mar 2020 15:46:14 +0800 Subject: [PATCH 2/8] Add the new appDir and projectRootDir option --- packages/koa/src/options/index.js | 28 +++++++++++++++++--- packages/koa/src/options/options.js | 14 +++++----- packages/koa/src/options/process-jwt-keys.js | 16 +++++------ 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/packages/koa/src/options/index.js b/packages/koa/src/options/index.js index 8df87edb..77f37035 100644 --- a/packages/koa/src/options/index.js +++ b/packages/koa/src/options/index.js @@ -66,7 +66,7 @@ const applyAuthOptions = function(config) { // @TODO need to get rip of the useJwt option! // && config.useJwt && !isString(config.useJwt) OLD options! if (config.enableAuth) { - const { keysDir, publicKeyFileName, privateKeyFileName } = config; + const { keysDir, publicKeyFileName, privateKeyFileName } = config // @BUG some where if there is no config pass then becomes a boolean? debug('keysDir', keysDir) debug('publicKeyFileName', publicKeyFileName) @@ -101,19 +101,39 @@ const initNodeClient = function(config) { } /** + * @1.6.0 we put all the directory under the appDir from now on + * @param {object} config options + * @return {object} mutated configuration + */ +const applyDirectories = function(config) { + const target = ['contractDir', 'resolverDir', 'keysDir'] + const { projectRootDir, appDir } = config + + return target.reduce((opt, prop) => { + return join(projectRootDir, appDir, opt[prop]) + }, config) +} + +/** + * The main method that run before everything else to check the configuration * @param {object} config configuration supply by developer * @return {object} configuration been checked * @api public */ export function configCheck(config = {}) { let now = Date.now() - let time; + let time if ((time = objHasProp(config, CHECKED_KEY)) !== undefined) { // @TODO we could check the time if we want ... debug(`config already checked, pass it through`, time, now - time) return config } - // @TODO should take this bit out for re-use - const fn = chainFns(checkConfig, applyGetContract, applyAuthOptions, initNodeClient) + const fn = chainFns( + checkConfig, + applyDirectories, + applyGetContract, + applyAuthOptions, + initNodeClient + ) const opts = fn(config, appProps, constProps) // return opts; return injectToFn(opts, CHECKED_KEY, now) diff --git a/packages/koa/src/options/options.js b/packages/koa/src/options/options.js index 90a7c9ee..854cf1e1 100644 --- a/packages/koa/src/options/options.js +++ b/packages/koa/src/options/options.js @@ -34,12 +34,12 @@ import { } from 'jsonql-params-validator' const DEFAULT_APP_DIR = JSONQL_PATH const DEFAULT_APP_NAME = [JSONQL_PATH, 'koa'].join('-') +const jwtProcessKey = 'INIT_JWT_KEYS' // just for id the promise call // const NodeCache from 'node-cache'); // const mcache = new NodeCache; // @BUG when we deploy it in docker, or using systemd the workingDirectory affect the // execute path, it might be better to allow a config option of workingDirectory and // use that as base -const dirname = process.cwd() // @TODO we need to create the same fn to clear out the options like I did in server-io-core const constProps = { // __checked__: true, we don't do this here, see index.js @@ -56,7 +56,8 @@ const constProps = { const appProps = { name: createConfig(DEFAULT_APP_NAME, [STRING_TYPE]), // this is for ID which one is which when use as ms expired: createConfig(0, [NUMBER_TYPE]), - appDir: createConfig(join(dirname, DEFAULT_APP_DIR), [STRING_TYPE]), + appDir: createConfig(DEFAULT_APP_DIR, [STRING_TYPE]), + projectRootDir: createConfig(process.cwd(), [STRING_TYPE]), // allow user to change their auth type methods name loginHandlerName: createConfig(ISSUER_NAME, [STRING_TYPE]), logoutHandlerName: createConfig(LOGOUT_NAME, [STRING_TYPE]), @@ -72,15 +73,15 @@ const appProps = { contractWithDesc: createConfig(false, [BOOLEAN_TYPE]), // @1.3.4 whenever generate a contract will generate the public contract as well withPublicContract: createConfig(true, [BOOLEAN_TYPE]), - keysDir: createConfig(join(dirname, DEFAULT_KEYS_DIR), [STRING_TYPE]), + keysDir: createConfig(DEFAULT_KEYS_DIR, [STRING_TYPE]), publicKeyFileName: createConfig(DEFAULT_PUBLIC_KEY_FILE, [STRING_TYPE]), privateKeyFileName: createConfig(DEFAULT_PRIVATE_KEY_FILE, [STRING_TYPE]), rsaModulusLength: createConfig(RSA_MIN_MODULE_LEN, [NUMBER_TYPE]), jsonqlPath: {[ARGS_KEY]: ['/', JSONQL_PATH].join(''), [TYPE_KEY]: STRING_TYPE}, - resolverDir: {[ARGS_KEY]: join(dirname, DEFAULT_RESOLVER_DIR), [TYPE_KEY]: STRING_TYPE, [CHECKER_KEY]: fs.existsSync}, + resolverDir: {[ARGS_KEY]: DEFAULT_RESOLVER_DIR, [TYPE_KEY]: STRING_TYPE, [CHECKER_KEY]: fs.existsSync}, // we don't really need to check if the contract directory exist or not, it will get created - contractDir: {[ARGS_KEY]: join(dirname, DEFAULT_CONTRACT_DIR), [TYPE_KEY]: STRING_TYPE}, + contractDir: {[ARGS_KEY]: DEFAULT_CONTRACT_DIR, [TYPE_KEY]: STRING_TYPE}, contractKey: {[ARGS_KEY]: false, [TYPE_KEY]: [BOOLEAN_TYPE, STRING_TYPE]}, contractKeyName: {[ARGS_KEY]: CONTRACT_KEY_NAME, [TYPE_KEY]: STRING_TYPE}, @@ -114,7 +115,8 @@ const appProps = { // same as the contract-cli enableSplitTask: createConfig(false, [BOOLEAN_TYPE]) } -const jwtProcessKey = 'INIT_JWT_KEYS' // just for id the promise call + + export { constProps, appProps, diff --git a/packages/koa/src/options/process-jwt-keys.js b/packages/koa/src/options/process-jwt-keys.js index 867fd10c..78891dd0 100644 --- a/packages/koa/src/options/process-jwt-keys.js +++ b/packages/koa/src/options/process-jwt-keys.js @@ -24,7 +24,7 @@ const getKeysFromCache = (ctx, config) => { // @BUG when init this at run time, we could get a getter is not a function error? // this happen in @jsonql/koa test // @TODO need to check the getter sequence, also allow supply a setter and getter - const { setter, getter } = ctx.state.jsonql; + const { setter, getter } = ctx.state.jsonql if (config.enableAuth && config.useJwt && // @TODO need to remove this !isString(config.useJwt) && // @TODO need to change this key name @@ -37,7 +37,7 @@ const getKeysFromCache = (ctx, config) => { } } } - return false; + return false } /** @@ -48,7 +48,7 @@ const getKeysFromCache = (ctx, config) => { */ const getCreatedKeys = (ctx, config) => { if (isObjectHasKey(config, jwtProcessKey) && config[jwtProcessKey].then) { - const { setter } = ctx.state.jsonql; + const { setter } = ctx.state.jsonql return config[jwtProcessKey] .then( result => _.extend( config, _.mapValues(result, value => fsx.readFileSync(value) ) ) ) .then(keys => { @@ -58,10 +58,10 @@ const getCreatedKeys = (ctx, config) => { setter(key, value) }) } - return keys; + return keys }) } - return false; + return false } /** @@ -73,10 +73,10 @@ const getCreatedKeys = (ctx, config) => { export default function processJwtKeys(ctx, config) { let result; if ((result = getKeysFromCache(ctx, config)) !== false) { - return result; + return result } if ((result = getCreatedKeys(ctx, config)) !== false) { - return result; + return result } - return config; + return config } -- Gitee From ba391b7acb3a39c3efd9a74da6d4d93e2fb484ad Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 2 Mar 2020 15:54:35 +0800 Subject: [PATCH 3/8] Change the appDir default to empty because I dont want to lose the flexiblity and cause too much problem --- packages/koa/README.md | 9 ++++++--- packages/koa/src/options/options.js | 2 +- packages/koa/tests/config.test.js | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/koa/README.md b/packages/koa/README.md index 17bd29ea..e6b34206 100644 --- a/packages/koa/README.md +++ b/packages/koa/README.md @@ -39,10 +39,13 @@ $ yarn add jsonql-koa | Name | Description | Expected Type | Default value | | ----------- |:----------------------| :------------:| :--------------| -| resolversDir | Where the resolvers is | `String` | `join(process.cwd(), appDir, 'resolvers')` | -| contractDir | Where to store the contract | `String` | `join(process.cwd(), appDir, 'contract')` | +| projectRootDir | Where the root of your project is | `String` | `process.cwd()` | +| appDir | The name of your project directory, the above `resolverDir` and `contractDir` will under this directory | `String` | '' | +| resolversDir | The name of the resolvers directory | `String` | 'resolvers' | +| contractDir | The name of the contract directory | `String` | 'contract' | | enableAuth | if you need to use jwt authorisation | `Boolean` | `false` | -| appDir | The name of your project, the above `resolverDir` and `contractDir` will under this directory | `String` | `jsonql` | +| keysDir | Where we store your RSA key to validate against the JWT token | `String` | 'keys' | + More options to come later diff --git a/packages/koa/src/options/options.js b/packages/koa/src/options/options.js index 854cf1e1..53164c34 100644 --- a/packages/koa/src/options/options.js +++ b/packages/koa/src/options/options.js @@ -56,7 +56,7 @@ const constProps = { const appProps = { name: createConfig(DEFAULT_APP_NAME, [STRING_TYPE]), // this is for ID which one is which when use as ms expired: createConfig(0, [NUMBER_TYPE]), - appDir: createConfig(DEFAULT_APP_DIR, [STRING_TYPE]), + appDir: createConfig('', [STRING_TYPE]), // it should be optional because it will lost the flexiblity projectRootDir: createConfig(process.cwd(), [STRING_TYPE]), // allow user to change their auth type methods name loginHandlerName: createConfig(ISSUER_NAME, [STRING_TYPE]), diff --git a/packages/koa/tests/config.test.js b/packages/koa/tests/config.test.js index 8d977ecc..da4fc7e2 100644 --- a/packages/koa/tests/config.test.js +++ b/packages/koa/tests/config.test.js @@ -15,6 +15,7 @@ const processJwtKeys = processJwtKeysDefault.default const { jwtProcessKey } = require('../src/options/options') const debug = require('debug')('jsonql-koa:test:config') + const resolverDir = join(__dirname, 'fixtures', 'resolvers') const contractDir = join(__dirname, 'fixtures', 'tmp', 'config-test') const keysDir = join(__dirname, 'fixtures', 'tmp', 'keys') -- Gitee From 4566d18ab34625eb3d3fd87d31e8be0bc72e4646 Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 2 Mar 2020 16:24:03 +0800 Subject: [PATCH 4/8] change the way how we are going to handle the appDir --- packages/koa/src/options/index.js | 30 +++++++++++++++++++++++------ packages/koa/src/options/options.js | 15 ++++++++++----- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/packages/koa/src/options/index.js b/packages/koa/src/options/index.js index 77f37035..e577e2bd 100644 --- a/packages/koa/src/options/index.js +++ b/packages/koa/src/options/index.js @@ -6,13 +6,21 @@ import fsx from 'fs-extra' import _ from 'lodash' import { rsaPemKeys } from 'jsonql-jwt' +import { JsonqlError } from 'jsonql-errors' import { checkConfig, isString } from 'jsonql-params-validator' import { validateClientConfig, clientsGenerator } from 'jsonql-resolver' -import { CHECKED_KEY, INIT_CONTRACT_PROP_KEY, INIT_CLIENT_PROP_KEY } from 'jsonql-constants' +import { + CHECKED_KEY, + INIT_CONTRACT_PROP_KEY, + INIT_CLIENT_PROP_KEY, + DEFAULT_RESOLVER_DIR, + DEFAULT_CONTRACT_DIR, + DEFAULT_KEYS_DIR +} from 'jsonql-constants' import { preConfigCheck as jsonqlUtilsPreConfigCheck } from 'jsonql-utils' -import { appProps, constProps, jwtProcessKey } from './options' +import { appProps, constProps, jwtProcessKey, RESOLVER_DIR_KEY, REQ_DIR_NAMES } from './options' import { isContract, chainFns, getDebug, inArray, injectToFn, objHasProp } from '../utils' import { getContract } from '../contracts' @@ -106,11 +114,21 @@ const initNodeClient = function(config) { * @return {object} mutated configuration */ const applyDirectories = function(config) { - const target = ['contractDir', 'resolverDir', 'keysDir'] const { projectRootDir, appDir } = config - - return target.reduce((opt, prop) => { - return join(projectRootDir, appDir, opt[prop]) + let i = 0 + return REQ_DIR_NAMES.reduce((opt, prop) => { + let dir = opt[prop] + if (dir === REQ_DIR_CHECK[i]) { // if it's default name + let propDir = join(projectRootDir, appDir, dir) + if (prop === RESOLVER_DIR_KEY) { + if (!fsx.existsSync(propDir)) { + throw new JsonqlError(`Expect the resolver redirectory to exist!`) + } + } + opt[prop] = propDir + } + ++i + return opt }, config) } diff --git a/packages/koa/src/options/options.js b/packages/koa/src/options/options.js index 53164c34..384092d2 100644 --- a/packages/koa/src/options/options.js +++ b/packages/koa/src/options/options.js @@ -1,5 +1,4 @@ import { join } from 'path' -import fs from 'fs' import { PUBLIC_KEY, PRIVATE_KEY, @@ -7,6 +6,7 @@ import { CONTENT_TYPE, DEFAULT_RESOLVER_DIR, DEFAULT_CONTRACT_DIR, + DEFAULT_KEYS_DIR, CONTRACT_KEY_NAME, ARRAY_TYPE, BOOLEAN_TYPE, @@ -23,7 +23,6 @@ import { LOGOUT_NAME, VALIDATOR_NAME, RETURN_AS_JSON, - DEFAULT_KEYS_DIR, DEFAULT_PUBLIC_KEY_FILE, DEFAULT_PRIVATE_KEY_FILE, RSA_MIN_MODULE_LEN @@ -32,9 +31,12 @@ import { createConfig, constructConfig } from 'jsonql-params-validator' -const DEFAULT_APP_DIR = JSONQL_PATH +// const DEFAULT_APP_DIR = JSONQL_PATH const DEFAULT_APP_NAME = [JSONQL_PATH, 'koa'].join('-') const jwtProcessKey = 'INIT_JWT_KEYS' // just for id the promise call +const RESOLVER_DIR_KEY = 'resolverDir' +const REQ_DIR_NAMES = [RESOLVER_DIR_KEY, 'contractDir', 'keysDir'] +const REQ_DIR_CHECK = [DEFAULT_RESOLVER_DIR, DEFAULT_CONTRACT_DIR, DEFAULT_KEYS_DIR] // const NodeCache from 'node-cache'); // const mcache = new NodeCache; // @BUG when we deploy it in docker, or using systemd the workingDirectory affect the @@ -79,7 +81,7 @@ const appProps = { rsaModulusLength: createConfig(RSA_MIN_MODULE_LEN, [NUMBER_TYPE]), jsonqlPath: {[ARGS_KEY]: ['/', JSONQL_PATH].join(''), [TYPE_KEY]: STRING_TYPE}, - resolverDir: {[ARGS_KEY]: DEFAULT_RESOLVER_DIR, [TYPE_KEY]: STRING_TYPE, [CHECKER_KEY]: fs.existsSync}, + resolverDir: {[ARGS_KEY]: DEFAULT_RESOLVER_DIR, [TYPE_KEY]: STRING_TYPE}, // we don't really need to check if the contract directory exist or not, it will get created contractDir: {[ARGS_KEY]: DEFAULT_CONTRACT_DIR, [TYPE_KEY]: STRING_TYPE}, @@ -120,5 +122,8 @@ const appProps = { export { constProps, appProps, - jwtProcessKey + jwtProcessKey, + RESOLVER_DIR_KEY, + REQ_DIR_NAMES, + REQ_DIR_CHECK } -- Gitee From d6314a2b8d1938b6be1c2c338cfcb16664d5a302 Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 2 Mar 2020 17:27:55 +0800 Subject: [PATCH 5/8] The config test passed even with the untouched default options --- packages/koa/src/options/index.js | 11 +++++++++-- packages/koa/tests/config.test.js | 10 ++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/packages/koa/src/options/index.js b/packages/koa/src/options/index.js index e577e2bd..bf79ac04 100644 --- a/packages/koa/src/options/index.js +++ b/packages/koa/src/options/index.js @@ -17,10 +17,17 @@ import { DEFAULT_CONTRACT_DIR, DEFAULT_KEYS_DIR } from 'jsonql-constants' +import { + appProps, + constProps, + jwtProcessKey, + RESOLVER_DIR_KEY, + REQ_DIR_NAMES, + REQ_DIR_CHECK +} from './options' import { preConfigCheck as jsonqlUtilsPreConfigCheck } from 'jsonql-utils' -import { appProps, constProps, jwtProcessKey, RESOLVER_DIR_KEY, REQ_DIR_NAMES } from './options' import { isContract, chainFns, getDebug, inArray, injectToFn, objHasProp } from '../utils' import { getContract } from '../contracts' @@ -122,7 +129,7 @@ const applyDirectories = function(config) { let propDir = join(projectRootDir, appDir, dir) if (prop === RESOLVER_DIR_KEY) { if (!fsx.existsSync(propDir)) { - throw new JsonqlError(`Expect the resolver redirectory to exist!`) + throw new JsonqlError('options.applyDirectories', `Expect the resolver redirectory to exist! ${propDir}`) } } opt[prop] = propDir diff --git a/packages/koa/tests/config.test.js b/packages/koa/tests/config.test.js index da4fc7e2..e1bd8945 100644 --- a/packages/koa/tests/config.test.js +++ b/packages/koa/tests/config.test.js @@ -58,6 +58,16 @@ test('It should able to check the in dir', t => { t.is( dir, opts.resolverDir ) }) +test(`It should allow to use the appDir option`, t => { + const opts = configCheck({ + appDir: 'tests/fixtures', + contractDir + }) + // debug(opts) + t.is(opts.contractDir, contractDir, 'should also allow to pass a custom directory name') +}) + + test('It should have privateKey and publicKey when set useJwt = true', async t => { let opts = configCheck({ enableAuth: true, -- Gitee From 56b0f4e77e78e36c4a4102927cfac5ff3599b3ed Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 2 Mar 2020 17:30:33 +0800 Subject: [PATCH 6/8] fix the contractAuth missing var name error --- packages/koa/src/contracts/helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/koa/src/contracts/helpers.js b/packages/koa/src/contracts/helpers.js index 40c22997..43387bcb 100644 --- a/packages/koa/src/contracts/helpers.js +++ b/packages/koa/src/contracts/helpers.js @@ -76,7 +76,7 @@ export const searchContractAuth = function(ctx, contractKeyName) { */ export const contractAuth = function(ctx, opts) { if (opts.contractKey !== false && opts.contractKeyName !== false) { - const { contractKey, contractKeyName } = opt + const { contractKey, contractKeyName } = opts // debug('Received this for auth', contractKeyName, contractKey); // @2019-05-08 we change from url query to header // const keyValueFromClient = trim(ctx.query[contractKeyName]); -- Gitee From 42f777e90f2d74de37cd35b21988e4b20894f336 Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 2 Mar 2020 17:33:16 +0800 Subject: [PATCH 7/8] The base test passed, not go back and try to fix the ms problems --- packages/koa/tests/node-client.test.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/koa/tests/node-client.test.js b/packages/koa/tests/node-client.test.js index 933d45ed..4e87b4f1 100644 --- a/packages/koa/tests/node-client.test.js +++ b/packages/koa/tests/node-client.test.js @@ -75,8 +75,8 @@ test(`First test calling the ${baseServerPort} directly with the mutation call`, hostname: `http://localhost:${msServerPort}`, contractDir: join(__dirname, 'fixtures', 'tmp', `client${msServerPort}`) }) - const result = await client.query.subMsService('testing') - t.truthy(result.indexOf(`ms service`)) + const result = await client.subMsService('testing') + t.truthy(result.indexOf(`ms service`), `It also tested the namespaced option in the node-client`) }) test.cb.skip(`[still got socket hang up @ 1.5.5] First test server ${baseServerPort} and ${msServerPort} are running`, t => { @@ -84,14 +84,14 @@ test.cb.skip(`[still got socket hang up @ 1.5.5] First test server ${baseServerP t.plan(2) t.context.isReady.then(() => { t.context.baseAppClient.then(client1 => { - client1.query.helloWorld() + client1.helloWorld() .then(res1 => { t.truthy(res1) }) }) t.context.msAppClient.then(client2 => { - client2.query.helloWorld() + client2.helloWorld() .then(res2 => { t.truthy(res2) setTimeout(() => { @@ -111,6 +111,6 @@ test.skip(`It should able to call a resolver that access another ms`, async t => debug(client) - const result = await client.mutation.subUpdateMsService('testing') + const result = await client.subUpdateMsService('testing') t.truthy(result.indexOf(`ms service`)) }) -- Gitee From f7b30ec652396de2b8cd3f5a57bd571c70b5c7af Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 2 Mar 2020 17:40:58 +0800 Subject: [PATCH 8/8] Thats it for now, we need to fix the ws server before continue here --- packages/koa/package.json | 2 +- packages/koa/tests/node-client.test.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/koa/package.json b/packages/koa/package.json index 0e21c1cd..53152587 100644 --- a/packages/koa/package.json +++ b/packages/koa/package.json @@ -31,7 +31,7 @@ "test:jsonp": "DEBUG=jsonql* ava --verbose ./tests/jsonp.test.js", "test:jsonql": "DEBUG=jsonql-koa* ava --verbose ./tests/jsonql.test.js", "test:chain": "DEBUG=jsonql* ava --verbose ./tests/chain-fn.test.js", - "test:client": "DEBUG=jsonql* ava --verbose ./tests/node-client.test.js", + "test:client": "DEBUG=jsonql-ws* ava --verbose ./tests/node-client.test.js", "web-console": "DEBUG=jsonql-koa*,jsonql-web-console* node ./tests/helpers/browser.js", "contract": "node ./node_modules/jsonql-contract/cli.js ./tests/fixtures/resolvers ./tests/fixtures/contracts" }, diff --git a/packages/koa/tests/node-client.test.js b/packages/koa/tests/node-client.test.js index 4e87b4f1..17f7fd2d 100644 --- a/packages/koa/tests/node-client.test.js +++ b/packages/koa/tests/node-client.test.js @@ -79,6 +79,7 @@ test(`First test calling the ${baseServerPort} directly with the mutation call`, t.truthy(result.indexOf(`ms service`), `It also tested the namespaced option in the node-client`) }) +// @1.6.0 this problem still here but it could be a ws problem instead of our framework test.cb.skip(`[still got socket hang up @ 1.5.5] First test server ${baseServerPort} and ${msServerPort} are running`, t => { t.plan(2) -- Gitee