aerogear / create-graphql

Command-line utility to build production-ready servers with GraphQL.
MIT License
440 stars 38 forks source link

Refactor to support plugin like babel #59

Open sibelius opened 7 years ago

sibelius commented 7 years ago

Babel plugin object example:

type PluginObject = {
  pre?: Function;
  post?: Function;
  manipulateOptions?: Function;

  visitor: ?{
    [key: string]: Function | {
      enter?: Function | Array<Function>;
      exit?: Function | Array<Function>;
    }
  };
};

each babel plugin returns an object like this.

we should think in CreateGraphQL PluginObject as well.


sibelius commented 7 years ago

First draft of Plugins

Read Database Schema Plugins

Motivation

A read schema plugin should read a schema (collection/table definition) and return an object describing it.

Examples

Templates Plugins

Motivation

CreateGraphql should output a different file for a different option provided, for instance: output a raw mutation or a relay mutation

Examples

we need to define inputs and outputs of these plugins

lucasbento commented 7 years ago

I can imagine it to handle schema from multiple types of databases but how would that be for different templates?

lucasbento commented 7 years ago

Also, how do you plan on starting, should #43 wait for it?

Turning the mongoose schema reading into a plugin should be really straightforward.

We should also have a plugins property on .graphqlrc.

sibelius commented 7 years ago

A template plugin could have an option parameter, like -t for template

lucasbento commented 7 years ago

A template plugin could have an option parameter, like -t for template

@sibelius: what do you mean?

I meant, how will we implement a template plugin? Will we prepare all the variables, pass it to the plugin and it will return the files?

sibelius commented 7 years ago

Yep, I think so, we need to define the inputs and outputs of each plugin

lucasbento commented 7 years ago

So, I started working on this, I thought the following as a blueprint for a create-graphql-plugin:

export default {
  pre: (arguments) => {
    const {
      config, // The content of `.graphqlrc`, will be the default if it doesn't exist
    } = arguments;

    console.log('this is a pre hook function');

    return {
      fields, // The fields generated on the plugin
      files, // Array of objects, e.g.: [{ name: 'ExampleAddMutation.js', content: 'Content of file }]
    };
  },
  post: (arguments) => {
    const {
      config, // The content of `.graphqlrc`, will be the default if it doesn't exist,
      fields, // The fields of the schema
    } = arguments;

    console.log('this is a post hook function');

    return {}; // What would this return?
  },
};

Would love your opinions on this, @sibelius & @felippepuhle.

Also, the plugins would be installed as a devDependency and specified on .graphqlrc under plugins, e.g.:

{
  "directories": {
    ...
    "connection": "connection",
    "loader": "loader",
    "model": "model",
    ...
  },
  "plugins": [
    "create-graphql-plugin-mongoose",
    "create-graphql-plugin-sequelize",
    ...
  ]
}

The generator would then call each plugin based on the order defined, so it would call the mongoose one and then sequelize with the results brought from mongoose.

Still have to figure out how we will deal with files.

lucasbento commented 7 years ago

Good content on Babel plugins: https://github.com/thejameskyle/babel-handbook/blob/master/translations/en/plugin-handbook.md

lucasbento commented 7 years ago

https://github.com/thejameskyle/babel-file