0.0.31 • Published 3 years ago

@magiql/ide v0.0.31

Weekly downloads
1
License
-
Repository
-
Last release
3 years ago

Important: Very early project and under active development, would love any feedback or help

Install

npm install @magiql/ide

// or 
yarn add @magiql/ide

Features

  • Goal: IDE-like experience for GraphQL exploration and development (eg. CodeSandbox for frontend) using monaco-editor
  • Language service: supported using web workers (everything is off the main UI thread) Uses graphql-language-service Based on work on monaco-graphql Syntax highlighting Schema-aware auto-completions Validations and error highlighting Formatting on Cmd + S (using prettier) * Run queries, mutations, and subscriptions (in development)
  • Explorer: point-and-click UI to manipulate the AST with hints from the schema (in development): Completely inspired by OneGraph/graphiql-explorer Goal: represent the entire AST as an explorer with hints from the schema Looks exactly like GraphQL syntax (syntax highlighted), but only the customizable parts should need user input, everything else should be toggles or buttons Would allow very easy exploration of API for non technical users as well, could hide text editor also Implementation: uses codegen to generate a recoil based AST data structure using the types in the graphql package, the Explorer is also just a renderer of the AST, that can update any part of the AST by updating its atom, and a new AST will be build The AST is exported as collection of recoil atoms: can be modified externally by other plugins
  • User interface: Goal: Browser-like UI for exploring GraphQL APIs Edit the URL in the nav bar to connect to any GraphQL API Support for multiple tabs: each has own schema configuration (url, headers), query, variables, etc. Resizable and configurable panels for everything (query, explorer, variables, headers, settings, etc.): extendable to allow plugins to add panels and switch to them * Persists configuration, history, etc to localStorage to get a stateful user experience
  • Embeddable: Exports components that can be used in any React App, Loads monaco-editor and web workers from CDNs to avoid any extra bundling step to include them CSS is added at runtime by beamwind so that its not necessary to bundle css
  • Extendable: IDE state exported as collection of Recoil atoms for plugins to manipulate them and react to them as necessary Plugin API to provide custom panels and functionality, Can run expensive stuff on web workers and use-monaco gives a really easy API to register and use workers that use text files from monaco-editor Ideas for plugins: GraphQL faker: design schema in one panels and explore it in another Hasura: create panel to generate declarative metadata/migrations like tables, etc Response manipulation: Allow user to write custom code in a panel that can be run with the result of the response, (like lodash, etc or persisting) Could create CLI / plugin to read directory and get GraphQL documents and have them available for exploration
  • @magiql/ide/render can be used by GraphQL servers as an alternative to GraphQL playground (usage shown below) * Should be configurable with plugins and initial state of IDE
  • Tech used: react recoil: state management tool beamwind: a collection of packages to compile Tailwind CSS like shorthand syntax into CSS at runtime use-monaco: wrapper around monaco-editor , handles loading from CDN and managing workers, exposes easier APIs to extend the editor

Usage for GraphQL server

import {
  getGraphQLParameters,
  processRequest,
  shouldRenderGraphiQL,
} from "graphql-helix";

import { renderPlayground } from "@magiql/ide/render";

const allowCors = (fn) => async (req, res) => {
  // ... middleware to allow cors for development
  return await fn(req, res);
};

export default allowCors(async (req, res) => {
  const request = {
    body: req.body,
    headers: req.headers,
    method: req.method,
    query: req.query,
  };

  if (shouldRenderGraphiQL(request)) {
    res.send(
      /*
       * returns HTML that you send from a server
       */
      renderPlayground({
        uri: "/api/graphql",
      })
    );
  } else {
    const { operationName, query, variables } = getGraphQLParameters(request);

    const result = await processRequest({
      operationName,
      query,
      variables,
      request,
      schema,
    });

    if (result.type === "RESPONSE") {
      result.headers.forEach(({ name, value }) => res.setHeader(name, value));
      res.status(result.status);
      res.json(result.payload);
    }
  }
});

Usage in React App

import GraphQLIDE from "@magiql/ide";
export default function App() {
  return (
    <GraphQLIDE
      schemaConfig={{
        // whichever GraphQL endpoint you want to connect to,
        // to access Next JS API Routes, we need the full url
        uri: window.location.origin + "/api/graphql",
      }}
    />
  )
}

Usage in server-rendered React App

As the tool is web-based, in case your app is server-rendered, use the following to skip rendering the IDE on the server

import GraphQLIDE from "@magiql/ide";
export default function App() {
  return typeof window !== "undefined" ? (
    <GraphQLIDE
      schemaConfig={{
        uri: window.location.origin + "/api/graphql",
      }}
    />
  ) : (
    <></>
  );
}
0.0.31

3 years ago

0.0.30

3 years ago

0.0.29

3 years ago

0.0.27

3 years ago

0.0.26

3 years ago

0.0.25

3 years ago

0.0.24

3 years ago

0.0.22

3 years ago

0.0.23

3 years ago

0.0.21

3 years ago

0.0.20

3 years ago

0.0.14

3 years ago

0.0.15

3 years ago

0.0.16

3 years ago

0.0.17

3 years ago

0.0.18

3 years ago

0.0.19

3 years ago

0.0.13

3 years ago

0.0.12

3 years ago

0.0.10

3 years ago

0.0.11

3 years ago

0.0.9

3 years ago

0.0.8

3 years ago

0.0.7

3 years ago

0.0.3

3 years ago

0.0.5

3 years ago

0.0.4

3 years ago

0.0.6

3 years ago

0.0.2

3 years ago

0.0.1

3 years ago