Nitrogenous Polymorphic Molecule
Learn about our RFC process, Open RFC meetings & more.Join in the discussion! »

jsonql-contract

1.9.2 • Public • Published

NPM

jsonql-contract

an automated tool to generate the contract file using AST / JSDOC

The contract file is the heart of the entire jsonql libraries. This is how we bind everything together. And jsonql-contract is the core engine to generate this files.

Installation

$ npm install jsonql-contract --global

You don't normally need to execute this directly. This module is included in every jsonql libraries tool that require it, and it's run automatically. But for testing purpose, you should install it and get yourself familiar with the contract files.

Command line options

Type jsonql-contract --help will show you all the available commands and options.

Here are all the command line options:

Local development

$ jsonql-contract create /path/to/your/resolvers

by default a contract.json file will be generate in the same directory where you run this command.

$ jsonql-contract create /path/to/your/resolvers /path/to/your/contracts

This will put the contract.json into /path/to/your/contracts.


If you are create a static version for your js client for distribution

$ jsonql-contract create /path/to/our/resolvers /path/to/your/contract --public=1

This will generate the public version of jsonql contract name public-contract.json.

Using config flag to import a configuation file

You can use a json or js file to specify all the options:

{
  "inDir": "/path/to/resolvers",
  "outDir": "/path/to/contract",
  "enableAuth": true
}

Then you can:

$ jsonql-contract config ./config.json

Supported JS

We only support common js (cjs) style function exports and ES6 import / export style (you need to pass the jsType: ES when you pass configuration options to the contract generator api)

/**
 * This is a query and we REQUIRED to write correct jsdoc since v1.2.x
 * @param {number} param1 
 * @param {number} param2 
 * @param {number} [param3=100] optional with default value of 100
 * @return {number} sum of all
 */
module.exports = function someResolver(param1, params2, param3=100) {
  return param1 + param2 + param3;
}

ES6 style:

/**
 * This is a query and we REQUIRED to write correct jsdoc since v1.2.x
 * @param {number} param1 
 * @param {number} param2 
 * @param {number} [param3=100] optional with default value of 100
 * @return {number} sum of all
 */
export default function someResolver(param1, param2, param3 = 100) {
  return param1 + param2 + param3
}
 

Resolvers folder structure

As of the jqonql-koa alpha.7 release. It will only support the following folder structure

/resolvers/
          /query/name-of-function.js
                /another-function/
                                 /index.js
          /mutation/name-of-update.js
                   /another-name-of-function/
                                            /index.js

Inside the resolver:

 
/**
 * we REQUIRED to write correct jsdoc from v1.2.x
 * @param {string} name 
 * @param {number} pos 
 * @param {object} [options={}] 
 * @return {object} combination
 */
module.exports = async function(name, pos, options = {}) {
  // do your things
  return result;
}

Its recommended to use an async method as your resolver. Inside, you can return promise or use async await.

Because when we execute your code it will look (not exactly the same) the following:

 
  ctx.body = await processResult(opts);
 

For mutation, there will only be 2 parameters payload and condition

/**
 * This is the signature of a mutation function
 * @param {object} payload 
 * @param {object} condition 
 * @return {boolean} true on success
 */
module.exports = function(payload, condition) {
  // do your thing
}

To properly documented your mutation code for the client side validation, you should do the following comment:

/**
 * This is the signature of a mutation function
 * @param {object} payload 
 * @param {string} payload.name key name
 * @param {object} condition 
 * @param {number} condition.id to id the field
 * @return {boolean} true on success
 */
module.exports = function({ name }, { id }) {
  // do something with your data
}
 

Once the contract finish parsing the code, the contract result will look like this:

{
  "mutation": {
    "someFunction": {
      "params": [
        {
          "type": "object",
          "name": "payload",
          "keys": [
            {
              "type": "string",
              "name": "name",
              "parent": "payload"
            }
          ]
        },
        {
          "type": "object",
          "name": "condition",
          "keys": [
            {
              "type": "number",
              "name": "id",
              "parent": "condition"
            }
          ]
        }
      ]
    }
  }
}

The above show you how the client will take the parameter, the children will fold under the keys property. And the client side validation will able to correctly validate your input before send to the server.

Also using jsdoc to id the type of your parameters solve the default value problem, and the client library will able to correctly apply the default value when call.

The result contract

There will be type information for the parameter, they will all set to mixed type by default. We have to wait until the flow interface completed before we can lock down on the type.

Another solution is enforcing writing standard compliant comment, and allow us to understand what's your parameters expected value type. Writing good comment is really a standard practice for any programmer.

1.2.X with jsdoc-api

Since we are not using any type system (if you want to, we have the Typescript port in future) Therefore, if we need to enable the validation feature on the client; you MUST write proper jsdoc. We will take the jsdoc output and create an additional temporary contract file (contract-jsdoc.json) and the base public contract will be the combination of two files. We also allow to create another contract file based on the NODE_ENV so let say, if you are currently under NODE_ENV=development then we will look for a development.json and use the property to overload the base contract file (But this is rarely necessary, and this feature might remove in the future release).

TODOS

  • Update README about the public folder within each resolvers
  • Add watch mode during development - this is not activate until the other part is ready
  • Add accept config file for easier to run in command line
  • add Auth part
  • add Socket part
  • add File part (not in the code base yet)

MIT (c) to1source & NEWBRAN LTD

Install

npm i jsonql-contract

DownloadsWeekly Downloads

63

Version

1.9.2

License

MIT

Unpacked Size

79.2 kB

Total Files

32

Homepage

jsonql.org

Last publish

Collaborators

  • avatar
  • avatar