Code Monkey home page Code Monkey logo

swapi-graphql's Introduction

GraphQL

GraphQL Logo

The GraphQL specification is edited in the markdown files found in /spec the latest release of which is published at https://graphql.github.io/graphql-spec/.

The latest draft specification can be found at https://graphql.github.io/graphql-spec/draft/ which tracks the latest commit to the main branch in this repository.

Previous releases of the GraphQL specification can be found at permalinks that match their release tag. For example, https://graphql.github.io/graphql-spec/October2016/. If you are linking directly to the GraphQL specification, it's best to link to a tagged permalink for the particular referenced version.

Overview

This is a Working Draft of the Specification for GraphQL, a query language for APIs created by Facebook.

The target audience for this specification is not the client developer, but those who have, or are actively interested in, building their own GraphQL implementations and tools.

In order to be broadly adopted, GraphQL will have to target a wide variety of backend environments, frameworks, and languages, which will necessitate a collaborative effort across projects and organizations. This specification serves as a point of coordination for this effort.

Looking for help? Find resources from the community.

Getting Started

GraphQL consists of a type system, query language and execution semantics, static validation, and type introspection, each outlined below. To guide you through each of these components, we've written an example designed to illustrate the various pieces of GraphQL.

This example is not comprehensive, but it is designed to quickly introduce the core concepts of GraphQL, to provide some context before diving into the more detailed specification or the GraphQL.js reference implementation.

The premise of the example is that we want to use GraphQL to query for information about characters and locations in the original Star Wars trilogy.

Type System

At the heart of any GraphQL implementation is a description of what types of objects it can return, described in a GraphQL type system and returned in the GraphQL Schema.

For our Star Wars example, the starWarsSchema.ts file in GraphQL.js defines this type system.

The most basic type in the system will be Human, representing characters like Luke, Leia, and Han. All humans in our type system will have a name, so we define the Human type to have a field called "name". This returns a String, and we know that it is not null (since all Humans have a name), so we will define the "name" field to be a non-nullable String. Using a shorthand notation that we will use throughout the spec and documentation, we would describe the human type as:

type Human {
  name: String
}

This shorthand is convenient for describing the basic shape of a type system; the JavaScript implementation is more full-featured, and allows types and fields to be documented. It also sets up the mapping between the type system and the underlying data; for a test case in GraphQL.js, the underlying data is a set of JavaScript objects, but in most cases the backing data will be accessed through some service, and this type system layer will be responsible for mapping from types and fields to that service.

A common pattern in many APIs, and indeed in GraphQL is to give objects an ID that can be used to refetch the object. So let's add that to our Human type. We'll also add a string for their home planet.

type Human {
  id: String
  name: String
  homePlanet: String
}

Since we're talking about the Star Wars trilogy, it would be useful to describe the episodes in which each character appears. To do so, we'll first define an enum, which lists the three episodes in the trilogy:

enum Episode {
  NEWHOPE
  EMPIRE
  JEDI
}

Now we want to add a field to Human describing what episodes they were in. This will return a list of Episodes:

type Human {
  id: String
  name: String
  appearsIn: [Episode]
  homePlanet: String
}

Now, let's introduce another type, Droid:

type Droid {
  id: String
  name: String
  appearsIn: [Episode]
  primaryFunction: String
}

Now we have two types! Let's add a way of going between them: humans and droids both have friends. But humans can be friends with both humans and droids. How do we refer to either a human or a droid?

If we look, we note that there's common functionality between humans and droids; they both have IDs, names, and episodes in which they appear. So we'll add an interface, Character, and make both Human and Droid implement it. Once we have that, we can add the friends field, that returns a list of Characters.

Our type system so far is:

enum Episode {
  NEWHOPE
  EMPIRE
  JEDI
}

interface Character {
  id: String
  name: String
  friends: [Character]
  appearsIn: [Episode]
}

type Human implements Character {
  id: String
  name: String
  friends: [Character]
  appearsIn: [Episode]
  homePlanet: String
}

type Droid implements Character {
  id: String
  name: String
  friends: [Character]
  appearsIn: [Episode]
  primaryFunction: String
}

One question we might ask, though, is whether any of those fields can return null. By default, null is a permitted value for any type in GraphQL, since fetching data to fulfill a GraphQL query often requires talking to different services that may or may not be available. However, if the type system can guarantee that a type is never null, then we can mark it as Non Null in the type system. We indicate that in our shorthand by adding an "!" after the type. We can update our type system to note that the id is never null.

Note that while in our current implementation, we can guarantee that more fields are non-null (since our current implementation has hard-coded data), we didn't mark them as non-null. One can imagine we would eventually replace our hardcoded data with a backend service, which might not be perfectly reliable; by leaving these fields as nullable, we allow ourselves the flexibility to eventually return null to indicate a backend error, while also telling the client that the error occurred.

enum Episode {
  NEWHOPE
  EMPIRE
  JEDI
}

interface Character {
  id: String!
  name: String
  friends: [Character]
  appearsIn: [Episode]
}

type Human implements Character {
  id: String!
  name: String
  friends: [Character]
  appearsIn: [Episode]
  homePlanet: String
}

type Droid implements Character {
  id: String!
  name: String
  friends: [Character]
  appearsIn: [Episode]
  primaryFunction: String
}

We're missing one last piece: an entry point into the type system.

When we define a schema, we define an object type that is the basis for all query operations. The name of this type is Query by convention, and it describes our public, top-level API. Our Query type for this example will look like this:

type Query {
  hero(episode: Episode): Character
  human(id: String!): Human
  droid(id: String!): Droid
}

In this example, there are three top-level operations that can be done on our schema:

  • hero returns the Character who is the hero of the Star Wars trilogy; it takes an optional argument that allows us to fetch the hero of a specific episode instead.
  • human accepts a non-null string as a query argument, a human's ID, and returns the human with that ID.
  • droid does the same for droids.

These fields demonstrate another feature of the type system, the ability for a field to specify arguments that configure their behavior.

When we package the whole type system together, defining the Query type above as our entry point for queries, this creates a GraphQL Schema.

This example just scratched the surface of the type system. The specification goes into more detail about this topic in the "Type System" section, and the type directory in GraphQL.js contains code implementing a specification-compliant GraphQL type system.

Query Syntax

GraphQL queries declaratively describe what data the issuer wishes to fetch from whoever is fulfilling the GraphQL query.

For our Star Wars example, the starWarsQueryTests.js file in the GraphQL.js repository contains a number of queries and responses. That file is a test file that uses the schema discussed above and a set of sample data, located in starWarsData.js. This test file can be run to exercise the reference implementation.

An example query on the above schema would be:

query HeroNameQuery {
  hero {
    name
  }
}

The initial line, query HeroNameQuery, defines a query with the operation name HeroNameQuery that starts with the schema's root query type; in this case, Query. As defined above, Query has a hero field that returns a Character, so we'll query for that. Character then has a name field that returns a String, so we query for that, completing our query. The result of this query would then be:

{
  "hero": {
    "name": "R2-D2"
  }
}

Specifying the query keyword and an operation name is only required when a GraphQL document defines multiple operations. We therefore could have written the previous query with the query shorthand:

{
  hero {
    name
  }
}

Assuming that the backing data for the GraphQL server identified R2-D2 as the hero. The response continues to vary based on the request; if we asked for R2-D2's ID and friends with this query:

query HeroNameAndFriendsQuery {
  hero {
    id
    name
    friends {
      id
      name
    }
  }
}

then we'll get back a response like this:

{
  "hero": {
    "id": "2001",
    "name": "R2-D2",
    "friends": [
      {
        "id": "1000",
        "name": "Luke Skywalker"
      },
      {
        "id": "1002",
        "name": "Han Solo"
      },
      {
        "id": "1003",
        "name": "Leia Organa"
      }
    ]
  }
}

One of the key aspects of GraphQL is its ability to nest queries. In the above query, we asked for R2-D2's friends, but we can ask for more information about each of those objects. So let's construct a query that asks for R2-D2's friends, gets their name and episode appearances, then asks for each of their friends.

query NestedQuery {
  hero {
    name
    friends {
      name
      appearsIn
      friends {
        name
      }
    }
  }
}

which will give us the nested response

{
  "hero": {
    "name": "R2-D2",
    "friends": [
      {
        "name": "Luke Skywalker",
        "appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
        "friends": [
          { "name": "Han Solo" },
          { "name": "Leia Organa" },
          { "name": "C-3PO" },
          { "name": "R2-D2" }
        ]
      },
      {
        "name": "Han Solo",
        "appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
        "friends": [
          { "name": "Luke Skywalker" },
          { "name": "Leia Organa" },
          { "name": "R2-D2" }
        ]
      },
      {
        "name": "Leia Organa",
        "appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
        "friends": [
          { "name": "Luke Skywalker" },
          { "name": "Han Solo" },
          { "name": "C-3PO" },
          { "name": "R2-D2" }
        ]
      }
    ]
  }
}

The Query type above defined a way to fetch a human given their ID. We can use it by hard-coding the ID in the query:

query FetchLukeQuery {
  human(id: "1000") {
    name
  }
}

to get

{
  "human": {
    "name": "Luke Skywalker"
  }
}

Alternately, we could have defined the query to have a query parameter:

query FetchSomeIDQuery($someId: String!) {
  human(id: $someId) {
    name
  }
}

This query is now parameterized by $someId; to run it, we must provide that ID. If we ran it with $someId set to "1000", we would get Luke; set to "1002", we would get Han. If we passed an invalid ID here, we would get null back for the human, indicating that no such object exists.

Notice that the key in the response is the name of the field, by default. It is sometimes useful to change this key, for clarity or to avoid key collisions when fetching the same field with different arguments.

We can do that with field aliases, as demonstrated in this query:

query FetchLukeAliased {
  luke: human(id: "1000") {
    name
  }
}

We aliased the result of the human field to the key luke. Now the response is:

{
  "luke": {
    "name": "Luke Skywalker"
  }
}

Notice the key is "luke" and not "human", as it was in our previous example where we did not use the alias.

This is particularly useful if we want to use the same field twice with different arguments, as in the following query:

query FetchLukeAndLeiaAliased {
  luke: human(id: "1000") {
    name
  }
  leia: human(id: "1003") {
    name
  }
}

We aliased the result of the first human field to the key luke, and the second to leia. So the result will be:

{
  "luke": {
    "name": "Luke Skywalker"
  },
  "leia": {
    "name": "Leia Organa"
  }
}

Now imagine we wanted to ask for Luke and Leia's home planets. We could do so with this query:

query DuplicateFields {
  luke: human(id: "1000") {
    name
    homePlanet
  }
  leia: human(id: "1003") {
    name
    homePlanet
  }
}

but we can already see that this could get unwieldy, since we have to add new fields to both parts of the query. Instead, we can extract out the common fields into a fragment, and include the fragment in the query, like this:

query UseFragment {
  luke: human(id: "1000") {
    ...HumanFragment
  }
  leia: human(id: "1003") {
    ...HumanFragment
  }
}

fragment HumanFragment on Human {
  name
  homePlanet
}

Both of those queries give this result:

{
  "luke": {
    "name": "Luke Skywalker",
    "homePlanet": "Tatooine"
  },
  "leia": {
    "name": "Leia Organa",
    "homePlanet": "Alderaan"
  }
}

The UseFragment and DuplicateFields queries will both get the same result, but UseFragment is less verbose; if we wanted to add more fields, we could add it to the common fragment rather than copying it into multiple places.

We defined the type system above, so we know the type of each object in the output; the query can ask for that type using the special field __typename, defined on every object.

query CheckTypeOfR2 {
  hero {
    __typename
    name
  }
}

Since R2-D2 is a droid, this will return

{
  "hero": {
    "__typename": "Droid",
    "name": "R2-D2"
  }
}

This was particularly useful because hero was defined to return a Character, which is an interface; we might want to know what concrete type was actually returned. If we instead asked for the hero of Episode V:

query CheckTypeOfLuke {
  hero(episode: EMPIRE) {
    __typename
    name
  }
}

We would find that it was Luke, who is a Human:

{
  "hero": {
    "__typename": "Human",
    "name": "Luke Skywalker"
  }
}

As with the type system, this example just scratched the surface of the query language. The specification goes into more detail about this topic in the "Language" section, and the language directory in GraphQL.js contains code implementing a specification-compliant GraphQL query language parser and lexer.

Validation

By using the type system, it can be predetermined whether a GraphQL query is valid or not. This allows servers and clients to effectively inform developers when an invalid query has been created, without having to rely on runtime checks.

For our Star Wars example, the file starWarsValidationTests.js contains a number of demonstrations of invalid operations, and is a test file that can be run to exercise the reference implementation's validator.

To start, let's take a complex valid query. This is the NestedQuery example from the above section, but with the duplicated fields factored out into a fragment:

query NestedQueryWithFragment {
  hero {
    ...NameAndAppearances
    friends {
      ...NameAndAppearances
      friends {
        ...NameAndAppearances
      }
    }
  }
}

fragment NameAndAppearances on Character {
  name
  appearsIn
}

And this query is valid. Let's take a look at some invalid queries!

When we query for fields, we have to query for a field that exists on the given type. So as hero returns a Character, we have to query for a field on Character. That type does not have a favoriteSpaceship field, so this query:

# INVALID: favoriteSpaceship does not exist on Character
query HeroSpaceshipQuery {
  hero {
    favoriteSpaceship
  }
}

is invalid.

Whenever we query for a field and it returns something other than a scalar or an enum, we need to specify what data we want to get back from the field. Hero returns a Character, and we've been requesting fields like name and appearsIn on it; if we omit that, the query will not be valid:

# INVALID: hero is not a scalar, so fields are needed
query HeroNoFieldsQuery {
  hero
}

Similarly, if a field is a scalar, it doesn't make sense to query for additional fields on it, and doing so will make the query invalid:

# INVALID: name is a scalar, so fields are not permitted
query HeroFieldsOnScalarQuery {
  hero {
    name {
      firstCharacterOfName
    }
  }
}

Earlier, it was noted that a query can only query for fields on the type in question; when we query for hero which returns a Character, we can only query for fields that exist on Character. What happens if we want to query for R2-D2s primary function, though?

# INVALID: primaryFunction does not exist on Character
query DroidFieldOnCharacter {
  hero {
    name
    primaryFunction
  }
}

That query is invalid, because primaryFunction is not a field on Character. We want some way of indicating that we wish to fetch primaryFunction if the Character is a Droid, and to ignore that field otherwise. We can use the fragments we introduced earlier to do this. By setting up a fragment defined on Droid and including it, we ensure that we only query for primaryFunction where it is defined.

query DroidFieldInFragment {
  hero {
    name
    ...DroidFields
  }
}

fragment DroidFields on Droid {
  primaryFunction
}

This query is valid, but it's a bit verbose; named fragments were valuable above when we used them multiple times, but we're only using this one once. Instead of using a named fragment, we can use an inline fragment; this still allows us to indicate the type we are querying on, but without naming a separate fragment:

query DroidFieldInInlineFragment {
  hero {
    name
    ... on Droid {
      primaryFunction
    }
  }
}

This has just scratched the surface of the validation system; there are a number of validation rules in place to ensure that a GraphQL query is semantically meaningful. The specification goes into more detail about this topic in the "Validation" section, and the validation directory in GraphQL.js contains code implementing a specification-compliant GraphQL validator.

Introspection

It's often useful to ask a GraphQL schema for information about what queries it supports. GraphQL allows us to do so using the introspection system!

For our Star Wars example, the file starWarsIntrospectionTests.js contains a number of queries demonstrating the introspection system, and is a test file that can be run to exercise the reference implementation's introspection system.

We designed the type system, so we know what types are available, but if we didn't, we can ask GraphQL, by querying the __schema field, always available on the root type of a Query. Let's do so now, and ask what types are available.

query IntrospectionTypeQuery {
  __schema {
    types {
      name
    }
  }
}

and we get back:

{
  "__schema": {
    "types": [
      {
        "name": "Query"
      },
      {
        "name": "Character"
      },
      {
        "name": "Human"
      },
      {
        "name": "String"
      },
      {
        "name": "Episode"
      },
      {
        "name": "Droid"
      },
      {
        "name": "__Schema"
      },
      {
        "name": "__Type"
      },
      {
        "name": "__TypeKind"
      },
      {
        "name": "Boolean"
      },
      {
        "name": "__Field"
      },
      {
        "name": "__InputValue"
      },
      {
        "name": "__EnumValue"
      },
      {
        "name": "__Directive"
      }
    ]
  }
}

Wow, that's a lot of types! What are they? Let's group them:

  • Query, Character, Human, Episode, Droid - These are the ones that we defined in our type system.
  • String, Boolean - These are built-in scalars that the type system provided.
  • __Schema, __Type, __TypeKind, __Field, __InputValue, __EnumValue, __Directive - These all are preceded with a double underscore, indicating that they are part of the introspection system.

Now, let's try and figure out a good place to start exploring what queries are available. When we designed our type system, we specified what type all queries would start at; let's ask the introspection system about that!

query IntrospectionQueryTypeQuery {
  __schema {
    queryType {
      name
    }
  }
}

and we get back:

{
  "__schema": {
    "queryType": {
      "name": "Query"
    }
  }
}

And that matches what we said in the type system section, that the Query type is where we will start! Note that the naming here was just by convention; we could have named our Query type anything else, and it still would have been returned here if we had specified it as the starting type for queries. Naming it Query, though, is a useful convention.

It is often useful to examine one specific type. Let's take a look at the Droid type:

query IntrospectionDroidTypeQuery {
  __type(name: "Droid") {
    name
  }
}

and we get back:

{
  "__type": {
    "name": "Droid"
  }
}

What if we want to know more about Droid, though? For example, is it an interface or an object?

query IntrospectionDroidKindQuery {
  __type(name: "Droid") {
    name
    kind
  }
}

and we get back:

{
  "__type": {
    "name": "Droid",
    "kind": "OBJECT"
  }
}

kind returns a __TypeKind enum, one of whose values is OBJECT. If we asked about Character instead:

query IntrospectionCharacterKindQuery {
  __type(name: "Character") {
    name
    kind
  }
}

and we get back:

{
  "__type": {
    "name": "Character",
    "kind": "INTERFACE"
  }
}

We'd find that it is an interface.

It's useful for an object to know what fields are available, so let's ask the introspection system about Droid:

query IntrospectionDroidFieldsQuery {
  __type(name: "Droid") {
    name
    fields {
      name
      type {
        name
        kind
      }
    }
  }
}

and we get back:

{
  "__type": {
    "name": "Droid",
    "fields": [
      {
        "name": "id",
        "type": {
          "name": null,
          "kind": "NON_NULL"
        }
      },
      {
        "name": "name",
        "type": {
          "name": "String",
          "kind": "SCALAR"
        }
      },
      {
        "name": "friends",
        "type": {
          "name": null,
          "kind": "LIST"
        }
      },
      {
        "name": "appearsIn",
        "type": {
          "name": null,
          "kind": "LIST"
        }
      },
      {
        "name": "primaryFunction",
        "type": {
          "name": "String",
          "kind": "SCALAR"
        }
      }
    ]
  }
}

Those are our fields that we defined on Droid!

id looks a bit weird there, it has no name for the type. That's because it's a "wrapper" type of kind NON_NULL. If we queried for ofType on that field's type, we would find the String type there, telling us that this is a non-null String.

Similarly, both friends and appearsIn have no name, since they are the LIST wrapper type. We can query for ofType on those types, which will tell us what these are lists of.

query IntrospectionDroidWrappedFieldsQuery {
  __type(name: "Droid") {
    name
    fields {
      name
      type {
        name
        kind
        ofType {
          name
          kind
        }
      }
    }
  }
}

and we get back:

{
  "__type": {
    "name": "Droid",
    "fields": [
      {
        "name": "id",
        "type": {
          "name": null,
          "kind": "NON_NULL",
          "ofType": {
            "name": "String",
            "kind": "SCALAR"
          }
        }
      },
      {
        "name": "name",
        "type": {
          "name": "String",
          "kind": "SCALAR",
          "ofType": null
        }
      },
      {
        "name": "friends",
        "type": {
          "name": null,
          "kind": "LIST",
          "ofType": {
            "name": "Character",
            "kind": "INTERFACE"
          }
        }
      },
      {
        "name": "appearsIn",
        "type": {
          "name": null,
          "kind": "LIST",
          "ofType": {
            "name": "Episode",
            "kind": "ENUM"
          }
        }
      },
      {
        "name": "primaryFunction",
        "type": {
          "name": "String",
          "kind": "SCALAR",
          "ofType": null
        }
      }
    ]
  }
}

Let's end with a feature of the introspection system particularly useful for tooling; let's ask the system for documentation!

query IntrospectionDroidDescriptionQuery {
  __type(name: "Droid") {
    name
    description
  }
}

yields

{
  "__type": {
    "name": "Droid",
    "description": "A mechanical creature in the Star Wars universe."
  }
}

So we can access the documentation about the type system using introspection, and create documentation browsers, or rich IDE experiences.

This has just scratched the surface of the introspection system; we can query for enum values, what interfaces a type implements, and more. We can even introspect on the introspection system itself. The specification goes into more detail about this topic in the "Introspection" section, and the introspection file in GraphQL.js contains code implementing a specification-compliant GraphQL query introspection system.

Additional Content

This README walked through the GraphQL.js reference implementation's type system, query execution, validation, and introspection systems. There's more in both GraphQL.js and specification, including a description and implementation for executing queries, how to format a response, explaining how a type system maps to an underlying implementation, and how to format a GraphQL response, as well as the grammar for GraphQL.

Contributing to this repo

This repository is managed by EasyCLA. Project participants must sign the free (GraphQL Specification Membership agreement before making a contribution. You only need to do this one time, and it can be signed by individual contributors or their employers.

To initiate the signature process please open a PR against this repo. The EasyCLA bot will block the merge if we still need a membership agreement from you.

You can find detailed information here. If you have issues, please email [email protected].

If your company benefits from GraphQL and you would like to provide essential financial support for the systems and people that power our community, please also consider membership in the GraphQL Foundation.

swapi-graphql's People

Contributors

acao avatar ags- avatar asiandrummer avatar bogdanbiv avatar brianwarner avatar dependabot[bot] avatar dschafer avatar elendev avatar gagoar avatar greenkeeper[bot] avatar ivangoncharov avatar jsoref avatar kassens avatar leebyron avatar mwilc0x avatar nikitastupin avatar orta avatar phregenes avatar rofrol avatar rportugal avatar saihaj avatar schrockn-zz avatar tapayne88 avatar thomasheyenbrock avatar wincent 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  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

swapi-graphql's Issues

[Q]: Circular references of types clarification

Hello, thanks to make this up, it gave me a lot inspiration on designing my GraphQL schema.

I encountered a circular reference problem while building my Schema and still after hours of debug i couldn't find the reason, you might help me out to understand.

I have the following GraphQLObjectTypes

types/Serie.js

import {
    ...
} from "graphql";

import Graphus from "./../graphus";
import CategoryType from "./Category";

const Serie = Graphus.createModelType('serie', {
  title: { type: new GraphQLNonNull(GraphQLString) },
  title_seo: { type: new GraphQLNonNull(GraphQLString) },
  trama: { type: new GraphQLNonNull(GraphQLString) },
  vote_count: { type: GraphQLInt },
  images: {
    type: new GraphQLObjectType({
      name: 'SerieImages',
      fields: () => ({
        profile: { type: GraphQLString },
        cover: { type: GraphQLString },
        background: { type: GraphQLString }
      })
    })
  },
  season_count: { type: GraphQLInt },
  categories: Graphus.createConnection('serie', 'category', CategoryType, {
    as: 'categories'
  }).connectChild(),

});

export default Serie;

types/Category.js

import {
   ...
} from "graphql";

import Graphus from "./../graphus";
import SerieType from "./Serie";

console.log(SerieType); // undefined :(

const Category = Graphus.createModelType('category', {
  name: {
    type: new GraphQLNonNull(GraphQLString)
  },
  description: {
    type: new GraphQLNonNull(GraphQLString)
  },
  series: Graphus.createConnection('category', 'serie', SerieType, {
    as: 'series'
  }).connectChild()
});

export default Category;

How you could notice SerieType has a categories fields which require CategoryType and the same thing for the CategoryType which require SerieType in a many to many relationship.

Graphus.createModelType returns a GraphQLObjectType Instance
Graphus.createConnection return a relay connection similar to connectionFromUrl

Looking trough the repo source, I noticed that you do the same thing but it doesn't cause any problem.
Ex: FilmType import PersonType and PersonType uses FilmType

If you have any hints on what might cause in my case, that when importing SerieType on CategoryType it give undefined would be appreciated.

PS: if only 1 of the type require the other, the schema is built corrected

An in-range update of babel-core is breaking the build 🚨

Version 6.23.1 of babel-core just got published.

Branch Build failing 🚨
Dependency babel-core
Current Version 6.23.0
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As babel-core is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪


Status Details
  • continuous-integration/travis-ci/push The Travis CI build failed Details
Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

Where's the schema.graphql file?

This being the premier GraphQL example, I expected the schema to be defined (and documented) in a GraphQL schema file. Or maybe I overlooked something? If not, it would be nice to have to support languages other than JS. Thanks!

Queries in the live demo site seem to give incorrect results

I may be missing something, but in attempting to do joins based on films and vehicle connections I get duplicate vehicles. Is the demo implementation incorrect or is my query syntax incorrect?

{
  allFilms(first: 3) {
    films {
      title
      vehicleConnection {
        vehicles {
          id
          name
        }
      }
    }
  }
}

Link to live demo with query populated

The result lists the same vehicle multiple times within a single movie:

{
  "data": {
    "allFilms": {
      "films": [
        {
          "title": "A New Hope",
          "vehicleConnection": {
            "vehicles": [
              {
                "id": "dmVoaWNsZXM6NA==",
                "name": "Sand Crawler"
              },
              {
                "id": "dmVoaWNsZXM6Ng==",
                "name": "T-16 skyhopper"
              },
              {
                "id": "dmVoaWNsZXM6Nw==",
                "name": "X-34 landspeeder"
              },
              {
                "id": "dmVoaWNsZXM6OA==",
                "name": "TIE/LN starfighter"
              },
              {
                "id": "dmVoaWNsZXM6NA==",
                "name": "Sand Crawler"
              },
              {
                "id": "dmVoaWNsZXM6Ng==",
                "name": "T-16 skyhopper"
              }, ...

Am I missing something?

Note: This links to a closed issue because I realized this was the repo for the Star Wars GraphQL wrapper around swapi.org used in the demo site and so moved my issue here. I still can't make sense of the result I am getting.

An in-range update of browserify is breaking the build 🚨

Version 14.2.0 of browserify just got published.

Branch Build failing 🚨
Dependency browserify
Current Version 14.1.0
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As browserify is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪


Status Details
  • continuous-integration/travis-ci/push The Travis CI build failed Details
Commits

The new version differs by 5 commits .

  • 18e1d65 14.2.0
  • 0e1a7a0 add cli support for --transform-key to support mode's like production/staging/etc..
  • a5aa660 Merge pull request #1701 from wogsland/doc-fix
  • ae281bc Fixed documentation formatting that was bugging me
  • fe8c57b async test for node 7

See the full diff.

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

CORS Issue

Hello am getting this error when trying to get an introspection of your graphql api using graphql voyager

Access to fetch at 'https://graphql.org/swapi-graphql' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Could you kindly assist me or tell me why am getting this error?

Error while running npm test

C:\swapi-graphql-master\scripts\pretty.js:36
const out = stdout.toString().trim();
^

TypeError: Cannot read property 'toString' of null
at Object. (C:\swapi-graphql-master\scripts\pretty.js:36:20)
at Module._compile (module.js:635:30)
at Object.Module._extensions..js (module.js:646:10)
at Module.load (module.js:554:32)
at tryModuleLoad (module.js:497:12)
at Function.Module._load (module.js:489:3)
at Function.Module.runMain (module.js:676:10)
at startup (bootstrap_node.js:187:16)
at bootstrap_node.js:608:3
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! swapi-graphql@ pretty-check: node scripts/pretty.js --check
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the swapi-graphql@ pretty-check 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\kmema\AppData\Roaming\npm-cache_logs\2017-11-13T03_07_21_469Z-debug.log
npm ERR! Test failed. See above for more details.

I am learning how to use GraphQL and connect with my android Application. But I am getting an error on npm test command. Am I supposed to run this command in any specific folder. And also I another issue with creating Schema.json file for my android app for variant debug purpose

An in-range update of browserify is breaking the build 🚨

Version 14.1.0 of browserify just got published.

Branch Build failing 🚨
Dependency browserify
Current Version 14.0.0
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As browserify is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪


Status Details
  • continuous-integration/travis-ci/push The Travis CI build failed Details
Commits

The new version differs by 3 commits .

See the full diff.

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

npm run start fails

npm run start fails. I initially thought it was because I'm using node v7.0.0 , so I switched nvm to use node v6.9.1 and it still failed.

Heres the error:

> swapi-graphql@ start /Users/kennetpostigo/Projects/greed/docs/swapi-graphql

> npm run download && babel-node src/cloud/main.js


> swapi-graphql@ download /Users/kennetpostigo/Projects/greed/docs/swapi-graphql
> if [ ! -f src/api/cachedData/cache.js ]; then echo 'Downloading cache...' && node src/api/cachedData/downloadCache.js > src/api/cachedData/cache.js && echo 'Cached!'; fi;

/Users/kennetpostigo/Projects/greed/docs/swapi-graphql/node_modules/babel-core/lib/transformation/file/options/option-manager.js:126
      if (!option) this.log.error("Unknown option: " + alias + "." + key, ReferenceError);
                           ^

TypeError: Cannot read property 'error' of undefined
    at OptionManager.mergeOptions (/Users/kennetpostigo/Projects/greed/docs/swapi-graphql/node_modules/babel-core/lib/transformation/file/options/option-manager.js:126:28)
    at OptionManager.addConfig (/Users/kennetpostigo/Projects/greed/docs/swapi-graphql/node_modules/babel-core/lib/transformation/file/options/option-manager.js:107:10)
    at OptionManager.findConfigs (/Users/kennetpostigo/Projects/greed/docs/swapi-graphql/node_modules/babel-core/lib/transformation/file/options/option-manager.js:168:35)
    at OptionManager.init (/Users/kennetpostigo/Projects/greed/docs/swapi-graphql/node_modules/babel-core/lib/transformation/file/options/option-manager.js:229:12)
    at compile (/Users/kennetpostigo/Projects/greed/docs/swapi-graphql/node_modules/babel-core/lib/api/register/node.js:117:22)
    at normalLoader (/Users/kennetpostigo/Projects/greed/docs/swapi-graphql/node_modules/babel-core/lib/api/register/node.js:199:14)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/kennetpostigo/Projects/greed/docs/swapi-graphql/node_modules/babel-core/lib/api/register/node.js:216:7)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)

Facing some issue when I try to run npm start

npm install
added 666 packages in 86.589s

C:\swapi-graphql-master>npm start

swapi-graphql@ start C:\swapi-graphql-master
npm run download && babel-node src/server/main.js

swapi-graphql@ download C:\swapi-graphql-master
sh scripts/download

'sh' is not recognized as an internal or external command,
operable program or batch file.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! swapi-graphql@ download: sh scripts/download
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the swapi-graphql@ download 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\kmema\AppData\Roaming\npm-cache_logs\2017-11-11T10_11_37_124Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! swapi-graphql@ start: npm run download && babel-node src/server/main.js
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the swapi-graphql@ start 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\kmema\AppData\Roaming\npm-cache_logs\2017-11-11T10_11_37_279Z-debug.log

Update master to main

Folks, just a heads up that we'll be swapping the primary branch from master to main. GitHub's tooling will remap any open PRs. If you're working locally and all your code has been merged, you can either reset your origin (GitHub will provide an instruction) or just do a fresh clone.

cc/ @leebyron

build:lamba command not working on windows

After running npm i, we are encountering an error in the build:lambda command, and the error message states that "NODE_ENV" is not recognized as an internal or external command.

More GraphQL language feature examples

It would be grand to add more examples to the schema of new features we have. That way, we can fully demonstrate the features of GraphiQL, etc to newcomers!

high priority:

  • fields with resolvers that yield after a delay, for demoing @defer/@stream

all else:

  • unions
  • interfaces implementing interfaces
  • custom directives and scalars maybe? demoing new directive introspection features would be nice
  • subscriptions - how to do this with netlify functions though? possible with aws in a complicated way... would be cool to have a subscription field that provides realtime starship coordinates

graphql SWAPI Reference

I was just curious why the sample queries from here http://graphql.org/learn/ don't work on your graphiQL instance.

for example, if I run

{
  hero {
    name
  }
}

I get "Cannot query field \"hero\" on type \"Root\". Did you mean \"person\"?",

Provide SWAPI as public GraphQL server

Continuation of #49.
Hosted GraphiQL is a great solution for introducing new users to GraphQL.
However many GraphQL tools designed to work with 3rd-party GraphQL APIs so in order to provide a demo or example they need to host they own server.
For our GraphQL Fakerl we host SWAPI under https://swapi.apis.guru domain.

Problem is that create a barrier for tooling author since hosting your own server requires time and money investments.

Broken starship connection

Looks like there's a regression: This query used to work but now returns error No entry in local cache for [object Object]

#b0a73b6 Seems to be ok, so it happened at some point since then

Connection types?

I was wondering if there was a specific reason as to why there are connection types. For instance, consider the following query:

{
  person(personID: 1) {
    filmConnection {
      films {
        title
      }
    }
  }
}

It would seem more intuitive to me to have something like the following:

{
  person(personID: 1) {
    films {
      title
    }
  }
}

The latter is how I recently constructed a graphql schema of my own, so I was wondering what the motivation was behind the connection types.

Open API to other origins

Hello,

Do you think it would be ok to add a header Access-Control-Allow-Origin: * ?
It might allow other GraphQL projects to use the same graph for example purposes.

An in-range update of babel-eslint is breaking the build 🚨

Version 7.2.1 of babel-eslint just got published.

Branch Build failing 🚨
Dependency babel-eslint
Current Version 7.2.0
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As babel-eslint is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪


Status Details
  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details
Commits

The new version differs by 6 commits .

  • 3cda62e 7.2.1
  • 5626de1 Remove left over eslint 2 estraverse code (#452)
  • b5fb53b Fix type param and interface declaration scoping (#449)
  • f1cee0f Remove lodash dependency (#450)
  • eb05812 Format non-regression errors for legibility (#451)
  • 7972a05 Update README.md with codeFrame option (#448)

See the full diff.

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

Expose API for outside testing

Could you expose the API without the GraphiQL interface?

So other people can send requests to the SWAPI GraphQL endpoint in order to tests GraphQL Clients.

  • GET
  • POST

An in-range update of prettier is breaking the build 🚨

Version 1.4.0 of prettier just got published.

Branch Build failing 🚨
Dependency prettier
Current Version 1.3.1
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As prettier is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪

Status Details
  • continuous-integration/travis-ci/push The Travis CI build failed Details

Release Notes 1.4.0: TypeScript and CSS support

prettier-revolution-conf

TypeScript Support

This is the most requested feature for prettier. With 1.4.0, you can now use prettier to format your .ts and .tsx files!

The way prettier works is by using those project to generate an AST representation of the code and print it. Both babylon (the parser that powers babel) and flow are producing an AST approximately following the estree format for the JavaScript parts and then have special nodes for Flow-specific ones.

TypeScript, the same way as Flow, introduces special nodes for the syntax it introduces. Unfortunately, it doesn't follow the estree format for the rest of the JavaScript language. This puts us in a rough spot with prettier as we would have to essentially completely fork it in order to print TypeScript.

This incompatibility with the AST is not a new problem and another project struggled with it: ESLint. Because the AST is different, none of the ESLint rules are working. Fortunately for us, @JamesHenry and @soda0289 wrote a project called typescript-eslint-parser which takes a TypeScript AST and convert it to an estree one, just what we need for prettier!

After that project got setup inside of prettier, @azz, @despairblue and @Pajn implemented all the TypeScript-specific nodes and ensured that the 13k tests of the TypeScript test suite are correctly passing. This was a huge undertaking and it is finally ready to be used :)

We tested prettier on the biggest TypeScript projects we could find on GitHub to ensure that it prints correct code. We haven't spent a lot of time trying to optimize the way code is formatted yet, so if you see something strange, please raise an issue!

CSS, Less and SCSS Support

While TypeScript is the most requested feature from open source, CSS is the biggest one from Facebook engineers. Once you are used to pretty print your code in one language, you want to do it everywhere!

It turns out that CSS is a much smaller language than JavaScript and supporting it only took a few days. We are using postcss by @ai as the underlying parser which is able to parse CSS, Less and SCSS. We also depend on postcss-values-parser, postcss-selector-parser by @ben-eb postcss-media-query-parser by @dryoma.

Unfortunately, postcss right now doesn't parse Sass nor Stylus. We'd be happy to support them if someone is willing to do the work of printing them.

Note that prettier is currently just formatting the code, it does not respect any options yet such as singleQuote nor is doing any color or number normalization like we do for JavaScript.

Editor Integration

The first phase of the project was to make prettier output correct and good looking code. Now that it's in a good shape, we can spend time on making the integrations better. We just introduced support for two great features: maintain cursor position and being able to format a range instead of the entire file.

Note that we just landed the support inside of prettier itself, none of the editor integrations are using it yet. Also, we haven't really tried them out in practice so we're likely going to have to fix rough edges with them!

Add cursorOffset option for cursor translation (#1637) by @josephfrazier

Right now, we let editors figure out where the cursor should be, which they do an okay job at. But since we are printing the code, we can give the correct position!

Add --range-start/end options to format only parts of the input (#1609) by @josephfrazier

This one is a very often requested feature. Right now prettier only formats the entire file. Now it is possible to format a range.

The way it works is by going up through the AST in order to find the closest statement. This way you don't need to select exactly the right range that is valid. You can just drag in the rough place where the code you want to reformat it, and it's going to!

Adding filepath option in order to enable filetype inference (#1835) by @mitermayer

Since we are now formatting CSS and TypeScript, it is not convenient to have to specify the parser for every file. You can now pass the filepath of the file you are working on and prettier will read the extension and figure out the right parser to use.

Highlights

Wrap text content inside of JSX (#1120, #1671, #1827, #1829) by @karl

The biggest remaining issue that people have with prettier when printing JSX is when it is used when printing text. The behavior of prettier used to add an ugly {" "} before and if a line was too long, just leave it alone. Now we treat each word as a token and are able to make it flow correctly.

This is an awesome piece of work by @karl as not only did he implement the feature, but also introduced a new primitive inside of prettier in order to print a sequence of elements and break as soon as one hits the edge.

// Before
<div>
  Please state your
  {" "}
  <b>name</b>
  {" "}
  and
  {" "}
  <b>occupation</b>
  {" "}
  for the board of directors.
</div>

// After
<div>
Please state your <b>name</b> and <b>occupation</b> for the board of
directors.
</div>

Remove parenthesis for JSX inside of arrow functions (#1733) by @xixixao

People writing functional components are going to be happy about this one. We no longer put parens for arrow functions that return JSX.

// Before
const render1 = ({ styles }) => (
  <div style={styles}>
      Keep the wrapping parens. Put each key on its own line.
  </div>
);

// After
const render1 = ({ styles }) =>
<div style={styles}>
Keep the wrapping parens. Put each key on its own line.
</div>;

Improve template literal printing (#1664, #1714) by @josephfrazier

Template literal printing has always caused prettier a lot of difficulties. With 1.3.0 we massively improved the situation and with this release, I believe that we handle all the common situations in a good way.

In order to workaround issues, we added an utility that removes empty lines from the output, but it yielded some really weird results sometimes, this is now gone. Another tweak we've done is instead of indenting when ${ starts, we indent where the line that contains ${ starts.

Let us know if you still have issues with how template literals output after this release!

// Before
const Bar = styled.div`
  color: ${props => (props.highlight.length > 0 ? palette([
                 'text',
                 'dark',
                 'tertiary'
               ])(props) : palette([
                 'text',
                 'dark',
                 'primary'
               ])(props))} !important;
`

// After
const Bar = styled.div</span></span> <span class="pl-s"> color: <span class="pl-s1"><span class="pl-pse">${</span><span class="pl-smi">props</span> <span class="pl-k">=&gt;</span></span></span> <span class="pl-s"><span class="pl-s1"> <span class="pl-smi">props</span>.<span class="pl-smi">highlight</span>.<span class="pl-c1">length</span> <span class="pl-k">&gt;</span> <span class="pl-c1">0</span></span></span> <span class="pl-s"><span class="pl-s1"> <span class="pl-k">?</span> <span class="pl-en">palette</span>([<span class="pl-s"><span class="pl-pds">"</span>text<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>dark<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>tertiary<span class="pl-pds">"</span></span>])(props)</span></span> <span class="pl-s"><span class="pl-s1"> <span class="pl-k">:</span> <span class="pl-en">palette</span>([<span class="pl-s"><span class="pl-pds">"</span>text<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>dark<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>primary<span class="pl-pds">"</span></span>])(props)<span class="pl-pse">}</span></span> !important;</span> <span class="pl-s"><span class="pl-pds">

Use the same breaking rules for assignment and object values (#1721)

We have a lot of fine-tuned logic for how to break things after assignment (eg a = ...). We are now using the same one for object values. This should help for multi-line boolean logic, or big conditionals. This is also a good example of how we can create a consistent printer.

// Before
const o = {
  somethingThatsAReallyLongPropName: this.props.cardType ===
    AwesomizerCardEnum.SEEFIRST,
};

// After
const o = {
somethingThatsAReallyLongPropName:
this.props.cardType === AwesomizerCardEnum.SEEFIRST,
};

Indent conditions inside of !() (#1731)

There's been a steady stream of people complaining about the way it was rendered and was put on the list of things that are probably hard to do, will check later. It turned out to be super easy, so here you go!

// Before
const anyTestFailures = !(aggregatedResults.numFailedTests === 0 &&
  aggregatedResults.numRuntimeErrorTestSuites === 0);

// After
const anyTestFailures = !(
aggregatedResults.numFailedTests === 0 &&
aggregatedResults.numRuntimeErrorTestSuites === 0
);

Formatting Fixes

Put loop bodies on the same line when possible (#1498)

We were already doing this for if statements, we should be consistent and also do it for loops.

// Before
for (a in b)
  var c = {};

// After
for (a in b) var c = {};

Fix empty line with flow union (#1511) by @existentialism

We shouldn't indent things twice ;)

// Before
type Foo = Promise<
<span class="pl-k">|</span> { ok<span class="pl-k">:</span> <span class="pl-c1">true</span>, bar<span class="pl-k">:</span> string, baz<span class="pl-k">:</span> SomeOtherLongType }
<span class="pl-k">|</span> { ok<span class="pl-k">:</span> <span class="pl-c1">false</span>, bar<span class="pl-k">:</span> SomeOtherLongType }

>;

// After
type Foo = Promise<
{ ok: true, bar: string, baz: SomeOtherLongType } |
{ ok: false, bar: SomeOtherLongType }
>;

Do not put parens for single argument with end of line comment (#1518)

The detection code for whether an arrow function should be written without parenthesis just checked if there was a comment, but instead we only want comments that are inline like (/* comment */ num), not end of line comments.

// Before
KEYPAD_NUMBERS.map((num) => ( // Buttons 0-9
  <div />
));

KEYPAD_NUMBERS.map(num => ( // Buttons 0-9
<div />
));

Do not indent nested ternaries (#1822)

This avoids making it seems like it is indented by 4 characters instead of two. The downside is that if the condition is multi-line it's not going to be properly aligned, but I feel it's a better trade-offs. If you are doing nested ternaries, you usually have small conditions.

// Before
aaaaaaaaaaaaaaa
  ? bbbbbbbbbbbbbbbbbb
  : ccccccccccccccc
      ? ddddddddddddddd
      : eeeeeeeeeeeeeee ? fffffffffffffff : gggggggggggggggg;

// After
aaaaaaaaaaaaaaa
? bbbbbbbbbbbbbbbbbb
: ccccccccccccccc
? ddddddddddddddd
: eeeeeeeeeeeeeee ? fffffffffffffff : gggggggggggggggg;

Inline chained conditionals inside of jsx attribute (#1519)

We don't need to use the indentation to disambiguate another block as nothing can come after.

// Before
<div
  src={
    !isEnabled &&
      diffUpdateMessageInput != null &&
      this.state.isUpdateMessageEmpty
  }
/>;

// After
<div
src={
!isEnabled &&
diffUpdateMessageInput != null &&
this.state.isUpdateMessageEmpty
}
/>;

Unescape unnecessarily escaped characters in strings (#1575) by @josephfrazier

We are already trying to cleanup strings in various ways, this is another small addition that's going to remove \ that are not needed.

// Before
a = 'hol\a';

// After
a = 'hola';

Fix boolean for empty objects (#1590) by @dmitrika

We want to inline objects inside of a boolean expression as it looks weird to have { on its own line. But it turns out that it leads to weird behaviors for empty objects. So we keep them on their own line if they are empty.

const x = firstItemWithAVeryLongNameThatKeepsGoing ||
secondItemWithALongNameAsWell || {};

// After
const x =
firstItemWithAVeryLongNameThatKeepsGoing ||
secondItemWithALongNameAsWell ||
{};

Remove Parens from SequenceExpressions in ForStatements (#1597) by @k15a

It is common to assign multiple values inside of a for loop, now we don't add parenthesis anymore.

// Before
for ((i = 0), (len = arr.length); i < len; i++) {

// After
for (i = 0, len = arr.length; i < len; i++) {

Do not inline arrow when argument has a leading comment (#1660)

If you put block comments inside of arrow functions, we no longer mess everything up!

// Before
export const bem = block => /**
   * @param {String} [element] - the BEM Element within that block; if undefined, selects the block itself.
   */
element => /**
     * @param {?String} [modifier] - the BEM Modifier for the Block or Element; if undefined, selects the Block or Element unmodified.
     */
modifier =>

// After
export const bem = block =>
/
* @param {String} [element] - the BEM Element within that block; if undefined, selects the block itself.
*/
element =>
/

* @param {?String} [modifier] - the BEM Modifier for the Block or Element; if undefined, selects the Block or Element unmodified.
*/
modifier =>

Fix last comments of imports (#1677)

Another place where we have to do special logic for comments!

// Before
import {
  ExecutionResult,
  DocumentNode,
  /* tslint:disable */
  SelectionSetNode,
} /* tslint:enable */ from 'graphql';

// After
import {
DocumentNode,
/* tslint:disable /
SelectionSetNode,
/
tslint:enable */
} from 'graphql';

Handle comments in member chain (#1686, #1691)

We handled some placements before and kept adding places where they could appear, now we switch to a more general approach. Hopefully those issues shouldn't crop up in the future anymore.

// Before
const configModel = this.baseConfigurationService.getCache().consolidated // global/default values (do NOT modify)
  .merge(this.cachedWorkspaceConfig);

// After
const configModel = this.baseConfigurationService
.getCache()
.consolidated // global/default values (do NOT modify)
.merge(this.cachedWorkspaceConfig);

Use expandLast for nested arrow functions (#1720)

// Before
f(action => next =>
    next(action));

// After
f(action => next =>
next(action),
);

Put JSX comments inside of the parenthesis (#1712)

This mostly affects Facebook engineers where we automatically add $FlowFixMe when pushing a new version of flow. Now it no longer messes up those comments.

// Before
const aDiv = /* $FlowFixMe */
(
  <div className="foo">
    Foo bar
  </div>
);

// After
const aDiv = (
/* $FlowFixMe */
<div className="foo">
Foo bar
</div>
);

Force \n for multiple variable declarations (#1723)

This one has been very often requested. We used to only break multiple variable declarations if the line was > 80 columns. Now we do it regardless if there's at least one with an assignment.

// Before
var numberValue1 = 1, numberValue2 = 2;

// After
var numberValue1 = 1,
numberValue2 = 2;

Inline | null and | void (#1734)

The expanded version of flow union looks good when they are many objects but if it's used for nullability, the it looks very weird. We're now inlining | null and | void.

// Before
interface RelayProps {
  articles:
    | Array<
      | {
        __id: string,
      }
      | null
    >
    | null
}

// After
interface RelayProps {
articles: Array<{
__id: string,
} | null> | null,
}

Break on implements instead of extends (#1730)

We no longer break on extends. This should make classes with extends that can break look less wonky.

// Before
class MyContractSelectionWidget
  extends React.Component<
    void,
    MyContractSelectionWidgetPropsType,
    void
  > {
  method() {}
}

// After
class MyContractSelectionWidget extends React.Component<
void,
MyContractSelectionWidgetPropsType,
void
> {
method() {}
}

Inline single import (#1729)

The same way we don't break long require calls, we no longer break import statements if there is only a single thing being imported.

// Before
import somethingSuperLongsomethingSuperLong
  from "somethingSuperLongsomethingSuperLongsomethingSuperLong";

// After
import somethingSuperLongsomethingSuperLong from "somethingSuperLongsomethingSuperLongsomethingSuperLong";

Add the ability for SequenceExpression to break (#1749)

Did you know that if none of your code were statements, you could use () instead of {} and , instead of ;? Now you do. Some people exploit this fact when returning things from arrow functions. This is not recommended but it's easy to support in prettier so might as well ¯_(ツ)_/¯

// Before
const f = (argument1, argument2, argument3) =>
  (doSomethingWithArgument(argument1), doSomethingWithArgument(
    argument2
  ), argument1);

// After
const f = (argument1, argument2, argument3) => (
doSomethingWithArgument(argument1),
doSomethingWithArgument(argument2),
argument1
);

Don't force line break in empty loop bodies (#1815)

Loops with empty body no longer have their {} split into two lines.

// Before
while (true) {
}

// After
while (true) {}

Preserve empty lines between switch cases with comments (#1708)

// Before
switch (true) {
  case true:
  // Good luck getting here
  case false:
}

// After
switch (true) {
case true:

// Good luck getting here
case false:
}

Correctness

Remove ast-types (#1743, #1744, #1745, #1746, #1747)

We used to find where to put comments by traversing the AST using the definition from ast-types. This occasionally caused issues when some field wasn't declared, we wouldn't find the node and either print comments in an incorrect location or throw an error. It turns out that we don't need to keep this mapping and can just traverse the objects and if a node has a type field, then it's a node.

// Before
Error: did not recognize object of type "ObjectTypeSpreadProperty"

// After
type X = {...Y//};
type X = {/
/...Y};

Preserve unusual unicode whitespace (#1658, #1165) by @karl and @yamafaktory

If you were adding invisible characters inside of JSX text, we would replace them by regular spaces. I don't know why anyone would ever want to do that, but now we print it back as is!

Don't let trailing template literal comments escape (#1580, #1713, #1598, #1713) by @josephfrazier and @k15a

We used to have some pretty complicated (and not working well) code to handle comments inside of template literals. We introduced a really nice solution for JSX {} expressions. The idea is to introduce a boundary before the end of the } and if we still have unprinted comments, then flush them all at once, put a \n and print the }. We are now using this logic for template literals :)

// Before
`${0} // comment`;

// After
</span><span class="pl-s1"><span class="pl-pse">${</span></span></span> <span class="pl-s"><span class="pl-s1"><span class="pl-c1">0</span></span></span> <span class="pl-s"><span class="pl-s1"><span class="pl-c"><span class="pl-c">//</span> comment</span></span></span> <span class="pl-s"><span class="pl-s1"><span class="pl-pse">}</span></span><span class="pl-pds">;

Parenthesize await correctly (#1513, #1595, #1593) by @bakkot and @existentialism

We don't have an automated way to put parenthesis, we instead specify all the possible combinations of nodes and when they should or shouldn't have parenthesis. So there's likely a long tail of unusual combinations that are still remaining. In this case, we made await handling a lot more robust by both adding parenthesis where they are needed and removing them when they are not.

// Before
(await spellcheck) && spellcheck.setChecking(false);
new A((await x));

// After
await (spellcheck && spellcheck.setChecking(false));
new A(await x);

Preserve getter/setter info on flow ObjectTypeProperty (#1585) by @josephfrazier

Another long tail option that we haven't got right!

// Before
type T = { method: () => void };

// After
type T = { get method(): void }

Add parenthesis for single arg types with generics (#1814)

Another case of sneaky parenthesis that we didn't properly add!

// Before
type ExtractType = <A>B<C> => D

// After
type ExtractType = <A>(B<C>) => D

Fall back to non-strict mode in babylon (#1587, #1608) by @josephfrazier

We want prettier to be able to parse all the JavaScript out there. For babylon parser, we have to chose whether a file is using strict mode or not. We opted in to use strict mode by default as most files parse that way. But if you have octal literals like 0775, it would not even parse. Now if it fails to parse in strict mode, we're going to try again in non-strict. We also allow return outside of a function as it's valid in node files.

// Before
SyntaxError

// After
return 0775;

CLI

Allow --write to be used with --list-different (#1633)

This is useful to combine the two if you are writing a commit hook to tell the user what actually changed in a single command.

Ignore node_modules when running prettier from CLI (#1683) by @thymikee

It's very easy to run prettier over the node_modules/ folder by mistake which is something you almost never want to. So now we disable it by default and add a --with-node-modules option if you really want to.

Traverse dot files for glob (#1844) by @jhgg

We enabled the option to go through .dotfiles in the glob parsing library we are using. This means that writing * will now catch .eslintrc.

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

Error while starting the server on Windows

Tell the author that this fails on your system:
npm ERR! if [ ! -f src/api/cachedData/cache.js ]; then echo 'Downloading cache...' && node src/api/cachedData/downloadCache.js > src/api/cachedData/cache.js && echo 'Cached!'; fi;

This is the error I am getting on my command prompt while starting the server, Kindly provide your help to resolve the issue.

npm install not working on Windows - Unable to set NODE_ENV Environment Variable

Description

npm install will not work on MS Windows 10. The system ins not able to set Environment Variable NODE_ENV

Please make swapi-graphql work with Windows 10.

Steps to Reproduce

  • Git clone Project to Windows
  • Open Windows Powershell in swapi-graphql directory
  • Run npm install

Error will occur:

> swapi-graphql@ build:lambda D:\z_git_jj\_graphql\swapi-graphql
> NODE_ENV=development netlify-lambda build handler

Der Befehl "NODE_ENV" ist entweder falsch geschrieben oder konnte nicht gefunden werden.
Translation: The Command "NODE_ENV" is either misspelled or could not be found.

Solution

  • npm install cross-env
  • Edit Line 40 in package.json "build:lambda" - Add cross-env before setting variable
  • Run npm install

package.json:

    "build:lambda": "cross-env NODE_ENV=development netlify-lambda build handler",

Further Readings

Stackoverflow: How to set environment variables from within package.json

Set up Travis CI

Some errors of late have only been caught by manually running npm test (which runs eslint, flow and the test suite).

API unusable with recent graphql client

Hi! Similar to what I reported in GraphQLHub, any client using graphql 0.5.0 or later is incompatible with this server. Do you intend to upgrade it? Right now, I don't know any public GraphQL API compatible with a recent graphql package version (currently 0.7.1).

SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode

When attempting to run npm run download, I received the following output:

swapi-graphql@ download /Users/lizborchardt/swapi-graphql
sh scripts/download

Downloading cache...
/Users/lizborchardt/swapi-graphql/src/api/cachedData/downloadCache.js:54
let url = prefix + urlTypes[type] + '/';
^^^

SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:373:25)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:139:18)
at node.js:974:3

npm ERR! Darwin 16.4.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "run" "download"
npm ERR! node v4.6.1
npm ERR! npm v2.15.9
npm ERR! code ELIFECYCLE
npm ERR! swapi-graphql@ download: sh scripts/download
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the swapi-graphql@ download script 'sh scripts/download'.
npm ERR! This is most likely a problem with the swapi-graphql package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! sh scripts/download
npm ERR! You can get information on how to open an issue for this project with:
npm ERR! npm bugs swapi-graphql
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!
npm ERR! npm owner ls swapi-graphql
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR! /Users/lizborchardt/swapi-graphql/npm-debug.log

Migrate live demo away from Parse

We should either wrap this demo up to be browser-contained and run from gh-pages, or deploy to heroku or something since Parse is shutting down in the future.

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.