Coder Social home page Coder Social logo

piglovesyou / graphql-let Goto Github PK

View Code? Open in Web Editor NEW
452.0 5.0 34.0 5.23 MB

A webpack loader / babel-plugin / babel-plugin-macros / CLI / generated file manager of GraphQL code generator.

License: Apache License 2.0

JavaScript 2.76% TypeScript 97.24%
typescript graphql webpack-loader graphql-codegen babel-plugin jest-transformer babel-plugin-macros

graphql-let's Introduction

graphql-let Node CI npm version downloads Babel Macro Stake to support us

A webpack loader/babel-plugin/babel-plugin-macros/CLI/generated file manager of GraphQL code generator.

Try Create React App example and Next.js example integrating graphql-let. A blog post

🛰 Migration guide to v0.18.0

Table of Contents

Why this exists

One of the strengths of GraphQL is enforcing data types on runtime. Further, TypeScript and GraphQL code generator help it even safer by typing your codebase statically. Both make a truly type-protected development environment with rich IDE assists.

graphql-let enhances that development pattern by minimizing configuration setup, introducing intuitive syntax, and comfortable development experience through HMR (hot module replacement).

import { useNewsQuery } from './news.graphql' // webpack
// or
import { gql, load } from "graphql-let/macro" // babel-plugin-macros
const { useNewsQuery } = gql("query News { braa }")

const News: React.FC = () => {
    // Typed already️⚡️
    const { data: { news } } = useNewsQuery()
    return <div>{news.map(...)}</div>
}

Entrypoints and features

Summary of characteristics of each entrypoint.

  • CLI for efficient code generation before your type checking
  • webpack loader to get HMR even on modifying GraphQL documents
  • babel-plugin-macros for the minimum configuration
  • Babel plugin if you don't want babel-plugin-macros

All of them mostly do the same behind the scene.

  1. Loads your configuration from .graphql-let.yml
  2. Finds GraphQL documents (queries, mutations, subscriptions) from .graphql* and .ts* specified in your config.documents
  3. Processes and passes arguments to GraphQL code generator to generate .ts* s. These are used for runtime.
  4. It also generates the corresponding .d.ts s of the codegen results. These are used for typing checking / IDE code completion.

Note there are a few differences between the entrypoints.

Syntax table for the entrypoints
Entry pointsYou need .graphql-let.yml and: Getting codegen result from Use values of codegen result Use types of codegen result Pros/Cons
webpack loader

Configure "graphql-let/loader"
to files "/.*\.(tsx?|graphql)$/" in webpack.config.(js|ts)
File ✅ Import both value and types from a GraphQL document as a module.
import { useQuery, Query } from "./a.graphql"
HMR works as expected.
Webpack config is required even though your project only uses Babel
String literal ✅ by
import { gql } from "graphql-let" 

const { useQuery } = gql("query A { braa }")
⚠️ You can, but you have to find the internal d.ts.
import { gql } from "graphql-let"
import {Query} from 'graphql-let/__generated__/index-A'

const { useQuery } = gql("query { braa }")
babel-plugin-macros

If you've already setupbabel-plugin-macros,no config needed any more
File ✅ by
import { load } from "graphql-let/macro"

const { useQuery } = load("./a.graphql")
⚠️ You can, but you have to find the internally generated d.ts.
import { load } from "graphql-let/macro"
import {Query} from 'graphql-let/__generated__/index-A'

const { useQuery } = load("./a.graphql")
Easiest to integrate if your project already has babel-plugin-macros. create-react-app is the great fit.Cannot load types from function call.

Modifying *.graphql doesn't emit HMR.
String literal ✅ by
import { gql } from "graphql-let/macro"

const { useQuery } = gql("query A { braa }")
⚠️ You can, but you have to find the internally generated d.ts.
import { gql } from "graphql-let/macro"
import {Query} from 'graphql-let/__generated__/index-A'

const { useQuery } = gql("query { braa }")
babel-plugin

Put "graphql-let/babel"to you .babelrc as a plugin
File ✅ by
import { load } from "graphql-let"

const { useQuery } = load("./a.graphql")
⚠️ You can, but you have to find the internally generated d.ts.
import { load } from "graphql-let"
import {Query} from 'graphql-let/__generated__/index-A'

const { useQuery } = load("./a.graphql")
Mostly equivalent to babel-plugin-macros, but you always need your .babelrc configuration. Possibly, "import "./a.graphql"" could be implemented, but not supported yet.Cannot load types from function call.

Modifying *.graphql doesn't emit HMR.Possibly I can make "--watch" option butlots to do for dependency management to detect file change.
String literal ✅ by
import { gql } from "graphql-let"

const { useQuery } = gql("query A { braa }")
⚠️ You can, but you have to find the internally generated d.ts.
import { gql } from "graphql-let"
import {Query} from 'graphql-let/__generated__/index-A'

const { useQuery } = gql("query { braa }")
Efficiency

There are things to make graphql-let light and stable.

  • Sharing the processes. Generating files is expensive, so it runs less time to run GraphQL code generator and TypeScript API.
  • Caching. Embedding hashes, as your source states, reduces the number of unnecessary processing.
  • Sharing the promises. The webpack compilation in typical SSR applications as Next.js runs targets of "node" and "web" simultaneously. If sources are the same, the compilation should be once.

Getting started with webpack loader

This is an example of TypeScript + React + Apollo Client on webpack. You may want TypeScript Vue Apollo or TypeScript Urql. Please replace the corresponding lines depending on your needs.

1. Install dependencies

Note graphql-let is in devDependencies.

# Prerequisites
yarn add -D typescript graphql

# Install graphql-let with its peer dependencies
yarn add -D graphql-let @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/import-types-preset

# Install GraphQL code generator plugins depending on your needs. These are in `plugins` of your .graphql-let.yml.
yarn add -D @graphql-codegen/typescript-operations @graphql-codegen/typescript-react-apollo

# Other libraries depending on your scenario
yarn add @apollo/client

2. Configure .graphql-let.yml

Run this command to generate a configuration template.

yarn graphql-let init
# This will generate .graphql-let.yml

Next, add graphql-codegen plugins in it. Please note that you have to generate a TypeScript source by the plugins.

Edit it like this:

  schema: lib/type-defs.graphqls
  documents:
    - '**/*.graphql'
    - '**/*.tsx'
  plugins:
+   - typescript-operations
+   - typescript-react-apollo

3. Check your cacheDir

cacheDir will have .ts(x)s that your sources will import. It's node_modules/.cache/graphql-let by default, but you may exclude node_modules for webpack compilation. In that case, we recommend setting up like this.

  schema: lib/type-defs.graphqls
  documents:
    - '**/*.graphql'
    - '**/*.tsx'
  plugins:
    - typescript-operations
    - typescript-react-apollo
+ cacheDir: .cache

Please note that files in cacheDir are only intermediate cache, possibly having wrong import paths. Your tsconfig.json probably complains, so give it a line for exclusion.

  // tsconfig.json
  {
+   "excludes": [".cache"]
  }

Also, remember you have to .gitignore the .cache directory in the next section.

3. Add lines to .gitignore

graphql-let will generate .d.ts files in the same folder of .graphql. Add these lines in your .gitignore.

+ *.graphql.d.ts
+ *.graphqls.d.ts
+ /.cache

4. Configure webpack.config.ts

The webpack loader also needs to be configured. Note that the content that graphql-let/loader generates is JSX-TypeScript. You have to compile it to JavaScript with an additional loader such as babel-loader.

  const config: Configuration = {
    module: {
      rules: [
+       {
+         test: /\.(tsx|graphql)$/,
+         use: [
+           { loader: 'babel-loader', options: { presets: ['@babel/preset-typescript', '@babel/preset-react'] } },
+           { loader: 'graphql-let/loader' },
+         ]
+       }
      ]
    }
  }

5. Generate type declarations

Run this to generate .d.ts.

yarn graphql-let

# This will generate files such as:
#   - src/query.graphql.d.ts
#   - src/schema.graphqls.d.ts

By --config option, you can specify the custom path to the .graphql-let.yml. The directory .graphql-let.yml is located at is the basepath of the relative paths in .grpahql-let.yml. Also, the basepath should be identical to webpack's config.context so the loader can find the config file.

pwd # "/app"
yarn graphql-let --config custom/path/.graphql-let.yml

# This will point paths such as:
# /app/custom/path/src/query.graphql.d.ts
# /app/custom/path/src/schema.graphqls.d.ts

You may want to run it every time before calling tsc. Please check your package.json and modify like this.

   "scripts": {
-     "build": "tsc"
+     "build": "graphql-let && tsc"
   },

6. Run webpack serve and Code

Enjoy HMR (Hot Module Replacement) of webpack with the generated react-apollo hooks and IDE code assists.

import { gql } from 'graphql-let'
import { useNewsQuery } from './news.graphql'

const { useViewerQuery } = gql(`query Viewer { blaa }`)

const News: React.FC = () => {
    // Already typed⚡️
    const { data: { news } } = useNewsQuery()
    const { data: { viewer } } = useViewerQuery()
    return <div>{ news.map(...) }</div>
}

Getting started with babel-plugin-macros

babel-plugin-macros requires the least configuration to setup.

Please finish 1. Install dependencies, and 2. Configure .graphql-let.yml as you still need .graphql-let.yml.

3. Make sure your babel-plugin-macros is ready

Put a line "plugins": ["macros"] to your .babelrc. If you use Create React App, it contains babel-plugin-macros out of the box.

If you want a custom path to .graphql-let.yml, you can use configFilePath babel option. <projectRoot>${configFilePath} should point to your .graphql-let.yml.

4. Code

Thanks to babel-plugin-macros's beautiful architecture, you're ready to use GraphQL codegen values.

import { gql, load } from "graphql-let/macro"

// Typed⚡️
const { useNewsQuery } = gql("query News { braa }")
const { useViewerQuery } = load("./viewer.graphql")

Note that your schema types are generated in graphql-let/__generated__/__types__, instead of per-document outputs.

import { News } from 'graphql-let/__generated__/__types__'

Getting started with Babel Plugin

Mostly the same as babel-plugin-macros, only you need to import "graphql-let".

Please finish 1. Install dependencies and 2. Configure .graphql-let.yml as you still need .graphql-let.yml.

3. Setup .babelrc

  {
+   "plugins": ["graphql-let/babel"]
  }

4. Code

import { gql, load } from "graphql-let"

const { useNewsQuery } = gql("query News { braa }")
const { useViewerQuery } = load("./viewer.graphql")

Difference between .graphql-let.yml and codegen.yml

graphql-let half passes your config options to GraphQL code generator API and half controls them. Here explains how different these and why. You can see this section as a migration guide, too.

  schema: https://api.github.com/graphql
  documents: "**/*.graphql"
- generates:
-     ./__generated__/operations.ts:
-         config:
-             key: value
-         plugins:
-             - typescript
-             - typescript-operations
-         preset: xxx
+ plugins:
+     - typescript-operations
+ config:
+     key: value

Plugin typescript should not be specified

You have to have @graphql-codegen/typescript as a dev dependency. graphql-let generates types by default, where it uses the plugin. The plugins in .graphql-let.yml is for per-document, which imports the shared types automatically. If you specify typescript as a plugin, it's still okay, but you can imagine it's kind of redundant.

No generates

codegen.yml has an option generates, but it's strictly controlled under graphql-let. Rather, think graphql-let as a tool to let you forget intermediate outputs and import/call GraphQL directly.

Therefore, we don't support output-file level configuration such as Output-file level schema, Output-file level documents, and Output Level config right now. But this could be changed logically, so please vote by issuing if you'd like.

No preset

Presets decide how to split/import each other, which graphql-let manages basically. graphql-let generates per-document .d.ts and binds up schema types into a shared file, that's why @graphql-codegen/import-types-preset is our peer dependency.

I think you don't need to configure Presets, because graphql-let takes care of what Presets does on your behalf. If you notice the use-case you need more flexibility, please issue it.

Limitation: documents expects string | string[]

Document-level options such as noRequir or Custom Document Loader are not supported.

graphql-let specific options

In addition to codegen.yml options, graphql-let accepts these.

# "plugins", required. The plugins for GraphQL documents to run GraphQL code
# generator with. You should omit `typescript` plugin which graphql-let generates internally.
# See here for more information. https://graphql-code-generator.com/docs/plugins/index
# Example:
plugins:
    - typescript-operations
    - typescript-react-apollo
    - add: "/* eslint-disable */"

# "respectGitIgnore", optional. `true` by default.
# If true, graphql-let will ignore files in .gitignore.
# Useful to prevent parsing files in such as `node_modules`.
respectGitIgnore: true

# "cacheDir", optional. `node_modules/.cache/graphql-let` by default.
# graphql-let takes care of intermediate `.ts(x)`s that GraphQL code generator
# generates, but we still need to write them on the disk for caching and
# TypeScript API purposes. This is the directory we store them to.
# Examples:
cacheDir: node_modules/.cache/graphql-let
cacheDir: .cache

# "TSConfigFile", optional. `tsconfig.json` by default.
# You can specify a custom config for generating `.d.ts`s.
# Examples:
TSConfigFile: tsconfig.json
TSConfigFile: tsconfig.compile.json

# "typeInjectEntrypoint", optional.
# `node_modules/@types/graphql-let/index.d.ts` by default. Needs to end with ".d.ts".
# Used as an entrypoint and directory of generated type declarations
# for `gql()` and `load()` calls.
typeInjectEntrypoint: node_modules/@types/graphql-let/index.d.ts

# "silent", optional. `false` by default.
# Pass `true` if you want to suppress all standard output from graphql-let.
silent: false

Simple example:

schema: "schema/**/*.graphqls"
documents:
    - "**/*.graphql"
    - "!shouldBeIgnored1"
plugins:
    - typescript-operations
    - typescript-react-apollo

Example with a bit more complicated options:

schema:
    - https://api.github.com/graphql:
          headers:
              Authorization: YOUR-TOKEN-HERE
documents:
    - "**/*.graphql"
    - "!shouldBeIgnored1"
plugins:
    - typescript-operations
    - typescript-react-apollo
respectGitIgnore: true
config:
    reactApolloVersion: 3
    apolloReactComponentsImportFrom: "@apollo/client/react/components"
    useIndexSignature: true
cacheDir: .cache
TSConfigFile: tsconfig.compile.json
typeInjectEntrypoint: typings/graphql-let.d.ts

Limitations of graphql-let/babel

Jest Transformer

graphql-let/jestTransformer is available. Configure your jest.config.js as:

  module.exports = {
    transform: {
+     "\\.graphql$": "graphql-let/jestTransformer",
    },
  };

Use babel-jest in Jest

babel-jest is the default subsequent transformer of graphql-let/jestTransformer. Install these:

yarn add -D graphql-let babel-jest

And make sure your babel config can compile generated .ts(x)s.

Use ts-jest or other subsequent transformers in Jest

The option subsequentTransformer is available. If you use ts-jest, your jest.config.js will look like this:

  const { defaults: tsjPreset } = require("ts-jest/presets");

  module.exports = {
    preset: "ts-jest",
    transform: {
      ...tsjPreset.transform,
+     "\\.graphql$": [
+       "graphql-let/jestTransformer",
+       { subsequentTransformer: "ts-jest" },
+     ],
    },
  };

Transform .graphqls in Jest

If you use graphql-let/schema/loader, you may want a corresponding transformer, but remember graphql-let does not transform the content of GraphQL schema. Just use what you need; it's most likely to be jest-transform-graphql.

  module.exports = {
    transform: {
      "\\.graphql$": "graphql-let/jestTransformer",
+     "\\.graphqls$": "jest-transform-graphql",
    },
  };

Experimental feature: Resolver Types

If you meet the following conditions, graphql-let generates Resolver Types.

Run:

yarn add -D @graphql-codegen/typescript-resolvers
yarn graphql-let

Then you will get resolver types in graphql-let/__generated__/__types__.

import { Resolvers } from "graphql-let/__generated__/__types__";

const resolvers: Resolvers = {
  Query: {
    // All typed⚡️
    viewer(parent, args, context, info) {
      return { ... }
    },
  }
};

export default resolvers;

graphql-let/schema/loader is also available to update resolver types. It doesn't transpile anything; just detects file modification and passes the content to the next loader.

  // webpack.config.ts
  const config: Configuration = {
    module: {
      rules: [
+       {
+         test: /\.graphqls$/,
+         use: [
+           { loader: 'graphql-let/schema/loader' },
+         ]
+       }
      ]
    }
  }

FAQ

So, it's just a graphql-codegen wrapper generating d.ts...?

Yes.

Supported combination of tools? / Tools x + y don't work!

The above documentation should work basically, but some of the combinations may require more effort. Please vote by creating issues. Sponsoring me is another way to get my attention🍩🍦👀

These are the states/tools for the syntaxes.

states/tools for syntax import GraphQL document as
import './a.graphql';
Inline GraphQL document as
import {gql} from 'graphql-let';
gql(`query {}` );
generating .d.tss by command graphql-let
importing GraphQL content from another as
# import A from './a.graphql'
webpack loader graphql-let/loader
Babel Plugin graphql-let/babel
Jest Transformer graphql-let/jestTransfomer Vote by issuing
Experimental: Resolver Types for
GraphQL schema
✅ by
import {Resolvers}
from 'graphql-let/__generated__/__types__'
(I think we don't need this)

Is this a tool only for React?

No. There are more plugins that also generates .ts(x)s from GraphQL documents.

Can I use Tagged Template as gql`query News { baa }`;?

Sadly, you need gql() instead of gql` ` because of the limitation of TypeScript.

What's the extensions .graphql and .graphqls? Can I use .gql or something else?

You can use what you want. I wanted to recommend distinguishing GraphQL schema and GraphQL documents in the extensions, which will lead to a more understandable configuration for webpack loaders with fewer pitfalls. Another reason for .graphqls is that it's one of the supported extensions in the internal library.

How to integrate Apollo refetchQueries?

Query document exports DocumentNode named ${QueryName}Document that you can make use of.

How to import .graphql from another document, especially GraphQL Fragment?

Thanks to graphql-tools/import, the syntax # import X from './fragment.graphql' is supported.

Define your fragment named as partial.graphql

fragment Partial on User {
    id
    name
}

and import it.

# import Partial from './partial.graphql'
query Viewer {
    viewer {
        ...Partial
    }
}

.tsxes generated in cacheDir (.cache) throw TypeScript errors of wrong import paths

It's not a bug. Please exclude cacheDir from your TypeScript compilation. The files in cacheDir are only intermediates, which will speed your next execution.

Your GraphQL documents -> (call GraphQL code generator API *1) -> .tsx *2 -> (call TypeScript to distribute declarations *3) -> .d.ts

You're seeing the *2. It's used to skip *1 and *3, and recodnized as generated implementations, which graphql-let/loader returns, for example.

Contribution

  • Create an issue if you have ideas, find a bug, or anything.
  • Creating a PR is always welcome!
    • Running npm run prepublishOnly locally will get your local development ready.
    • Adding tests is preferable, but not necessary. Maybe someone else will fill it.
  • We have a chronic accumulation of dependabot PRs. Please help us fix these version conflicts by cloning the dependabot branches.

License

Apache License Version 2.0

graphql-let's People

Contributors

andrenanninga avatar cbmd avatar comp615 avatar deanslamajr avatar dependabot-preview[bot] avatar dependabot[bot] avatar eschaefer avatar gsimone avatar hasparus avatar irrelevelephant avatar johnrackles avatar kube avatar piglovesyou avatar rajington avatar renovate-bot avatar renovate[bot] avatar sachinraja avatar salzhrani avatar samio avatar ssypi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

graphql-let's Issues

Duplicate named .graphql files intermittently don't generate

Hey, thanks for this project!

I'm just starting to integrate this into my project, and I've found that my previous naming convention doesn't work properly when rerunning generation.

I split my queries and mutations into different folders, but it seems that doing this causes only the types for 1 or the other to be generated, and it seems the behaviour is intermittent.

./mutations/Device.graphql and ./queries/Device.graphql only generates a single Device.graphql{hash}.d.ts file some of the time.

Is this something you know about? I was expecting the hash to stop this from happening and to write both files and let typescript do the merging.

Cryptic error when contextType not found

Example config:

# Breaks the build
config:
  contextType: './file-which-does-not-exist'

# Other default stuff.. doesn't matter.
generateDir: __generated__
schema: '**/*.graphqls'
documents: '**/*.graphql'
plugins:
  - typescript
  - typescript-operations
  - typescript-react-apollo
respectGitIgnore: true

Observed error:

TypeScript API was not expected as graphql-let developer, it needs to be fixed

Expected behaviour:
Not sure, something a bit more descriptive of the underlying problem... It took me a while to debug this.

Cannot read property 'definitions' of undefined

When trying to use my schema definitions of a remote server getting this error

[ graphql-let ] Cannot read property 'definitions' of undefined

I believe this is from graphql-code-generator as I used this separately and was getting the same issue but upgraded to version 1.13.2 and this seems to have solved it for me in graphql-code-generator.

It seems graphql-let is still using ^1.12.2 which seems to have the problem.

dotansimha/graphql-code-generator#3445

Consequences of turning on skipLibCheck?

It seems that quite significant performance improvements can be had by turning on the skipLibCheck option here:

skipLibCheck: false,

In our case, a clean run of "yarn graphql-let" improved from 25 seconds to 10 seconds.

In your opinion, what would the consequences of this be in practice?

Support writing configuration as webpack Loader option

From #78 (comment)

Ideally it should also be available as a Webpack Loader option.

The problem is the command-line execution, but maybe we can get it from webpack.config.ts. Reasonable spec would be:

  • Load config by the following priority:
    1. .graphql-let.yml
      • CWD is where the .graphql-let.yml is located
    2. webpack Loader option
      • If the paths are absolute, it respects as is
      • If the paths are relative, it recognizes config.context as CWD

Disable generating of Resolver Types

I don't need to generate resolver types, but everytime graphql-let runs I get ons of messages like this in my logs:

[ graphql-let ] Failed to generate Resolver Types. You have to specify at least one schema (glob) path WITH an extension, such as "**/*.graphqls

Per the documentation, this happens when you have @graphql-codegen/typescript-resolvers installed but this seems to be installed with graphql-let and I wasn't able to uninstall it. Is there another way to disable the Generation of resolver types?

My config:

schema: 'http://***.com/graphql'
documents:
  - 'src/**/*.graphql'
plugins:
  - typescript
  - typescript-operations
  - typescript-react-apollo
config:
  reactApolloVersion: 3
  withComponent: false
TSConfigFile: ./tsconfig.graphql-let.json
respectGitIgnore: true
cacheDir: __generated__

Thanks!

Fail to generated .d.ts when I add a Mutation

Hello,

I am starting with NextJs and use this Repository with-typescript-graphql as my basis.

Everything works fine and I can start my dev-server and create a build by running: graphql-let && next.

If I add a mutation like this…

mutation login($username: String!, $password: String!) {
  login(username: $username, password: $password) {
    token
    user {
      id
      username
      email
    }
  }
}

and try to use the created Hook useLoginMutation inside my login page, the dev-server runs fine again. But a graphql-let && next build && next start throws this error:

$ graphql-let
[ graphql-let ] .d.ts were generated in __generated__/types.
Creating an optimized production build  

Compiled successfully.

Automatically optimizing pages ...
Error occurred prerendering page "/login". Read more: https://err.sh/next.js/prerender-error:
Invariant Violation: Invariant Violation: 2 (see https://github.com/apollographql/invariant-packages)

> Build error occurred

What's going wrong? How can I see more details? Is there a verbose-mode? Can the error be in my mutation or in the code-part using the Hook

It would be super nice if everyone can support me and/or give me some tips 🙏

typescript compiler custom config

Hello,
I am facing an issue where my schema has a subscription and the generated tsx has AsyncIterator type.
for typescript to generate the declarations it requires the that the compiler lib option to be set to a target that can handle AsyncIterator like esnext.
Currently there is no API to override the compiler options here.
in my case if graphql-let used my tsconfig.json, the files would have been properly generated.

Migrating to Apollo Client 3.0 issue

Good day!

According to the migration guide of apollo-client, react hooks were taken from a separate package to the client itself. So, it causes module_not_found issues.

./node_modules/@apollo/react-components/node_modules/@apollo/react-hooks/lib/react-hooks.esm.js
Module not found: Can't resolve 'apollo-client' in '/------/node_modules/@apollo/react-components/node_modules/@apollo/react-hooks/lib'

Looks like the generator generates code which requires @apollo/react-hooks package, and this package itself requires apollo-client, which also changes name in version 3 to @apollo/client

Test Next.js with-typescript-graphql examle

yarn create next-app --example with-typescript-graphql with-typescript-graphql-app is the primary path that users install graphql-let. To avoid regressions, effecting to Next.js example, we should test it.

Expose graphql-let/schema/loader

Now graphql-let command generates @graphql-codegen/typescript-resolvers results, but there's no loaders.

  • Add all *.graphqls to the webpack loader deps, so users will get HMR on any .graphqls change.

Accept object as "schema" configuration

graphQL codegen supports setting custom headers for schema introspection using an object as the "schema" attribute, e.g.:

schema:
  - http://localhost:3000/graphql:
      headers:
        Authorization: YOUR-TOKEN-HERE

Can't get resolver-types to work

First issue is that the types aren't "linked" to the GraphQL-Schema file as expected (i.e. no declare module '*/schema.graphqls').

The second issue is that there seems to be a mismatch between what's generated in the __concatedschema__.tsx and what Apollo expects for makeExecutableSchema:

Type 'undefined' is not assignable to type '(() => any) | GraphQLScalarType | IEnumResolver | IResolverObject<any, GraphQLResolveInfo, any> | IResolverOptions<...>'. Interfaces.d.ts(86, 5):
The expected type comes from property 'resolvers' which is declared here on type 'IExecutableSchemaDefinition'

URL Schema with Headers

Currently the validator gives an error that the schema must be a string when you pass it a URL with headers.

The graphql-codegen schema docs support this format:

schema:
  - http://localhost:3000/graphql:
      headers:
        Authorization: YOUR-TOKEN-HERE

It'd be great to have support for this in graphq-let as well 🙌

Duplication in generated types

When using multiple operations it seems like all operation types are generated for each of them (the only difference between the generated files is the declare module '*/DocumentName.graphql' part). I think each file should only contain the matching types.

Export "graphql-let/jestTransformer"

To let users have a graphql-let transformer in jest.config.json, configured as:

module.exports = {
  transform: {
    '\\.(graphql|graphqls)$': 'graphql-let/jestTransformer',
  },
},

and let them run Jest tests with @apollo/client/testing as:

import { MockedProvider } from "@apollo/client/testing";
import {readFileSync} from 'fs';
import renderer from 'react-test-renderer';

const mocks = [
  {
    request: {
      query: readFileSync('../lib/viewer.graphql', 'utf-8'),
      variables: { first: 4 }
    },
    result: {
      data: {
        dog: {
          name: "Douglas"
        }
      }
    }
  },
]

it("runs the mocked query", () => {
  const tree = renderer.create(
    <MockedProvider mocks={mocks}>
      <MyQueryComponent />
    </MockedProvider>
  ).toJSON()

  expect(tree).toMatchSnapshot();
});

Implementation: Jest transformer must be synchronous. We have to ask users to run graphql-let command beforehand and read the generated .tsx synchronously when the transformer is called. The way to integrate Babel is what I need to learn.

Allow multiple schema files

Currently the when using Resolver Types it will only work when using a single schema file. It would be nice if it worked with the array and/or glob syntax like graphql-codegen does.

Get schema definition by introspecting a graphql API

I had been using graphql code-gen with the following codegen.yml

generates:
  ./vendure-types.ts:
    schema: https://demo.vendure.io/shop-api
    documents: 'src/components/ShoppingCart/ShoppingCart.vendure.ts'
    pluckConfig:
      modules:
        - name: apollo-boost
          identifier: gql
    plugins:
      - add: '// tslint:disable'
      - typescript
      - typescript-operations

Is this supported?

HMR test is unstable

It occasionally fails. It passes by rerunning it in most cases. Perhaps I should put another timeout or retry on it.
Screen Shot 2020-03-15 at 18 28 10

next.js example hot reloading bug

I love this loader! Great work!!

Unfortunately, I believe I've found a bug in the next.js example. The bug is that the new types that are generated by graphql-let as part of the next-js hot reload action seem to be ignored by the typechecker.

Reproduction steps

  1. npm run dev
  2. Make a change to the schema (e.g. Add a field isActive: Boolean to the User type in the schema). Save the file.
  3. Add this new field to the Viewer query. Save the file.
  4. Add a reference to this new field after the query hook on the index view. Save the file.
    e.g.:
import withApollo from '../lib/with-apollo'
import Link from 'next/link'
import { useViewerQuery } from '../lib/viewer.graphql'

const Index = () => {
  const { data } = useViewerQuery()

  if (data && data.viewer && data.viewer.isActive) {
    const { viewer } = data
    return (
      <div>
        You're signed in as {viewer.name} and you're {viewer.status} goto{' '}
        <Link href="/about">
          <a>static</a>
        </Link>{' '}
        page.
      </div>
    )
  }

  return <div>...</div>
}

export default withApollo(Index)
  1. In a browser, navigate to localhost:3000

Actual Behavior

New types are ignored: type error reported according to the types initially generated at app start:
graphql-let-bug
Killing the next.js process and starting it again seems to provide the correct types until another change to the schema occurs i.e. it seems that this bug only occurs during the next.js hot reload action.

Expected Behavior

During the next.js hot reload action, graphql-let properly replaces the generated types with the latest and this is reflected properly by the typechecker.

Error: Network error: Expected undefined to be a GraphQL schema.

Hi There,

maybe somebody can help me out im starting from the next example referenced within the readme.
However I'm stucking with the error stated in the topic. I can nail it down to the following code lines:

  await apolloClient.query({
    query: AllTechsDocument,
  });

within the getStaticProps into an Page Component. I don't know why it erros because when i comment it out the const { data } = useAllTechsQuery(); hooks works fine. But since i comment it out it destroys my SSG and moves to CS.

Here is the whole component code

import Body from '../Components/layout/Body';
import { useMutation, useQuery } from '@apollo/react-hooks';
import { initializeApollo } from '../apollo/useApollo';
import { CREATE_USER } from '../apollo/localDocuments';
import {
  GET_CURRENT_USER,
  GET_CURRENT_USER_RESOLVER,
} from '../apollo/localDocuments';
import About from '../Components/About/About.component';
import Tech from '../Components/Tech/Tech.component';
import {
  useAllDataQuery,
  AllDataDocument,
  useAllTechsQuery,
  AllTechsDocument,
} from '../lib/apolloServerDocs/documents.graphql';

const IndexPage = () => {
  let { data } = useAllTechsQuery();
  return (
    <Body>
      <>
        <div>This is the Index page</div>
        <About />
        <Tech />
      </>
    </Body>
  );
};

export async function getStaticProps() {
  const apolloClient = initializeApollo();

  await apolloClient.query({
    query: AllTechsDocument,
  });

  return {
    props: {
      initialApolloState: apolloClient.cache.extract(),
    },
  };
}

export default IndexPage;

Create hashes for caching against stripped GraphQL contents

AS-IS
Caching hashes are created against the raw GraphQL contents. So if users add spaces and save the file, the hash will change and graphql-let starts re-compiling even though the actual content remains.

TO-BE
Do createHash(schemaHash + stripIgnoredCharacters(content)); it may be able to decrease number of compilation.

Support for graphql string literal

I want to be able to use the use gql tag template literal with fragment embedding as I find that format to be easier to read and write. I am not sure how separate .graphql files are technically different to string literal format. Is it that it adds a package to parse the query to AST at runtime? If that is true then can we integrate a static compiler that does that for me during build-time?
https://github.com/firede/ts-transform-graphql-tag

Better error handling for invalid schemas

Not sure if this is an issue with graphql-let or @graphql-codegen, but if you have an error with your schema, the only error message is [ graphql-let ] Failed to load schema. Is there a way a more detailed error that could be exposed? (eg line number of the error)

Output directory?

Is there a config option available to specify an output directory of all .graphql.d.ts files?

  • Would make clearing out these generated files easier for clean scripts and before a new run
  • old generated files currently remain after a graphql file is renamed between runs

Support Typed Document Node

Would be nice if this could support graphql-typed-document-node

I've added the issue to both projects since at this point I don't know which library should be the one to handle this.

Generates the following error:

Plugin "typed-document-node" validation failed:


 Found 1 error

  ✖  <redacted>/node_modules/graphql-let/__generated__/src/renderer/auth/graphql/documents.graphql.tsx
    Plugin "typed-document-node" requires extension to be ".ts"!
    Error: Plugin "typed-document-node" validation failed:
        at executePlugin (<redacted>/node_modules/@graphql-codegen/core/index.cjs.js:31:19)
    Error: Plugin "typed-document-node" validation failed:
        at executePlugin (<redacted>/node_modules/@graphql-codegen/core/index.cjs.js:31:19)

API design of Resolver Types feature is problematic/misleading

When using the Resolver Types feature it is adding the output to all files including the document types. One of the features of Resolver Types is the ability to use relative paths to external types. As documents can be anywhere within the project (most likely near the component) these relative paths break.

As the Resolver Types are only used on the server, I believe they should only be included in the schema types file.

A workaround is to set a baseUrl in your tsconfig and use paths relative to it

Cannot read property 'definitions' of undefined.

Hi, in this new release (v0.6.2), the CLI fails with below error.

carbon

I tried cleaning up the workspace (rm -rf node_modules yarn.lock generated .next) and also to revert back to v0.5.2. I'm not sure about this error but I suspect it might be from @graphql-codegen/typescript-operations but it's just an assumption.

Local state?

Hey,

it's less of an issue rather than a question and i really enjoyed to use graphql-let in one of my projects.

But how is it possible to use the abilitie of handling the local state with apollo? I mean it's not possible anymore to write gql`` with @client directive? Am I missing something or does the use of graphql-let disable apollo`s local state handling?

(not a big issue but would love to learn if it's possible to still rely on it).

Thanks (:

Example with fragments

I tried for a while to get fragment to work and failed. Are they supported? If so, can you extend your reference application to demonstrate?

feat: Output resolver types by @graphql-codegen/typescript-resolvers

Why

Some users implement GraphQL servers in Node runtime by themselves and some users don't. For those who write resolvers will want resolver types, otherwise, they'll type signatures of resolver functions by themselves.

Mercifully there's a plugin.

import { QueryResolvers } from './resolvers-types';

export const resolvers: QueryResolvers = {
  myQuery: (root, args, context) => {},
};

How

According to the value of schema in .graphql-let.yml, graphql-let will generate schema types by default. But I'm not sure the way fits all developer use-cases. For a while, I'll publish it as an experimental feature.

  • On graphql-let Command #51
  • On webpack Loader

Failed to generate .d.ts.Error: Failed to generate .d.ts.

Something in the new reslease broke the generation of .d.ts.

I'm getting the error

yarn run v1.22.4
$ graphql-let
[ graphql-let ] Generating .d.ts...
[ graphql-let ] Failed to generate .d.ts.Error: Failed to generate .d.ts.
    at Object.genDts (C:\Users\USER_NAME\client\node_modules\graphql-let\dist\lib\dts.js:71:15)
    at processDtsForCodegenContext (C:\Users\USER_NAME\client\node_modules\graphql-let\dist\lib\full-generate.js:97:31)
    at Object.fullGenerate [as default] (C:\Users\USER_NAME\client\node_modules\graphql-let\dist\lib\full-generate.js:112:15)
    at async gen (C:\Users\USER_NAME\client\node_modules\graphql-let\dist\gen.js:26:28)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] dev: `yarn codegen && next`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] dev script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\matthiass\AppData\Roaming\npm-cache\_logs\2020-07-10T16_41_33_559Z-debug.log

I just did a clean

yarn create next-app --example with-typescript-graphql with-typescript-graphql-app
yarn
yarn dev

Here is my package.json

{
  "name": "with-typescript-graphql",
  "version": "0.1.0",
  "author": "",
  "license": "ISC",
  "scripts": {
    "codegen": "graphql-let",
    "dev": "yarn codegen && next",
    "build": "yarn codegen && next build",
    "start": "next start"
  },
  "dependencies": {
    "@apollo/react-common": "3.1.4",
    "@apollo/react-components": "^3.1.5",
    "@apollo/react-hooks": "3.1.5",
    "apollo-cache": "^1.3.5",
    "apollo-cache-inmemory": "^1.6.6",
    "apollo-client": "^2.6.10",
    "apollo-link": "1.2.14",
    "apollo-link-http": "1.5.17",
    "apollo-link-schema": "1.2.5",
    "apollo-server-micro": "^2.14.2",
    "apollo-utilities": "^1.3.3",
    "graphql": "^14.6.0",
    "graphql-tag": "^2.10.3",
    "next": "latest",
    "react": "^16.13.1",
    "react-dom": "^16.13.1"
  },
  "devDependencies": {
    "@graphql-codegen/cli": "^1.15.1",
    "@graphql-codegen/plugin-helpers": "^1.15.1",
    "@graphql-codegen/typescript": "^1.13.3",
    "@graphql-codegen/typescript-operations": "^1.13.3",
    "@graphql-codegen/typescript-react-apollo": "^1.13.3",
    "@graphql-codegen/typescript-resolvers": "^1.15.1",
    "@types/react": "^16.9.34",
    "@types/react-dom": "^16.9.7",
    "graphql-let": "0.x",
    "typescript": "^3.8.3"
  }
}

On a windows machine with npm@latest

Reverting to graphql-let: "0.10.0" fixed the issue

Can't install the package

Getting the following error, not sure why this is happening

Now using node v12.14.1 (npm v6.13.4)
➜  npm i --save graphql-let
npm ERR! Unexpected end of JSON input while parsing near '...MCPYrqEdsEE4APu0U9D5q'

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/xxx/.npm/_logs/2020-01-19T12_53_04_317Z-debug.log

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.