Skip to content

Latest commit

History

History
119 lines (86 loc) 路 3.69 KB

CUSTOM_EXTENSION.md

File metadata and controls

119 lines (86 loc) 路 3.69 KB

Writing your own GraphQL-CLI Extension

graphql-cli allow you to write your own plugin/extenion, and intergrate external tools and configuration, and run it from a single CLI.

The current implementation of graphql-cli is using Yargs to manage it's CLI commands.

Plugins and extension are treated as NodeJS module by the graphql-cli, so it means you can use JavaScript/TypeScript/Any other super-set of JavaScript to write your extension. It means that you plugin will be loaded by it's name under node_modules - for example graphql-cli my-custom-plugin ....

graphql-cli also supports graphql-config, so it can help you easily load your GraphQL schema, operations and configuration from a unified config file.

If you are wrapping an existing tool that has it's own CLI already, consider to expose a programatic API so it will be easier to consume.

TL;DR

We have a ready-to-use boilerplate for that purpose, you can find it here.

Also, inside this repo, under packages/commands you can find a set of plugins implementation you can use as reference.

Getting Started

Start by creating a simple JavaScript/TypeScript project, according to your preference. Install @graphql-cli/common package and use defineCommand utility in your entry point (usually index file):

import { defineCommand } from '@graphql-cli/common';

export default defineCommand((api) => {
  return {};
});

To register your CLI command, give it a name first. Use the command property:

export default defineCommand((api) => {
  return {
    command: 'my-plugin',
    async handler() {
      // code here
    },
  };
});

Now, your plugin will be avaiable to use with the following command: graphql my-plugin.

You can also add custom validations, flags, default values and much more with Yargs. You can read the documentation here.

Testing your plugin locally

To test your plugin locally, install graphql-cli in your project as a devDependency, and run the following command:

graphql ./src/index.js

If you registerd sub-commands, you should be able to run those this way:

graphql ./src/index.js do-something

The path should point to the entry point of your script, and if you are using TypeScript - point to the compile file.

Loading GraphQL Schema

To easily load GraphQL schema, you can use graphql-config:

import { defineCommand } from '@graphql-cli/common';

export default defineCommand((api) => {
  return {
    command: 'my-plugin',
    builder(build) {
      return build.options({
        project: {
          type: 'string',
          describe: 'Name of your project',
        },
      });
    },
    async handler(args) {
      // use graphql-config and find configuration
      const config = await api.useConfig();
      // pick project
      const project = args.project ? config.getProject(args.project) : config.getDefault();
      // get schema
      const schema = await config.getSchema();
    },
  };
});

If you are using graphql-config to define your configuration, and you wish to load your extenion config from it, do:

type MyConfig = { ... };

const extensionConfig = await config.extension<MyConfig>('my-plugin');

Error Handling

If you wish to fail the execution of your plugin and report it back to GraphQL CLI host, simply throw an error:

import { defineCommand } from '@graphql-cli/common';

export default defineCommand(() => {
  return {
    command: 'check-if-missing',
    handler() {
      if (somethingIsMissing) {
        throw new Error(`Ooops, something is missing`);
      }
    },
  };
});