diff --git a/packages/contract-cli/extra.js b/packages/contract-cli/extra.js index bf0ea852bafa0eeb3a9ffd85f7a2eb33a4d6d6aa..75548500a641e9d5900288eaed1e29700a26dfa7 100644 --- a/packages/contract-cli/extra.js +++ b/packages/contract-cli/extra.js @@ -4,11 +4,14 @@ const fsx = require('fs-extra') const { join } = require('path') const nbSplitTasks = require('nb-split-tasks') +const { getSocketAuthResolver } = require('./src/generator/get-socket-auth-resolver') + const contractApi = require('./index') const { DEFAULT_CONTRACT_FILE_NAME, PUBLIC_CONTRACT_FILE_NAME } = require('jsonql-constants') const debug = require('debug')('jsonql-contract:extra') + /** * @param {string} contractDir where the contract is * @param {boolean} pub system of public @@ -70,5 +73,6 @@ const splitContractGenerator = function(config, pub = false) { module.exports = { contractGenerator, readContract, - splitContractGenerator + splitContractGenerator, + getSocketAuthResolver } diff --git a/packages/contract-cli/package.json b/packages/contract-cli/package.json index b73772cab944b01820ad0c909e0f0836f1b2fef0..45b541d9c318488e5fc94e7d0e98990329f5f10e 100755 --- a/packages/contract-cli/package.json +++ b/packages/contract-cli/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-contract", - "version": "1.8.9", + "version": "1.8.10", "description": "JS API / command line tool to generate the contract.json for jsonql", "main": "index.js", "files": [ @@ -17,17 +17,17 @@ "cli": "DEBUG=jsonql-contract* node ./cli.js", "cli:watch": "DEBUG=jsonql-contract* node ./watch.js", "test": "ava", + "test:debug": "DEBUG=jsonql* ava tests/koa-debug.donttest.js", "test:socket": "DEBUG=jsonql-contract* ava ./tests/socket.test.js", "test:cli": "npm run cli configFile ./tests/fixtures/cmd-config-test.js", "test:doc": "DEBUG=jsonql-contract:* ava ./tests/contract-with-doc.test.js", - "test:gen": "DEBUG=jsonql-contract:* ava ./tests/generator.test.js", + "test:gen": "DEBUG=jsonql-contract:test* ava ./tests/generator.test.js", "test:path": "DEBUG=jsonql-contract:* ava tests/paths.test.js", "test:extra": "DEBUG=jsonql-contract:* ava tests/extra-props.test.js", "test:cmd": "DEBUG=jsonql-contract:* ava tests/cmd.test.js", "test:watch": "DEBUG=jsonql-contract:* ava tests/watch.test.js", "test:config": "DEBUG=jsonql-contract:* ava tests/config-params.test.js", "test:custom": "DEBUG=jsonql-contract:* ava tests/custom-login.test.js", - "test:debug": "DEBUG=jsonql* ava tests/koa-debug.test.js", "test:split": "DEBUG=jsonql-contract* ava tests/split-task.test.js", "test:dc": "DEBUG=jsonql-contract* ava tests/debug-contract.test.js", "test:public": "DEBUG=jsonql-contract:* ava tests/public-enable-auth-false.test.js" @@ -35,7 +35,9 @@ "keywords": [ "jsonql", "nodejs", - "node" + "node", + "contract", + "public-contract" ], "author": "to1soure ", "contributors": [ @@ -55,7 +57,7 @@ "jsdoc-api": "^5.0.4", "jsonql-constants": "^1.9.10", "jsonql-errors": "^1.1.10", - "jsonql-params-validator": "^1.5.3", + "jsonql-params-validator": "^1.6.0", "jsonql-utils": "^1.1.3", "kefir": "^3.8.6", "lodash": "^4.17.15", diff --git a/packages/contract-cli/src/ast/jsdoc.js b/packages/contract-cli/src/ast/jsdoc.js index f50e539fbde18a94d35e0fe0d31810f414047839..45240bd55fdfe6277d04061e0efebc06c9ca5bd6 100644 --- a/packages/contract-cli/src/ast/jsdoc.js +++ b/packages/contract-cli/src/ast/jsdoc.js @@ -1,9 +1,9 @@ // using jsdoc-cli to read the file and get additional properties // @TODO we still need to handle the @callback tag for function parameter // http://usejsdoc.org/tags-param.html -// const fs = require('fs-extra') -// const { join } = require('path') +const { join } = require('path') const { inspect } = require('util') +const fs = require('fs-extra') const jsdoc = require('jsdoc-api') const debug = require('debug')('jsonql-contract:jsdoc-api') const { diff --git a/packages/contract-cli/src/generator/generate-output.js b/packages/contract-cli/src/generator/generate-output.js index 2efcd39f5da1e858609f5cde20f4d44e96eebca3..c2d4e692a6675361e8a5aafa0f118208a12c7459 100644 --- a/packages/contract-cli/src/generator/generate-output.js +++ b/packages/contract-cli/src/generator/generate-output.js @@ -1,18 +1,19 @@ // the final step to generate output const { RETURN_AS_JSON } = require('jsonql-constants') -const { keepOrCleanContract, writeFileOut } = require('./files-op') +const { keepOrCleanContract, isContractExisted, writeFileOut } = require('./files-op') const { mutateContract } = require('./helpers') const { join } = require('path') - /** * Generate the final contract output to file + * @param {string} sourceType what type of file we are dealing with * @param {object} config output directory * @param {object} contract processed result + * @param {boolean|object} [rawData=false] the raw contract data for ES6 create files * @return {boolean} true on success */ -const generateOutput = function(config, contract) { +const generateOutput = function(sourceType, config, contract, rawData = false) { // this return a promise interface - const { outputFilename, contractDir } = config + const { outputFilename, contractDir, resolverDir } = config; const dist = join(contractDir, outputFilename) // keep or remove the existing contract file return keepOrCleanContract(config, dist) diff --git a/packages/contract-cli/src/generator/get-resolver.js b/packages/contract-cli/src/generator/get-resolver.js index 8422d1b0b9e9b224a50f59deafde14fbd507121b..5fa417ddcf9078cfc73b30eb0d071b69526a91d4 100644 --- a/packages/contract-cli/src/generator/get-resolver.js +++ b/packages/contract-cli/src/generator/get-resolver.js @@ -1,65 +1,22 @@ // this is the HEART of this module const fsx = require('fs-extra') -const { basename } = require('path') -const { compact, merge } = require('lodash') +const { basename } = require('path') // join, +const { compact } = require('lodash') +const { INDEX_KEY } = require('jsonql-constants') const { - MODULE_TYPE, - SCRIPT_TYPE, - INDEX_KEY -} = require('jsonql-constants') -const { - // logToFile, + // addPublicKey, inTypesArray, isAuthType, checkIfIsPublic, checkIfIsPrivate, - // addPublicKey, packOutput } = require('./helpers') -const { - astParser, - // extractReturns, - extractParams, - isExpression, - getJsdoc -} = require('../ast') -const { getDebug, getTimestamp } = require('../utils') -const debug = getDebug('generator:get-resolvers') -/** - * There is a potential bug here if the first file is not a resolver than this will failed! - * Use the first file to determine the source type NOT ALLOW MIX AND MATCH - * @param {string} source the path to the file - * @return {string} sourceType - */ -const sourceFileType = src => { - const source = fsx.readFileSync(src, 'utf8').toString() - if (source.indexOf('module.exports') > -1) { - return SCRIPT_TYPE - } else if (source.indexOf('export default') > -1) { - return MODULE_TYPE - } - return false -} +const { getDebug, getTimestamp } = require('../utils') +const { getSourceType } = require('./get-source-type') +const { parseFileToAst } = require('./parse-file-to-ast') -/** - * Try to find out the resourceType until we find it - * @param {array} objs array of objs - * @return {object} add the resourceType to the object - */ -function getSourceType(objs) { - let sourceType - let ctn = objs.lengths - for (let i = 0; i < ctn; ++i) { - if (!sourceType) { - resourceType = sourceFileType(objs[i].file) - if (resourceType) { - return resourceType - } - } - } - throw new Error(`Can not determine the resourceType!`) -} +const debug = getDebug('generator:get-resolvers') /** * Breaking out from the getResolver because we need to hook another method into it @@ -76,7 +33,7 @@ const checkResolver = (indexFile, inDir, fileType, config) => (baseFile) => { const type = fileParts[0] // we ignore all the fileParts on the root level if (fileParts.length === 1) { - return failed + return failed; } const ext = '.' + fileType // process fileParts within the folder of query, mutation, auth @@ -148,12 +105,7 @@ function getResolver(config, fileType) { function processResolverToContract(type, name, file, public, namespace, sourceType) { // how do I change this to non-block instead? const source = fsx.readFileSync(file, 'utf8').toString() - // parsing the file - const result = astParser(source, { sourceType }) - // logToFile(config.logDirectory, [type, name].join('-'), result) - // get params @BUG the error happens here? - const baseParams = result.body.filter(isExpression).map(extractParams).filter(p => p) - const { description, params, returns } = getJsdoc(source, name) + const { params, description, returns } = parseFileToAst(source, name, sourceType) // return return { [type]: { @@ -162,8 +114,8 @@ function processResolverToContract(type, name, file, public, namespace, sourceTy public, // mark if this is a public accessible method or not file, description, - params: merge([], baseParams[0], params), // merge array NOT OBJECT - returns: returns // merge({}, takeDownArray(returns), returns) + params, // merge array NOT OBJECT + returns } } } diff --git a/packages/contract-cli/src/generator/get-socket-auth-resolver.js b/packages/contract-cli/src/generator/get-socket-auth-resolver.js index 52b81226bd4221b6a8f35d4449b6c44e336c5059..fbdd27db5d6efaeded045622d853bc8f2c9ac4de 100644 --- a/packages/contract-cli/src/generator/get-socket-auth-resolver.js +++ b/packages/contract-cli/src/generator/get-socket-auth-resolver.js @@ -3,24 +3,38 @@ // its mainly for internal use const fsx = require('fs-extra') const debug = require('debug')('jsonql-contract:generator:get-socket-auth-resolver') -const { join } = require('path') -const { SOCKET_NAME, AUTH_TYPE } = require('jsonql-constants') +const { join, basename } = require('path') +const { SOCKET_NAME, AUTH_NAME, EXT } = require('jsonql-constants') const { getResolverFiles } = require('./read-files-out-contract') - - -function getSocketAuthResolver(resolverDir, fileType) { - +const { inArray } = require('jsonql-params-validator') +const { getSourceType } = require('./get-source-type') +const { parseFileToAst } = require('./parse-file-to-ast') +const { chainPromises } = require('jsonql-utils') +/** + * Return the list of files from the folder first + * @param {string} resolverDir where the base resolver directory + * @param {string} [fileExt=EXT] what type of files + * @return {promise} resolve the list of files + */ +function getSocketAuthResolverFiles(resolverDir, fileExt = EXT) { + const dir = join(resolverDir, SOCKET_NAME, AUTH_NAME) + if (fsx.existsSync(dir)) { + return getResolverFiles(dir, fileExt) + } + debug(`${dir} not existed!`) + // we don't throw error here just return an empty result + return Promise.resolve([]) } /** * Take the list of files from the folder, then filter out those that are not * registered socket auth files - * @param {array} authFiles the list of auth files - * @param {string} fileType the file extension * @param {object} config configuration options - * @return {array} the list of registered socket auth files + * @param {array} authFiles the list of auth files + * @param {string} fileExt the file extension + * @return {object} the list of registered socket auth files using name as key */ -function filterAuthFiles(authFiles, fileType, config) { +function filterAuthFiles(config, authFiles, fileExt = EXT) { // setup the targets const { loginHandlerName, @@ -32,27 +46,83 @@ function filterAuthFiles(authFiles, fileType, config) { logoutHandlerName, disconnectHandlerName ] - return authFiles.filter(file => { - - }) + return authFiles + .map(file => { + const name = basename(file).replace('.'+fileExt, '') + return {[name]: file} + }) + .filter(fileObj => { + const name = Object.keys(fileObj)[0] + return inArray(targets, name) + }) + .reduce((a,b) => Object.assign(a, b), {}) +} +/** + * This is similiar to the processResolverToContract in get-resolver + * but we don't need that many options, so this is a cut down version + * @param {string} file path to the file + * @param {string} sourceType what type are they + * @return {promise} resolve the partial contract for that particular resolver + */ +function processFileToContract(name, file, sourceType) { + + return Promise + .resolve(fsx.readFileSync(file, 'utf8').toString() ) + .then(source => parseFileToAst(source, name, sourceType)) + .then(({ description, params, returns }) => ( + { + [name]: { + file, + description, + returns, + params + } + } + )) } /** - * Return the list of files from the folder first - * @param {string} resolverDir where the base resolver directory - * @param {string} fileType what type of files - * @return {promise} resolve the list of files + * The main method to generate the partial contract of the socket auth methods + * @param {object} config configuration + * @param {string} resolverDir where the resolvers are + * @param {string|boolean} [sourceType=null] what type of files are they ES6 or CS + * @param {string} [fileExt=EXT] the file extension + * @return {promise} resolve the socket auth partial contract */ -function getSocketAuthResolverFiles(resolverDir, fileType) { - const dir = join(resolverDir, SOCKET_NAME, AUTH_TYPE) - if (fsx.existsSync(dir)) { - return getResolverFiles(dir, fileType) - } - debug(`${dir} not existed!`) - // we don't throw error here just return an empty result - return Promise.resolve([]) +function getSocketAuthResolver(config, resolverDir, sourceType = null, fileExt = EXT) { + + return getSocketAuthResolverFiles(resolverDir, fileExt) + .then(files => filterAuthFiles(config, files, fileExt)) + .then(fileObj => { + if (sourceType === null) { + // need to match the expected object structure + const _files = Object.values(fileObj).map(f => ({file: f})) + + return { + sourceType: getSourceType(_files), + fileObj + } + } + return { sourceType, fileObj } + }) + .then(({ sourceType, fileObj }) => { + const names = Object.keys(fileObj) + const files = Object.values(fileObj) + + return chainPromises( + names.map((n, i) => ( + Promise.resolve(processFileToContract(n, files[i], sourceType)) + )) + ) + }) } +module.exports = { + getSocketAuthResolver, + filterAuthFiles, + getSocketAuthResolverFiles +} + diff --git a/packages/contract-cli/src/generator/get-source-type.js b/packages/contract-cli/src/generator/get-source-type.js new file mode 100644 index 0000000000000000000000000000000000000000..2bf1c1e900ff105504f63760a1281b4572b5f85a --- /dev/null +++ b/packages/contract-cli/src/generator/get-source-type.js @@ -0,0 +1,43 @@ +// breaking this out from get-resolver and re-use in two places +const fsx = require('fs-extra') +const { + MODULE_TYPE, + SCRIPT_TYPE +} = require('jsonql-constants') + +/** + * There is a potential bug here if the first file is not a resolver than this will failed! + * Use the first file to determine the source type NOT ALLOW MIX AND MATCH + * @param {string} source the path to the file + * @return {string} sourceType + */ +const sourceFileType = src => { + const source = fsx.readFileSync(src, 'utf8').toString() + if (source.indexOf('module.exports') > -1) { + return SCRIPT_TYPE + } else if (source.indexOf('export default') > -1) { + return MODULE_TYPE + } + return false +} + +/** + * Try to find out the resourceType until we find it + * @param {array} objs array of objs + * @return {object} add the resourceType to the object + */ +function getSourceType(objs) { + let sourceType + let ctn = objs.length + for (let i = 0; i < ctn; ++i) { + if (!sourceType) { + resourceType = sourceFileType(objs[i].file) + if (resourceType) { + return resourceType + } + } + } + throw new Error(`Can not determine the resourceType!`) +} + +module.exports = { getSourceType } \ No newline at end of file diff --git a/packages/contract-cli/src/generator/helpers.js b/packages/contract-cli/src/generator/helpers.js index 339ca03e8a860da300a38485bdb81951c0348882..4b9bfaf4aae0dc9197605befae570e42281afcfe 100644 --- a/packages/contract-cli/src/generator/helpers.js +++ b/packages/contract-cli/src/generator/helpers.js @@ -2,7 +2,7 @@ const fsx = require('fs-extra') const { merge, extend, camelCase } = require('lodash') const { isObject } = require('jsonql-params-validator') -const { isContract } = require('jsonql-utils') +const { isContract } = require('jsonql-utils') // isObjectHasKey, const { RESOLVER_TYPES, AUTH_TYPE, @@ -46,6 +46,7 @@ const isAuthType = function(type, file, config) { const { loginHandlerName, logoutHandlerName, validatorHandlerName } = config AUTH_TYPE_METHODS = [loginHandlerName, logoutHandlerName, validatorHandlerName] } + // debug('AUTH_TYPE_METHODS', AUTH_TYPE_METHODS) // debug('AUTH_TYPE_METHODS', resolverName, AUTH_TYPE_METHODS) return type === AUTH_TYPE && !!AUTH_TYPE_METHODS.filter(method => resolverName === method).length } @@ -105,7 +106,7 @@ const checkIfIsPrivate = (files, config) => ( * @return {object} flag up or not */ const addPublicKey = (baseObj, isPublic) => ( - extend( baseObj, (isPublic ? { public: isPublic } : {}) ) + extend( baseObj, (isPublic ? {public: isPublic} : {}) ) ) /** diff --git a/packages/contract-cli/src/generator/index.js b/packages/contract-cli/src/generator/index.js index ebe0da58ee0761451166c1fa934de83436847c5c..d5a168c54781a7f698a1ec88cdc313f1acfcbaa2 100644 --- a/packages/contract-cli/src/generator/index.js +++ b/packages/contract-cli/src/generator/index.js @@ -8,7 +8,7 @@ const { merge } = require('lodash') const colors = require('colors/safe') -// const debug = require('debug')('jsonql-contract:generator') +const debug = require('debug')('jsonql-contract:generator') const { PUBLIC_CONTRACT_FILE_NAME } = require('jsonql-constants') @@ -46,14 +46,15 @@ const banner = config => { */ const callPublicGenerator = (config, contract) => ( generateOutput( + contract.sourceType, merge({}, config, { outputFilename: PUBLIC_CONTRACT_FILE_NAME }), - publicContractGenerator(config, contract) + publicContractGenerator(config, contract), + contract // <-- this is when ES6 module require to generate import export files ) ) /** * This is taken out from the original generator main interface - * Create a new contract from scratch * @param {object} config options * @return {mixed} depends on the returnAs parameter */ @@ -65,7 +66,7 @@ const generateNewContract = (config) => { // we can get the sourceType from the contract return callPublicGenerator(config, contract) } - return generateOutput(config, contract) + return generateOutput(sourceType, config, contract) }) } diff --git a/packages/contract-cli/src/generator/parse-file-to-ast.js b/packages/contract-cli/src/generator/parse-file-to-ast.js new file mode 100644 index 0000000000000000000000000000000000000000..0565e0618fa05b901dc35a2f60da604ac2838f54 --- /dev/null +++ b/packages/contract-cli/src/generator/parse-file-to-ast.js @@ -0,0 +1,31 @@ +// take the core parse to ast function on its own for reuse +const { merge } = require('lodash') +const { + // extractReturns, + astParser, + extractParams, + isExpression, + getJsdoc +} = require('../ast') +/** + * Break out the core function for resuse + * @param {string} source read the resolver into file + * @param {string} name of the resovler + * @param {string} sourceType ES6 or other + */ +function parseFileToAst(source, name, sourceType) { + // parsing the file + const result = astParser(source, { sourceType }) + // logToFile(config.logDirectory, [type, name].join('-'), result) + // get params @BUG the error happens here? + const baseParams = result.body.filter(isExpression).map(extractParams).filter(p => p) + const { description, params, returns } = getJsdoc(source, name) + + return { + params: merge([], baseParams[0], params), + description, + returns + } +} + +module.exports = { parseFileToAst } \ No newline at end of file diff --git a/packages/contract-cli/src/generator/process-file.js b/packages/contract-cli/src/generator/process-file.js index 28f9b324ba419888bd7157b2c4563d0185234b68..e05fb8a65bcc0ee8efaad49ca20d2a41f8753967 100644 --- a/packages/contract-cli/src/generator/process-file.js +++ b/packages/contract-cli/src/generator/process-file.js @@ -1,5 +1,6 @@ // this is the heart of the process that pass the resolver file into the AST to understand it // const { join, basename } = require('path') +// const { EXT } = require('jsonql-constants') const { merge } = require('lodash') const { getResolver, @@ -9,7 +10,6 @@ const { } = require('./get-resolver') const { splitTask } = require('./split-task') const { NOT_ENOUGH_CPU } = require('nb-split-tasks/constants') -// const { EXT } = require('jsonql-constants') const { JsonqlError } = require('jsonql-errors') const { getDebug } = require('../utils') @@ -23,10 +23,8 @@ const debug = getDebug('process-file') */ function processFilesAction(files, fileType, config) { const preprocessor = getResolver(config, fileType) - return Promise - .resolve( - files - .map( preprocessor ) + return Promise.resolve( + files.map( preprocessor ) .filter( obj => obj.ok ) ) } diff --git a/packages/contract-cli/src/generator/read-files-out-contract.js b/packages/contract-cli/src/generator/read-files-out-contract.js index b2b54cdebe5a370f100157c26815967a9fa6331c..f0d71d738bc6009eba9b1d22236bd7eb7ed5161f 100644 --- a/packages/contract-cli/src/generator/read-files-out-contract.js +++ b/packages/contract-cli/src/generator/read-files-out-contract.js @@ -1,5 +1,5 @@ // Here is the point where we need to split to load to different CPU -const { join } = require('path') +const { join } = require('path') // basename // const os = require('os') const glob = require('glob') const colors = require('colors/safe') @@ -19,7 +19,7 @@ const debug = getDebug('read-files-out-contract') * @param {string} [fileType=EXT] the file extension * @return {promise} resolve the files array on success or reject with error */ -function getResolverFiles(resolverDir, fileType = EXT) { +function getResolverFiles(resolverDir, fileType) { const pat = join(resolverDir, '**', ['*', fileType].join('.')) return new Promise((resolver, rejecter) => { glob(pat, (err, files) => { @@ -38,11 +38,10 @@ function getResolverFiles(resolverDir, fileType = EXT) { * @return {object} query / mutation */ function readFilesOutContract(config) { - const { resolverDir } = config; + const { resolverDir } = config let fileType = config.ext || EXT let timestart = Date.now() - const name = 'readFilesOutContract' - console.time(name) + return getResolverFiles(resolverDir, fileType) .then(files => preprocessResolverFile(files, fileType, config) .then(result => { @@ -53,7 +52,7 @@ function readFilesOutContract(config) { ) .then(result => { let timeend = Date.now() - timestart - debug('Time it took:', colors.yellow(timeend), console.timeEnd(name)) + debug('Time it took:', colors.yellow(timeend)) return result }) } diff --git a/packages/contract-cli/src/generator/split-task.js b/packages/contract-cli/src/generator/split-task.js index 1072efe1dbfa740b0978bfae10c3261e8eae15b3..373837248869ffddcc9b4cf90935d3a20df4d750 100644 --- a/packages/contract-cli/src/generator/split-task.js +++ b/packages/contract-cli/src/generator/split-task.js @@ -3,7 +3,7 @@ const { join } = require('path') const nbSplitTasks = require('nb-split-tasks') const { getDebug } = require('../utils') -// const debug = getDebug('split-task') +const debug = getDebug('split-task') const basePath = join(__dirname, 'sub') diff --git a/packages/contract-cli/src/get-paths.js b/packages/contract-cli/src/get-paths.js index a3f3cabb1e5ac153120deb642cb64263d422e58a..62d60424f0a6bd4ac834b9b59bfae2dbc308bd14 100755 --- a/packages/contract-cli/src/get-paths.js +++ b/packages/contract-cli/src/get-paths.js @@ -17,19 +17,19 @@ function getPaths(argv) { if (argv.contractDir) { argv.contractDir = resolve(argv.contractDir) } else { - argv.contractDir = baseDir + argv.contractDir = baseDir; } argv.resolverDir = resolve(argv.resolverDir) - return resolver(argv) // just return it + return resolver(argv); // just return it } else if (argv._) { - const args = argv._ + const args = argv._; if (args[0]) { return resolver({ resolverDir: resolve(args[0]), contractDir: args[1] ? resolve(args[1]) : baseDir, // raw: argv.raw, if they are using command line raw is not available as option public: argv.public - }) + }); } } rejecter('You need to provide the input path!') diff --git a/packages/contract-cli/src/options/index.js b/packages/contract-cli/src/options.js similarity index 73% rename from packages/contract-cli/src/options/index.js rename to packages/contract-cli/src/options.js index 8080c85b3cd6611a6fac75bb5c3363e1bbb88da0..f1297f30cdce7dda98a0e4270f28b98a50148dae 100644 --- a/packages/contract-cli/src/options/index.js +++ b/packages/contract-cli/src/options.js @@ -1,10 +1,10 @@ // default options @TODO add in the next upgrade -const fs = require('fs') +// const fs = require('fs') const { resolve, join } = require('path') -const { - checkConfigAsync, - constructConfig, - createConfig +const { + checkConfigAsync, + constructConfig, + createConfig } = require('jsonql-params-validator') const { DEFAULT_RESOLVER_DIR, @@ -27,35 +27,25 @@ 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') -// injecter after check +const BASE_DIR = process.cwd() + 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]), - // 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 + // Auth related props loginHandlerName: createConfig(LOGIN_NAME, [STRING_TYPE]), logoutHandlerName: createConfig(LOGOUT_NAME, [STRING_TYPE]), validatorHandlerName: createConfig(VALIDATOR_NAME, [STRING_TYPE, BOOLEAN_TYPE]), - enableAuth: createConfig(false, BOOLEAN_TYPE, {[ALIAS_KEY]: AUTH_ALIAS}), + enableAuth: createConfig(false, BOOLEAN_TYPE, {[ALIAS_KEY]: 'auth'}), // 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 @@ -63,8 +53,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]: IN_DIR_ALIAS}), - contractDir: createConfig(resolve(join(BASE_DIR, DEFAULT_CONTRACT_DIR)), STRING_TYPE, {[ALIAS_KEY]: OUT_DIR_ALIAS}), + 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'}), // 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 @@ -76,22 +66,18 @@ 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]: 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'}), - + 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'}), logDirectory: constructConfig(false, [STRING_TYPE], true), - - tmpDir: createConfig(join(BASE_DIR, TMP_DIR), [STRING_TYPE]), + tmpDir: createConfig(join(BASE_DIR, 'tmp'), [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]), - standalone: createConfig(false, [BOOLEAN_TYPE], {[ALIAS_KEY]: STANDALONE_ALIAS}) + // add 1.8.7 to determine if we clean out the contract folder or not + development: createConfig(false, [BOOLEAN_TYPE]) } - // export it module.exports = config => checkConfigAsync(config, defaultOptions, constProps) diff --git a/packages/contract-cli/src/options/constants.js b/packages/contract-cli/src/options/constants.js deleted file mode 100644 index cf8d1cf0a16781a584bee67dc6dbf0b6daa35dc3..0000000000000000000000000000000000000000 --- a/packages/contract-cli/src/options/constants.js +++ /dev/null @@ -1,23 +0,0 @@ -// 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/public-contract/hello-world.json b/packages/contract-cli/src/public-contract/hello-world.json index cebe1fc8ea4108328fdad7598965601723d422e2..3598a33199d75945e32110f6f9072ac5ee8f6c35 100755 --- a/packages/contract-cli/src/public-contract/hello-world.json +++ b/packages/contract-cli/src/public-contract/hello-world.json @@ -5,9 +5,7 @@ "params": [], "returns": [ { - "type": [ - "string" - ], + "type": [ "string" ], "description": "stock message" } ] diff --git a/packages/contract-cli/src/utils.js b/packages/contract-cli/src/utils.js index 6961832697082b743866d22dd764043de4df5fd0..4155acb2c04bf730b685546e81e7f655018f4dd7 100644 --- a/packages/contract-cli/src/utils.js +++ b/packages/contract-cli/src/utils.js @@ -48,17 +48,18 @@ const getConfigFromArgs = (config, cmd) => ( if (key === '_') { switch (cmd) { case 'create': - let [inDir, outDir] = value - result.inDir = inDir - result.outDir = outDir - break + let [inDir, outDir] = value; + result.inDir = inDir; + result.outDir = outDir; + break; case 'remote': // @TODO throw new Error('Not support at the moment!') + break; case 'config': // we don't need to do anything here // console.log('config', key, value) - break + break; } } else { result[key] = value @@ -76,14 +77,11 @@ const getConfigFromArgs = (config, cmd) => ( const applyDefaultOptions = (config, cmd = false) => ( getConfigFromArgs(config, cmd) .then(config => { - getDebug('applyDefaultOptions')('show config', config) - if (config.public === 'true' || config.public === 1 || config.public === '1') { - config.public = true // because it might be a string true + config.public = true; // because it might be a string true } - - return config + return config; }) .then(checkForConfigFile) .then(checkOptions) diff --git a/packages/contract-cli/tests/config-params.test.js b/packages/contract-cli/tests/config-params.test.js index 09b8735331673e93c760fd11abf53d7094b33708..8ae323c06ef734c81a0dc0baf8406450d473e6bf 100644 --- a/packages/contract-cli/tests/config-params.test.js +++ b/packages/contract-cli/tests/config-params.test.js @@ -7,8 +7,8 @@ const fsx = require('fs-extra') const resolverDir = join(__dirname, 'fixtures', 'resolvers') const contractDir = join(__dirname, 'fixtures', 'tmp', 'private-test') const { extend } = require('lodash') -const contractFile = join(contractDir, 'contract.json') -const publicFile = join(contractDir, 'public-contract.json') +// const contractFile = join(contractDir, 'contract.json') +// const publicFile = join(contractDir, 'public-contract.json') const { JSONQL_PATH, PUBLIC_KEY, PRIVATE_KEY } = require('jsonql-constants') diff --git a/packages/contract-cli/tests/contract-with-doc.test.js b/packages/contract-cli/tests/contract-with-doc.test.js index 96ed8a88e9f158b9e5c79fbbe0c5f9af85acc82f..46db62e0556cfee8363f11a23eed6fc27c13e929 100644 --- a/packages/contract-cli/tests/contract-with-doc.test.js +++ b/packages/contract-cli/tests/contract-with-doc.test.js @@ -1,14 +1,14 @@ // this will test the contract with useDoc option const test = require('ava') const { join } = require('path') -const { inspect } = require('util') +// const { inspect } = require('util') const generator = require('../index') const resolverDir = join(__dirname, 'fixtures', 'resolvers') const contractDir = join(__dirname, 'fixtures', 'tmp', 'doc') -const debug = require('debug')('jsonql-contract:test:generator') +// const debug = require('debug')('jsonql-contract:test:generator') const fsx = require('fs-extra') const baseContractFile = join(contractDir, 'contract.json') -const publicContractFile = join(contractDir, 'public-contract.json') +// const publicContractFile = join(contractDir, 'public-contract.json') const { DEFAULT_TYPE } = require('jsonql-constants') const checkConfig = require('../src/options') diff --git a/packages/contract-cli/tests/custom-login.test.js b/packages/contract-cli/tests/custom-login.test.js index 9ab87ac19fc06f36ee23b7c63eaba63cf96c6e69..2c335b51c434e14dd68408e4ae82dcc48914723e 100644 --- a/packages/contract-cli/tests/custom-login.test.js +++ b/packages/contract-cli/tests/custom-login.test.js @@ -6,11 +6,11 @@ const { join } = require('path') const generator = require('../index') const resolverDir = join(__dirname, 'fixtures', 'resolvers') const contractDir = join(__dirname, 'fixtures', 'tmp', 'custom-login') -const debug = require('debug')('jsonql-contract:test:extra-props') +// const debug = require('debug')('jsonql-contract:test:extra-props') const fsx = require('fs-extra') const baseContractFile = join(contractDir, 'contract.json') -const publicContractFile = join(contractDir, 'public-contract.json') +// const publicContractFile = join(contractDir, 'public-contract.json') test.before(async t => { const result = await generator({ diff --git a/packages/contract-cli/tests/debug-contract.test.js b/packages/contract-cli/tests/debug-contract.donttest.js similarity index 94% rename from packages/contract-cli/tests/debug-contract.test.js rename to packages/contract-cli/tests/debug-contract.donttest.js index 24b397f1f0ce8a0a86d650150aee50718d680220..1c76ac102f5e53f5f65f88236e2f3d2feffee4ce 100644 --- a/packages/contract-cli/tests/debug-contract.test.js +++ b/packages/contract-cli/tests/debug-contract.donttest.js @@ -3,7 +3,7 @@ const test = require('ava') const { join } = require('path') -const fsx = require('fs-extra') +// const fsx = require('fs-extra') const baseDir = join(__dirname, '..', '..', 'node-client', 'tests', 'fixtures') const resolverDir = join(baseDir, 'resolvers') @@ -16,7 +16,7 @@ const debug = require('debug')('jsonql-contract:test:debug-contract') const generator = require('../index') test.after(t => { - // fsx.removeSync(contractDir) + fsx.removeSync(contractDir) }) test(`It should able to create contract with this resolverDir when using custom methods and enableAuth`, async t => { diff --git a/packages/contract-cli/tests/extra-props.test.js b/packages/contract-cli/tests/extra-props.test.js index 35c5b5eec7b59890419da0e2c859301e7c4fa993..85b2d24bd44167b9a42b73ce770c7d58c1617717 100644 --- a/packages/contract-cli/tests/extra-props.test.js +++ b/packages/contract-cli/tests/extra-props.test.js @@ -1,7 +1,7 @@ // test out the extra props will present on the contract.json or not const test = require('ava') const { join } = require('path') -const { inspect } = require('util') +// const { inspect } = require('util') const generator = require('../index') const resolverDir = join(__dirname, 'fixtures', 'resolvers') const contractDir = join(__dirname, 'fixtures', 'tmp', 'with-public-methods') @@ -9,7 +9,7 @@ const debug = require('debug')('jsonql-contract:test:extra-props') const fsx = require('fs-extra') const { RETURN_AS_JSON } = require('jsonql-constants') const baseContractFile = join(contractDir, 'contract.json') -const publicContractFile = join(contractDir, 'public-contract.json') +// const publicContractFile = join(contractDir, 'public-contract.json') test.before(async t => { const result = await generator({ diff --git a/packages/contract-cli/tests/fixtures/socket/config.js b/packages/contract-cli/tests/fixtures/socket/config.js index efb9dbf7f2f907e1d2df08446ecfd20f68fdacbd..91f4870d706595ea935ec2c429c789011ffd2a1a 100644 --- a/packages/contract-cli/tests/fixtures/socket/config.js +++ b/packages/contract-cli/tests/fixtures/socket/config.js @@ -1,10 +1,7 @@ // create a configuration files for the socket operation -const base = { - enableAuth: true, - loginHandlerName: 'login', - logoutHandlerName: 'logout' -} +const checkConfig = require('../../../src/options') -module.exports = function(extra = {}) { - return Object.assign({}, base, extra) + +module.exports = function(config = {}) { + return checkConfig(config) } \ No newline at end of file diff --git a/packages/contract-cli/tests/generator.test.js b/packages/contract-cli/tests/generator.test.js index 7adf0c8b16e3fb69a445a073a6de29868f14b3c8..3b9a0b7305b7d87f3793202b792bd01f01ffa16b 100755 --- a/packages/contract-cli/tests/generator.test.js +++ b/packages/contract-cli/tests/generator.test.js @@ -21,7 +21,7 @@ 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 esContractDir = join(__dirname, 'tmp', 'es') const esResolverDir = join(__dirname, 'fixtures', 'es') const expired = Date.now() + 60*365*1000 @@ -68,11 +68,14 @@ test.only('Should able to create a public-contract.json', async t => { t.true(fsx.existsSync(publicContractFile)) const json = fsx.readJsonSync(publicContractFile) + debug('output json', json) + t.is(json.expired, expired, 'Expired field should be the same as what is given') t.false(!!json.auth.validator, 'should not have a validator field') - // there is no auth in there - t.true(json.auth.login !== undefined, 'should have a login') + // there is no auth in theres + t.truthy(json.auth.login, 'should have a login') + // now check if certain method is public t.true(json.query.anyoneCanGetThis.public, 'anyoneCanGetThis should be public') // now check if certain method in private folder is included diff --git a/packages/contract-cli/tests/socket.test.js b/packages/contract-cli/tests/socket.test.js index f74cbd341b0a39405ceff03470e4fef0a6f8a093..253e1bf7a774d082c534f56c9aff2322df83aa0e 100644 --- a/packages/contract-cli/tests/socket.test.js +++ b/packages/contract-cli/tests/socket.test.js @@ -5,31 +5,49 @@ const fsx = require('fs-extra') const { SOCKET_NAME, AUTH_TYPE } = require('jsonql-constants') const resolverDir = join(__dirname, 'fixtures', 'resolvers') const { - getResolver, - getSourceType, - getContractBase -} = require('../src/generator/get-resolver') -const { getResolverFiles } = require('../src/generator/read-files-out-contract') + filterAuthFiles, + getSocketAuthResolverFiles +} = require('../src/generator/get-socket-auth-resolver') +const { getSocketAuthResolver } = require('../extra') +const getConfig = require('./fixtures/socket/config') -const socketConfig = require('./fixtures/socket/config') +// const socketConfig = require('./fixtures/socket/config') const debug = require('debug')('jsonql-contract:test:socket') +test.before(async t => { + t.context.config = await getConfig({enableAuth: true}) +}) + test.cb(`It should able to return a list of socket auth files`, t => { t.plan(1) - getResolverFiles(join(resolverDir, SOCKET_NAME, AUTH_TYPE)) + getSocketAuthResolverFiles(resolverDir) .then(files => { debug('files', files) - t.pass() + t.truthy(files.length) + + const filteredFiles = filterAuthFiles(t.context.config, files) + + debug('filtered', filteredFiles) + t.end() }) - }) +test.cb.only(`It should able to generate partial contract for socket auth`, t => { + t.plan(1) + getSocketAuthResolver(t.context.config, resolverDir) + .then(contract => { + debug('partial contract', contract) + t.truthy(contract) + t.end() + }) + +}) 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 c4d029a8153a8c0169f31e79ac7622aac9376584..52aaf1dc4c2cce0af8d32aa480ccb97a269ffaf9 100644 --- a/packages/node-client/tests/fixtures/jwt/contract.json +++ b/packages/node-client/tests/fixtures/jwt/contract.json @@ -102,7 +102,7 @@ ] } }, - "timestamp": 1584151039, + "timestamp": 1584193871, "sourceType": "script", "socket": { "gateway": {