diff --git a/packages/contract-cli/package.json b/packages/contract-cli/package.json index b9127ffaf29c00b43d308e63924ee316bb90f2d9..7e40d16920782f7606f92d726547db76ce883cc7 100755 --- a/packages/contract-cli/package.json +++ b/packages/contract-cli/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-contract", - "version": "1.7.20", + "version": "1.7.21", "description": "JS API / command line tool to generate the contract.json for jsonql", "main": "index.js", "files": [ diff --git a/packages/contract-cli/src/generator/generate-output.js b/packages/contract-cli/src/generator/generate-output.js index bb29a9b4ad12065ebbfe0be628afeef16191a56d..dc9a92686e5ed40b7a100cdebef7638f923c8f1a 100644 --- a/packages/contract-cli/src/generator/generate-output.js +++ b/packages/contract-cli/src/generator/generate-output.js @@ -1,7 +1,8 @@ // the final step to generate output const { RETURN_AS_JSON } = require('jsonql-constants') const { keepOrCleanContract, isContractExisted, writeFileOut } = require('./files-op') -const { esPostProcess } = require('./es-post-process') +// @NOTE this is removed in v1.7.21 +// const { esPostProcess } = require('./es-post-process') const { mutateContract } = require('./helpers') const { join } = require('path') /** @@ -21,9 +22,11 @@ const generateOutput = function(sourceType, config, contract, rawData = false) { .then(() => mutateContract(config, contract)) .then(finalContract => ( writeFileOut(dist, finalContract) - .then(contract => ( + .then(() => ( + config.returnAs === RETURN_AS_JSON ? finalContract : dist + /* esPostProcess(sourceType, resolverDir, rawData || contract) - .then(() => config.returnAs === RETURN_AS_JSON ? finalContract : dist) + .then(() => config.returnAs === RETURN_AS_JSON ? finalContract : dist) */ )) )) } diff --git a/packages/contract-cli/src/generator/get-resolver.js b/packages/contract-cli/src/generator/get-resolver.js index 78e52283b79f15f5f23cf97b8d3342d02ddbef14..185ec717a973a03c10ffbdb1526d3ef5345eb7a8 100644 --- a/packages/contract-cli/src/generator/get-resolver.js +++ b/packages/contract-cli/src/generator/get-resolver.js @@ -130,7 +130,7 @@ function getResolver(config, fileType) { const indexFile = [INDEX_KEY, fileType].join('.') // return a function here const fn = checkResolver(indexFile, config.resolverDir, fileType, config) - debug(fn.toString()) + // debug(fn.toString()) return fn; } diff --git a/packages/contract-cli/src/generator/split-task.js b/packages/contract-cli/src/generator/split-task.js index 59524c232ca3c4bf64839080827769c249bb0359..07deeeb812cc288c71f4b37640753d83ffc590ec 100644 --- a/packages/contract-cli/src/generator/split-task.js +++ b/packages/contract-cli/src/generator/split-task.js @@ -73,7 +73,7 @@ function createTask(slots, taskPath, payloads, returnType = true) { * @param {array} payload array of payload * @return {promise} resolve the final result */ -function splitTask(taskName, payload) { +function splitTask(config, payload) { return Promise.resolve(false) diff --git a/packages/contract-cli/tests/generator.test.js b/packages/contract-cli/tests/generator.test.js index 7e68a788320848e1f3bb0a8b928a50411309dc26..509b0f14c39ada61254708d0eefac8085a438a99 100755 --- a/packages/contract-cli/tests/generator.test.js +++ b/packages/contract-cli/tests/generator.test.js @@ -3,6 +3,7 @@ const test = require('ava') const { join } = require('path') const { inspect } = require('util') const { + MODULE_TYPE, PUBLIC_KEY, DEFAULT_CONTRACT_FILE_NAME, PUBLIC_CONTRACT_FILE_NAME, @@ -29,8 +30,9 @@ test.after(async t => { fsx.removeSync(contractDir) fsx.removeSync(esContractDir) // remove the two generate files - fsx.removeSync( join(esResolverDir, DEFAULT_RESOLVER_LIST_FILE_NAME) ) - fsx.removeSync( join(esResolverDir, DEFAULT_RESOLVER_IMPORT_FILE_NAME) ) + // @NOTE remove these two files in 1.7.21 + // fsx.removeSync( join(esResolverDir, DEFAULT_RESOLVER_LIST_FILE_NAME) ) + // fsx.removeSync( join(esResolverDir, DEFAULT_RESOLVER_IMPORT_FILE_NAME) ) }) test.serial('Should able to read list of files', async t => { @@ -90,11 +92,11 @@ test.serial('It should able to parse ES6 style resolvers automatically', async t }) t.true( fsx.existsSync( join(esContractDir, DEFAULT_CONTRACT_FILE_NAME) ) ) - // - t.truthy( result.sourceType, 'should have a sourceType field' ) + // check if this is the module type + t.is( result.sourceType, MODULE_TYPE) - t.true( fsx.existsSync( join(esResolverDir, DEFAULT_RESOLVER_LIST_FILE_NAME) )) - t.true( fsx.existsSync( join(esResolverDir, DEFAULT_RESOLVER_IMPORT_FILE_NAME) )) + // t.true( fsx.existsSync( join(esResolverDir, DEFAULT_RESOLVER_LIST_FILE_NAME) )) + // t.true( fsx.existsSync( join(esResolverDir, DEFAULT_RESOLVER_IMPORT_FILE_NAME) )) }) test.serial('The ES6 public contract file should not contain a sourceType field', async t => { diff --git a/packages/koa/package.json b/packages/koa/package.json index e489d33521c90a5353c8f6411279a119cc594bad..9d1f6ce2810e335e12625c84f4ca26f0817d9936 100644 --- a/packages/koa/package.json +++ b/packages/koa/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-koa", - "version": "1.3.10", + "version": "1.3.11", "description": "jsonql Koa middleware", "main": "main.js", "module": "index.js", @@ -17,7 +17,7 @@ "coverage": "nyc ava --verbose", "test:basic": "DEBUG=jsonql* ava ./tests/koa.test.js", "test:notfound": "DEBUG=jsonql-koa* ava --verbose ./tests/resolverNotFound.test.js", - "test:es6": "DEBUG=jsonql-koa* ava --verbose ./tests/es6-module.test.js", + "test:es6": "DEBUG=jsonql-* ava --verbose ./tests/es6-module.test.js", "test:jwt": "DEBUG=jsonql-koa*,jsonql-jwt* ava ./tests/jwt.test.js", "test:jwt-auth": "DEBUG=jsonql-koa* ava ./tests/jwt-auth.test.js", "test:fail": "ava ./tests/fail.test.js", @@ -72,12 +72,12 @@ "esm": "^3.2.25", "fs-extra": "^8.1.0", "jsonql-constants": "^1.8.3", - "jsonql-contract": "^1.7.16", + "jsonql-contract": "^1.7.20", "jsonql-errors": "^1.1.3", "jsonql-jwt": "^1.3.2", "jsonql-node-client": "^1.1.9", "jsonql-params-validator": "^1.4.11", - "jsonql-resolver": "^0.8.7", + "jsonql-resolver": "^0.9.2", "jsonql-utils": "^0.6.12", "jsonql-web-console": "^0.4.3", "koa": "^2.8.2", diff --git a/packages/koa/tests/es6-module.test.js b/packages/koa/tests/es6-module.test.js index a5dbcf0d337b203eb3dda3365b7f3f7d42562b2f..927245da78a6205fe119cf622023ba271da24397 100644 --- a/packages/koa/tests/es6-module.test.js +++ b/packages/koa/tests/es6-module.test.js @@ -53,6 +53,7 @@ test('It should able to handle a ES6 function', async t => { createQuery('getSomething') ) t.is(200, res.status) + // @BUG the result is undefined t.true(Array.isArray(res.body.data)) diff --git a/packages/koa/tests/node-client._test_.js b/packages/koa/tests/node-client.test.js similarity index 87% rename from packages/koa/tests/node-client._test_.js rename to packages/koa/tests/node-client.test.js index c749becfb686ee48801ba099c8ed97a42277fd3e..d4a8ee7cdc85776187c939bb3f6dd7b6ca12b7f4 100644 --- a/packages/koa/tests/node-client._test_.js +++ b/packages/koa/tests/node-client.test.js @@ -49,7 +49,7 @@ test.skip(`First test both server is running`, async t => { t.is(res2.status, 200) }) -test.skip(`First test calling the 6001 directly with the mutation call`, async t => { +test.skip(`First test calling the ${port} directly with the mutation call`, async t => { const client = await nodeClient({ hostname: `http://localhost:${msPort}`, contractDir: join(__dirname, 'fixtures', 'tmp', `client${msPort}`) @@ -58,13 +58,15 @@ test.skip(`First test calling the 6001 directly with the mutation call`, async t t.truthy(result.indexOf(`ms service`)) }) -test(`It should able to call a resolver that access another ms`, async t => { +test.skip(`It should able to call a resolver that access another ms`, async t => { // the problem now is calling the 6001 but received the 8001 public contract? const client = await nodeClient({ hostname: `http://localhost:${port}`, contractDir: clientContractDir }) - const result = await client.mutation.updateMsService('testing') + debug(client) + + const result = await client.mutation.subUpdateMsService('testing') t.truthy(result.indexOf(`ms service`)) }) diff --git a/packages/koa/tests/resolverNotFound.test.js b/packages/koa/tests/resolverNotFound.test.js index 4412f27e3793f1f16d511a943756aefe786d1a46..2cd96953673185ada8c5e2a9a4b03527fa32c7a7 100644 --- a/packages/koa/tests/resolverNotFound.test.js +++ b/packages/koa/tests/resolverNotFound.test.js @@ -31,7 +31,7 @@ test('it should throw a ResolverNotFoundError', async (t) => { t.is(res.body.error.statusCode, 404) }) -// @BUG need fixing +// @BUG need fixing test("It should cause an Application error but nothing throw", async t => { let res = await superkoa(t.context.app) .post('/jsonql') @@ -46,4 +46,6 @@ test("It should cause an Application error but nothing throw", async t => { t.is(true, res.status === 200) + t.is('JsonqlResolverAppError', res.body.error.className) + }) diff --git a/packages/node-client/package.json b/packages/node-client/package.json index 52ff4e1f19a715d8652aed9d3cbb155eafd4bf4f..9e0647dbb188b5261d3f9d0ae6fc5e538a4e65fe 100755 --- a/packages/node-client/package.json +++ b/packages/node-client/package.json @@ -42,14 +42,14 @@ "jsonql-errors": "^1.1.3", "jsonql-jwt": "^1.3.2", "jsonql-params-validator": "^1.4.11", - "jsonql-utils": "^0.6.10", + "jsonql-utils": "^0.6.12", "lodash.merge": "^4.6.2", "node-cache": "^4.2.1", "request": "^2.88.0" }, "devDependencies": { "ava": "^2.4.0", - "jsonql-contract": "^1.7.15", + "jsonql-contract": "^1.7.20", "jsonql-koa": "^1.3.9", "nyc": "^14.1.1", "server-io-core": "^1.2.0", diff --git a/packages/resolver/package.json b/packages/resolver/package.json index 9bfc5c2da697ff4dbab608a068d648922d2ba049..b5d3e501a04f98e0471aa44ecde4aef411398ba7 100644 --- a/packages/resolver/package.json +++ b/packages/resolver/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-resolver", - "version": "0.9.0", + "version": "0.9.3", "description": "This is NOT for general use, please do not install it directly. This module is part of the jsonql tools supporting modules.", "main": "index.js", "files": [ @@ -12,6 +12,7 @@ "prepare": "npm run test", "test:clients": "DEBUG=jsonql* ava --verbose ./tests/clients.test.js", "test:throw": "DEBUG=jsonql-resolver* ava --verbose ./tests/throw.test.js", + "test:es": "DEBUG=jsonql-resolver* ava --verbose ./tests/es.test.js", "contract": "DEBUG=jsonql-contract* jsonql-contract create ./tests/fixtures/resolvers ./tests/fixtures/contract" }, "keywords": [ @@ -36,7 +37,7 @@ }, "devDependencies": { "ava": "^2.4.0", - "jsonql-contract": "^1.7.19", + "jsonql-contract": "^1.7.20", "jsonql-koa": "^1.3.9", "server-io-core": "^1.2.0" }, diff --git a/packages/resolver/src/resolve-methods.js b/packages/resolver/src/resolve-methods.js index ed37f153a833504d1f2f2fc6642da6398d6446d0..b0be78fa35ba0af369386f50ec45efa5a4f44194 100644 --- a/packages/resolver/src/resolve-methods.js +++ b/packages/resolver/src/resolve-methods.js @@ -16,10 +16,11 @@ const { handleOutput, ctxErrorHandler, packResult, - extractArgsFromPayload + extractArgsFromPayload, + findFromContract } = require('jsonql-utils') const { getDebug } = require('./utils') -const { searchResolvers, importFromModule } = require('./search-resolvers') +const { searchResolvers, importFromModule, requireEsModule } = require('./search-resolvers') const { validateAndCall } = require('./validate-and-call') const { provideNodeClients } = require('./provide-node-clients') @@ -40,8 +41,13 @@ const executeResolver = (opts, type, resolverName, payload, contract, userdata = let fn; const { sourceType } = contract; if (sourceType === MODULE_TYPE) { + /* const { resolverDir } = opts; fn = importFromModule(resolverDir, type, resolverName) + */ + const pathToResolver = findFromContract(type, resolverName, contract) + debug('call requireEsModule', resolverName, pathToResolver) + fn = requireEsModule(pathToResolver) } else { fn = require(searchResolvers(resolverName, type, opts, contract)) } diff --git a/packages/resolver/src/search-resolvers.js b/packages/resolver/src/search-resolvers.js index 38521f6a12e6cf021c47c41ce26d1c5e5fe26200..0a533b4d8e0298331f1e7b4438652874116cc9e8 100644 --- a/packages/resolver/src/search-resolvers.js +++ b/packages/resolver/src/search-resolvers.js @@ -1,5 +1,5 @@ // search for the resolver location -// const { join } = require('path') +const { join } = require('path') const { JsonqlResolverNotFoundError } = require('jsonql-errors') const { getPathToFn, findFromContract } = require('jsonql-utils') @@ -24,6 +24,32 @@ function importFromModule(resolverDir, type, resolverName) { return resolvers[ [type, resolverName].join('') ] } +/** + * Try to use the esm module to require the module directly + * @param {string} pathToResolver path to resolver from contract + * @return {*} resolver function on success + */ +function requireEsModule(pathToResolver) { + let oldRequire; + try { + oldRequire = require; + require = require("esm")(module/*, options*/) + const obj = require(pathToResolver) + debug(obj) + if (typeof obj === 'function') { + return obj; + } else if (obj.default && typeof obj.default === 'function') { + return obj.default; + } + throw new Error(`Unable to import ES module!`) + } catch (e) { + throw new Error(e) + } finally { + // reset the require here? + require = oldRequire; // reset + } +} + /** * search for the file starting with * 1. Is the path in the contract (or do we have a contract file) @@ -38,15 +64,16 @@ function importFromModule(resolverDir, type, resolverName) { function searchResolvers(name, type, opts, contract) { try { const json = typeof contract === 'string' ? JSON.parse(contract) : contract; - const search = findFromContract(type, name, json) - if (search !== false) { - return search; + let pathToResolver; + pathToResolver = findFromContract(type, name, json) + if (pathToResolver !== false) { + return pathToResolver; } debug(`contract is not contract?`, contract) // search by running - const filePath = getPathToFn(name, type, opts) - if (filePath) { - return filePath; + pathToResolver = getPathToFn(name, type, opts) + if (pathToResolver) { + return pathToResolver; } const debugMsg = `${name} not found! [${opts.name}]`; debug('JsonqlResolverNotFoundError', debugMsg) @@ -59,5 +86,6 @@ function searchResolvers(name, type, opts, contract) { module.exports = { searchResolvers, - importFromModule + importFromModule, + requireEsModule } diff --git a/packages/resolver/tests/es.test.js b/packages/resolver/tests/es.test.js new file mode 100644 index 0000000000000000000000000000000000000000..2602e859b271ade30d3ad77b4ef0c52d66a4d739 --- /dev/null +++ b/packages/resolver/tests/es.test.js @@ -0,0 +1,50 @@ +// test the ES module import +const test = require('ava') +const { join } = require('path') +const debug = require('debug')('jsonql-resolver:test:es') +const contractApi = require('jsonql-contract') +// method to test +const { executeResolver } = require('../') +const { createQuery } = require('jsonql-utils') +// variables +const resolverDir = join(__dirname, 'fixtures', 'es') +const contractDir = join(__dirname, 'fixtures', 'contract', 'es') +// before test +test.before(async t => { + t.context.opts = { + resolverDir, + contractDir, + returnAs: 'json' + } + // generate contract file for the es + t.context.contract = await contractApi(t.context.opts) +}) +// after test +test.after(t => { + // todo +}) + +// start testing +test(`It should able to generate a contract for the es module`, t => { + const contract = t.context.contract; + + debug(contract) + + t.truthy(contract.query) +}) + +test.only(`It should able to use the requireEsModule to import ES module to commonjs code base`, async t => { + const resolverName = 'getSomething'; + const payload = createQuery(resolverName, []) + + const result = await executeResolver( + t.context.opts, + 'query', + resolverName, + payload[resolverName], + t.context.contract + ) + + t.is('Hello there', result[0]) + +}) diff --git a/packages/resolver/tests/fixtures/contract/es/contract.json b/packages/resolver/tests/fixtures/contract/es/contract.json new file mode 100644 index 0000000000000000000000000000000000000000..dd6753f674201163da095736d5e0cf091df73d97 --- /dev/null +++ b/packages/resolver/tests/fixtures/contract/es/contract.json @@ -0,0 +1,48 @@ +{ + "query": { + "getSomething": { + "file": "/home/joel/projects/open-source/jsonql/packages/resolver/tests/fixtures/es/query/get-something.js", + "description": false, + "params": [], + "returns": [ + { + "type": [ + "array" + ], + "description": "list of something" + } + ] + } + }, + "mutation": { + "saveSomething": { + "file": "/home/joel/projects/open-source/jsonql/packages/resolver/tests/fixtures/es/mutation/save-something.js", + "description": false, + "params": [ + { + "type": [ + "object" + ], + "name": "payload" + }, + { + "type": [ + "object" + ], + "name": "condition" + } + ], + "returns": [ + { + "type": [ + "boolean" + ], + "description": "true on OK" + } + ] + } + }, + "auth": {}, + "timestamp": 1570437612, + "sourceType": "module" +} diff --git a/packages/resolver/tests/fixtures/es/import.js b/packages/resolver/tests/fixtures/es/import.js new file mode 100644 index 0000000000000000000000000000000000000000..6601f782c3497ae953db86928e4e6e922da04a10 --- /dev/null +++ b/packages/resolver/tests/fixtures/es/import.js @@ -0,0 +1,2 @@ +require = require("esm")(module/*, options*/) +module.exports = require("./resolver.js") diff --git a/packages/resolver/tests/fixtures/es/mutation/save-something.js b/packages/resolver/tests/fixtures/es/mutation/save-something.js new file mode 100644 index 0000000000000000000000000000000000000000..ea30ca671bbfb46aa5caacefe000e8d0c9114a2b --- /dev/null +++ b/packages/resolver/tests/fixtures/es/mutation/save-something.js @@ -0,0 +1,9 @@ + +/** + * @param {object} payload + * @param {object} condition + * @return {boolean} true on OK + */ +export default function saveSomething(payload, condition) { + return true; +} diff --git a/packages/resolver/tests/fixtures/es/query/get-something.js b/packages/resolver/tests/fixtures/es/query/get-something.js new file mode 100644 index 0000000000000000000000000000000000000000..9a5d7c8c86d5c44bac11228be7cb8436c85d60d9 --- /dev/null +++ b/packages/resolver/tests/fixtures/es/query/get-something.js @@ -0,0 +1,8 @@ + + +/** + * @return {array} list of something + */ +export default function getSomething() { + return ['Hello there'] +} diff --git a/packages/resolver/tests/fixtures/es/resolver.js b/packages/resolver/tests/fixtures/es/resolver.js new file mode 100644 index 0000000000000000000000000000000000000000..9057792d52c58f8bf7b6f1ff88ab9fbc7c4f3967 --- /dev/null +++ b/packages/resolver/tests/fixtures/es/resolver.js @@ -0,0 +1,7 @@ +import querygetSomething from './query/get-something.js' +import mutationsaveSomething from './mutation/save-something.js' + +export { + querygetSomething, +mutationsaveSomething +} \ No newline at end of file