Giter VIP home page Giter VIP logo

graphql-cli-generate-fragments's Introduction

graphql-cli-generate-fragments npm

Generates GraphQL fragments for each type in the project schema.

Installation

npm i -g graphql-cli graphql-cli-generate-fragments

Usage

graphql generate-fragments

Generate Fragments for Graphql Schemas

Options:
  --dotenv         Path to .env file                                    [string]
  -p, --project    Project name                                         [string]
  --output, -o     Output folder                                        [string]
  --save, -s       Save settings to config file     [boolean] [default: "false"]
"false"]
  --generator, -g  Generate to 'js' or 'graphq'                 [string]
  --verbose        Show verbose output messages     [boolean] [default: "false"]
  -h, --help       Show help                                           [boolean]
  -v, --version    Show version number                                 [boolean]

Graphql Fragments Generation

Creates graphql fragments containing the fields for each type in the supplied schema.

For more information on fragments and their use: (https://www.apollographql.com/docs/react/features/fragments.html)

The first time you use fragment generation in your project, you need to provide an output folder for your fragments, and the generator you want to use:

$ graphql generate-fragments -p database -o src/generated -g graphql --save
✔ Fragments for project database written to src/generated/database.fragments.js

This will also save the configuration in your .graphqlconfig file (see below).

Automating graphql generate-fragments

After you have set up fragment generation for all projects, you can simply run graphql generate-fragments without any parameters to process all projects:

$ graphql generate-fragments
✔ Fragments for project app written to src/generated/app.fragments.graphql
✔ Fragments for project database written to src/generated/database.fragments.js

Fragments Usage and Examples

Generated Fragments

There are three types of fragments outputted by graphql-cli-generate-fragments.

Given the schema:

type User implements Node {
  id: ID!
  email: String!
  password: String!
  posts: [Post!]
}

type Post  {
  id: ID!
  createdAt: DateTime!
  updatedAt: DateTime!
  isPublished: Boolean!
  title: String!
  text: String!
  author: User!
}

The following fragments are generated:

fragment User on User {
  id
  email
  password
  posts {
    ...PostNoNesting
  }
}

fragment Post on Post {
  id
  createdAt
  updatedAt
  isPublished
  title
  text
  author {
    ...UserNoNesting
  }
}

fragment UserNoNesting on User {
  id
  email
  password
}

fragment PostNoNesting on Post {
  id
  createdAt
  updatedAt
  isPublished
  title
  text
}

Notice that we generate _NoNesting fragments, which do not include relations. Post and User would be recursive otherwise. If there is a recursive fragment you will receive a "Cannot spread fragment within itself" error.

Deeply Nested Fragments

When there is no recursive nesting of fragments it can be useful to include all related types queries. _DeepNesting fragments are generated for this use.

Given the following schema:

type User implements Node {
  id: ID!
  email: String!
  password: String!
  details: UserDetails!
}

type UserDetails {
  firstName: String!
  lastName: String!
  address: Address!
}

type Address {
  line1: String!
  line2: String
  county: String
  postcode: String!
}

The following is also generated:

fragment UserDeepNesting on User {
  id
  email
  password
  details {
    ...UserDetails
  }
}

fragment UserDetailsDeepNesting on UserDetails {
  firstName
  lastName
  address {
    ...Address
  }
}

fragment AddressDeepNesting on Address {
  line1
  line2
  county
  postcode
}

Use with Apollo Graphql Tag Loader

By using graphql-tag/loader with Webpack you can import fragments into .graphql files:

#import "../generated/app.fragments.graphql"

query CurrentUser {
  currentUser {
    ...User
  }
}

or into javascript

import { User } from "../generated/app.fragments.graphql"

const query = gql`
    query CurrentUser {
    currentUser {
      ...User
    }
  }

  ${User}

Use with JS

If you are unable to use Webpack - fragments can be generated to javascript models (see below)

import { User } from "../generated/app.fragments.js"

const query = gql`
    query CurrentUser {
    currentUser {
      ...User
    }
  }

  ${User}

Available generators

The following generators are provided:

Generator Purpose
graphql Generates fragments for all types in schema
js Wraps the graphql and exports them for import in javascript

graphql-config extensions

To store the project configuration for fragment generation, graphql-cli-generate-fragments uses two extension keys in the graphql-config configuration file. These keys can be set manually, or using the --save parameter.

# ./.graphqlconfig.yml
projects:
  app:
    schemaPath: src/schema.graphql
    extensions:
      endpoints:
        default: 'http://localhost:4000'
+   generate-fragments:
+     output: src/generated/app.fragments.js
+     generator: js
  database:
    schemaPath: src/generated/prisma.graphql
    extensions:
      prisma: database/prisma.yml
+     generate-fragments:
+       output: src/generated/database.fragments.graphql
+       generator: graphql

License

This project is licensed under the MIT License - see the LICENSE.md file for details

Acknowledgments


graphql-cli-generate-fragments's People

Contributors

develomark avatar paulcpk 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

Watchers

 avatar  avatar  avatar

graphql-cli-generate-fragments's Issues

Syntax Error: Cannot parse the unexpected character "/".

i get this syntax error when using the generate-fragments command:

$ API_URL=foo AUTH_TOKEN=bar graphql generate-fragments -p default -g js -o baz --save
✖ Generating fragments for project default...
Syntax Error: Cannot parse the unexpected character "/".

my .graphqlconfig:

{
  "schemaPath": "schema.json",
  "extensions": {
    "endpoints": {
      "default": {
        "url": "${env:API_URL}",
        "headers": {
          "Authorization": "Bearer ${env:AUTH_TOKEN}"
        }
      }
    }
  }
}

i've successfully saved the schema file (with graphql get-schema) so the url and the token are valid.

from my package.json:

"graphql-cli": "^2.13.0",
"graphql-cli-generate-fragments": "^1.1.0",

Is there a way to make this work with `apollo generate:codegen`?

import {RouteModelFragment} from 'fragments/foo.fragments'

const query = gql`
  query maintenanceRoutes {
    routes {
      ...RouteModelFragment
    }
    zones {
      id
      zoneName
    }
  }
  
  ${RouteModelFragment}
`

$ apollo codegen:generate --schema=schema.graphql --target=flow --outputFlat --queries='foo.js' $OUT_DIR/types

Unknown fragment "RouteModelFragment".

ToolError: Validation of GraphQL query document failed
    at Object.validateQueryDocument (~/nvm/versions/node/v8.9.0/pnpm-global/1/node_modules/.registry.npmjs.org/apollo/1.4.0/node_modules/apollo/lib/validation.js:17:15)
    at Object.generate [as default] (~/nvm/versions/node/v8.9.0/pnpm-global/1/node_modules/.registry.npmjs.org/apollo/1.4.0/node_modules/apollo/lib/generate.js:19:18)
    at Task.task (~/nvm/versions/node/v8.9.0/pnpm-global/1/node_modules/.registry.npmjs.org/apollo/1.4.0/node_modules/apollo/lib/commands/codegen/generate.js:152:60)
    at Promise.resolve.then.then.skipped (~/nvm/versions/node/v8.9.0/pnpm-global/1/node_modules/.registry.npmjs.org/listr/0.14.1/node_modules/listr/lib/task.js:167:30)
    at <anonymous>

I wonder if apollo codegen can reference fragments from its schema so we don't need the import?

This issue means having to choose between templated gql queries or query type generation.

graphql-cli-generate-fragments may still be useful for copy-pasting in the generated fragments instead of having to type them.

And maybe its better to keep gql queries static so IDE integrations can work properly. Although the Apollo docs suggest importing fragments into your queries here: https://www.apollographql.com/docs/react/advanced/fragments.html.

Fragment not generated for array fields

I have a schema that has an array field (notificationEmails in the example below). The generated fragment for this schema is missing the field.

Example schema:

type Note {
  text: String!
}

type Step {
  name: String!
  note: Note
  notificationEmails: [String!]
}

Generated fragment:

fragment Note on Note {
  text
}

fragment Step on Step {
  name
  note {
    ...NoteNoNesting
  }
}

Is there anything I may be doing wrong here?

`generate-fragments` creates empty fragments

Hi there 👋,

running generate-fragments on the following schema:

type User {
  email: String
  id: Int
  name: String
}

type PayloadUser{
  data: User
}

type dataWrapper {
  getUser: PayloadUser
}

type Query {
  dataWrapper: dataWrapper
}

generates the according fragments:

# DO NOT EDIT THIS FILE DIRECTLY

# Standard Fragments
# Nested fragments will spread one layer deep


fragment User on User {
  email
  id
  name
}

fragment PayloadUser on PayloadUser {
  data {
    ...UserNoNesting
  }
}

fragment dataWrapper on dataWrapper {
  getUser {
    ...PayloadUserNoNesting
  }
}


# No Relational objects
# No nested fragments


fragment UserNoNesting on User {
  email
  id
  name
}

fragment PayloadUserNoNesting on PayloadUser {
  
}

fragment dataWrapperNoNesting on dataWrapper {
  
}


# Deeply nested Fragments
# Will include n nested fragments
# If there is a recursive relation you will receive a
# "Cannot spread fragment within itself" error when using


fragment UserDeepNesting on User {
  email
  id
  name
}

fragment PayloadUserDeepNesting on PayloadUser {
  data {
    ...User
  }
}

fragment dataWrapperDeepNesting on dataWrapper {
  getUser {
    ...PayloadUser
  }
}

As you may notice, PayloadUserNoNesting and dataWrapperNoNesting are empty, which throws an error in graphql.

I was able to circumvent this by commenting out a 'return null' case in GenerateFragments.ts, like so https://github.com/plck/graphql-cli-generate-fragments/blob/master/src/GenerateFragments.ts#L391
then the fragments aren't empty anymore.
Ideally the logic should be tweaked a bit, so that dataWrapperNoNesting isn't generated at all, since it's never used. I couldn't wrap my head around this so far though.

Any ideas on how to approach this?

Thanks!

Error: Cannot read property 'name' of null

Hi 👋 ,

when I run graphql generate-fragments -p app with the following configuration:

  "projects": {
    "app": {
      "schemaPath": "schema.graphql",
      "extensions": {
        "endpoints": {
          "default": "http://localhost:3000/graphql"
        },
        "generate-fragments": {
          "output": "generated/graphql.fragments.js",
          "generator": "js"
        }
      }
    }
  }
}

I get an error Cannot read property 'name' of null.

My Schema is really large, for simplicity I tried to recreate the error with a simple example Schema:

# This works
type Post {
  id: ID!
  title: String!
  author: User
}

type Query {
  allPosts: [Post]
}

type User {
  id: ID!
  firstName: String!
  lastName: String!
  posts: [Post]!
}

# This throws an error
type Post {
  id: ID!
  title: String!
  author: User
}

type Query {
  allPosts: [Post]
}

type User {
  id: ID!
  firstName: String!
  lastName: String!
  posts: [Post]
}

The only difference here is the non-nullable array at posts in type User.

This might be related to #2
Any Ideas on how to fix this?

Thanks!

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.