Skip to content

Commit

Permalink
Merge graphql-tools-fork into v5 (#1307)
Browse files Browse the repository at this point in the history
  • Loading branch information
yaacovCR authored and kamilkisiela committed Mar 31, 2020
1 parent 91dbf2e commit ec9e16e
Show file tree
Hide file tree
Showing 184 changed files with 15,872 additions and 6,284 deletions.
507 changes: 507 additions & 0 deletions .eslintrc.yml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions .gitattributes
@@ -0,0 +1 @@
* text=auto eol=lf
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -11,3 +11,6 @@ package-lock.json
npm-debug.log*
yarn-debug.log*
yarn-error.log*

.eslintcache
.nyc_output
9 changes: 0 additions & 9 deletions .npmignore

This file was deleted.

30 changes: 25 additions & 5 deletions .travis.yml
@@ -1,18 +1,38 @@
language: node_js
node_js:
- "8"
- "13"
- "12"
- "10"

env:
- GRAPHQL_VERSION='0.12'
- GRAPHQL_VERSION='0.13'
- GRAPHQL_VERSION='14.0'
- GRAPHQL_VERSION='14.1'
- GRAPHQL_VERSION='14.2'
- GRAPHQL_VERSION='14.3'
- GRAPHQL_VERSION='14.4'
- GRAPHQL_VERSION='14.5'
- GRAPHQL_VERSION='14.6'
- GRAPHQL_VERSION='rc'

install:
- npm config set spin=false
- npm install -g coveralls
- npm install

script:
- npm test
- npm run lint
- node_version=$(node -v); if [[ ${node_version:1:2} == "13" && $GRAPHQL_VERSION == "14.6" ]]; then
npm run lint;
fi
- node_version=$(node -v); if [[ ${node_version:1:2} == "13" && $GRAPHQL_VERSION == "14.6" ]]; then
npm run prettier:check;
fi
- npm run compile
- npm install graphql@$GRAPHQL_VERSION
- npm run testonly:cover

after_success:
- npm run coverage
- coveralls < ./coverage/lcov.info || true # if coveralls doesn't have it covered

# Allow Travis tests to run in containers.
sudo: false
32 changes: 32 additions & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,32 @@

### Next

#### Features

* Adds [graphql-upload](https://github.com/jaydenseric/graphql-upload) compatible scalar and link for proxying remote file uploads #671
* Add ability to merge fields from types from different schemas
* Adds transforms to wrap, extract, and rename fields #1183
* Adds transform to filter object fields #819
* Exports visitSchema, SchemaVisitor, healSchema, healTypes, cloneSchema, cloneType, cloneDirective to enable more custom transforms. #1070
* Allows removing extra delegation layers by passing fetcher/link options directly to delegateToSchema, mergeSchemas, and transformSchema and by filtering directly with filterSchema without additional transformation round #1165

#### Bug Fixes

* Filter unused variables from map when proxying requests
* Preserve subscription errors when using makeRemoteExecutableSchema
* Preserve extensions when transforming schemas
* Fix merging and transforming of custom scalars and enums #501, #1056, #1200
* Allow renaming of subscription root fields #997, #1002
* Fix alias resolution to no longer incorrectly fallback to non-aliased field when null #1171
* Do not remove default directives (skip, include, deprecated) when not merging custom directives #1159
* Fixes errors support #743, #1037, #1046
* Fix mergeSchemas to allow resolvers to return fields defined as functions #1061
* Fix default values with mergeSchemas and addResolveFunctionsToSchema #1121
* Fix interface and union healing
* Fix stitching unions of types with enums
* Fix mocking to work when schema stitching
* Fix lost directives when adding an enum resolver

### 4.0.7

* Filter `extensions` prior to passing them to `buildASTSchema`, in an effort to provide minimum compatibilty for `graphql@14`-compatible schemas with the upcoming `graphql@15` release. This PR does not, however, bring support for newer `graphql@15` features like interfaces implementing interfaces. [#1284](https://github.com/apollographql/graphql-tools/pull/1284)
Expand All @@ -20,6 +46,12 @@
[@freiksenet](https://github.com/freiksenet) in [#1003](https://github.com/apollographql/graphql-tools/pull/1003)
* Allow user-provided `buildSchema` options. <br/>
[@trevor-scheer](https://github.com/trevor-scheer) in [#1154](https://github.com/apollographql/graphql-tools/pull/1154)
* Fix `delegateToSchema` to allow delegation to subscriptions with different root field names, allows
the use of the `RenameRootFields` transform with subscriptions,
pull request [#1104](https://github.com/apollographql/graphql-tools/pull/1104), fixes
[#997](https://github.com/apollographql/graphql-tools/issues/997). <br/>
* Add transformers to rename, filter, and arbitrarily transform object fields. <br/>
Fixes [#819](https://github.com/apollographql/graphql-tools/issues/819).

### 4.0.4

Expand Down
6 changes: 3 additions & 3 deletions designs/connectors.md
Expand Up @@ -9,7 +9,7 @@ This document is intended as a design document for people who want to write conn
This is a draft at the moment, and not the final document. Chances are that the spec will change as we learn about the better ways to build GraphQL servers. It should be pretty close to the final version though, so if you want to get started and build connectors for specific backends, this document is a good starting point.


Technically you could write a GraphQL server without connectors and models by writing all your logic directly into the resolve functions, but in most cases that's not ideal. Connectors and models are a way of organizing code in a GraphQL server, and you should use them to keep your server modular. If the need arises, you can always write optimized queries directly in your resolvers or models.
Technically you could write a GraphQL server without connectors and models by writing all your logic directly into the resolvers, but in most cases that's not ideal. Connectors and models are a way of organizing code in a GraphQL server, and you should use them to keep your server modular. If the need arises, you can always write optimized queries directly in your resolvers or models.

Let's use an example schema, because it's always easier to explain things with examples:
```
Expand Down Expand Up @@ -60,7 +60,7 @@ Both batching and caching are more important in GraphQL than in traditional endp

Models are the glue between connectors - which are backend-specific - and GraphQL types - which are app-specific. They are very similar to models in ORMs, such as Rails' Active Record.

Let's say for example that you have two types, Author and Post, which are both stored in MySQL. Rather than calling the MySQL connector directly from your resolve functions, you should create models for Author and Post, which use the MySQL connector. This additional level of abstraction helps separate the data fetching logic from the GraphQL schema, which makes reusing and refactoring it easier.
Let's say for example that you have two types, Author and Post, which are both stored in MySQL. Rather than calling the MySQL connector directly from your resolvers, you should create models for Author and Post, which use the MySQL connector. This additional level of abstraction helps separate the data fetching logic from the GraphQL schema, which makes reusing and refactoring it easier.

In the example schema above, the Authors model would have the following methods:
```
Expand Down Expand Up @@ -150,7 +150,7 @@ app.use('/graphql', apolloServer({
});
```

Step 4: Calling models in resolve functions
Step 4: Calling models in resolvers
```
function resolve(author, args, ctx){
return ctx.models.Author.getById(author.id, ctx);
Expand Down
6 changes: 3 additions & 3 deletions designs/graphql-decorator-spec.md
Expand Up @@ -73,9 +73,9 @@ Decorators can be selectively applied to:
* A specific field
* An argument

Decorators can modify the behavior of the parts of the schema they are applied to. Sometimes that requires modifying other parts of the schema. For instance, the @validateRange decorator modifies the behavior of the containing field's resolve function.
Decorators can modify the behavior of the parts of the schema they are applied to. Sometimes that requires modifying other parts of the schema. For instance, the @validateRange decorator modifies the behavior of the containing field's resolver.

In general, decorators either add, remove or modify an attribute of the thing they wrap. The most common type of decorator (e.g. @adminOnly, @log, @connector) will wrap one or more field's resolve functions to alter the execution behavior of the GraphQL schema, but other decorators (e.g. @description) may add attributes to a type, field or argument. It is also possible for a type decorator to add a field to the type (e.g. @id(fields: ["uuid"]) can add the __id field).
In general, decorators either add, remove or modify an attribute of the thing they wrap. The most common type of decorator (e.g. @adminOnly, @log, @connector) will wrap one or more field resolvers to alter the execution behavior of the GraphQL schema, but other decorators (e.g. @description) may add attributes to a type, field or argument. It is also possible for a type decorator to add a field to the type (e.g. @id(fields: ["uuid"]) can add the __id field).


## Schema decorator API
Expand Down Expand Up @@ -120,7 +120,7 @@ class SampleFieldDecorator extends SchemaDecorator {
return (wrappedThing, { schema, type, field, context }) => {
// use this.config ...
// use args
// modify wrappedThing's properties, resolve functions, etc.
// modify wrappedThing's properties, resolvers, etc.
}
}
}
Expand Down
2 changes: 0 additions & 2 deletions docs/source/directive-resolvers.md
Expand Up @@ -2,7 +2,6 @@
## Directive example

Let's take a look at how we can create `@upper` Directive to upper-case a string returned from resolve on Field
[See a complete runnable example on Launchpad.](https://launchpad.graphql.com/p00rw37qx0)

To start, let's grab the schema definition string from the `makeExecutableSchema` example [in the "Generating a schema" article](/generate-schema/#example).

Expand Down Expand Up @@ -65,7 +64,6 @@ graphql(schema, query).then((result) => console.log('Got result', result));
## Multi-Directives example

Multi-Directives on a field will be apply with LTR order.
[See a complete runnable example on Launchpad.](https://launchpad.graphql.com/nx945rq1x7)

```js
// graphql-tools combines a schema string with resolvers.
Expand Down
8 changes: 3 additions & 5 deletions docs/source/generate-schema.md
Expand Up @@ -7,8 +7,6 @@ The graphql-tools package allows you to create a GraphQL.js GraphQLSchema instan

## Example

[See the complete live example in Apollo Launchpad.](https://launchpad.graphql.com/1jzxrj179)

When using `graphql-tools`, you describe the schema as a GraphQL type language string:

```js
Expand Down Expand Up @@ -212,14 +210,14 @@ const jsSchema = makeExecutableSchema({

- `parseOptions` is an optional argument which allows customization of parse when specifying `typeDefs` as a string.

- `allowUndefinedInResolve` is an optional argument, which is `true` by default. When set to `false`, causes your resolve functions to throw errors if they return undefined, which can help make debugging easier.
- `allowUndefinedInResolve` is an optional argument, which is `true` by default. When set to `false`, causes your resolver to throw errors if they return undefined, which can help make debugging easier.

- `resolverValidationOptions` is an optional argument which accepts an `ResolverValidationOptions` object which has the following boolean properties:
- `requireResolversForArgs` will cause `makeExecutableSchema` to throw an error if no resolve function is defined for a field that has arguments.
- `requireResolversForArgs` will cause `makeExecutableSchema` to throw an error if no resolver is defined for a field that has arguments.

- `requireResolversForNonScalar` will cause `makeExecutableSchema` to throw an error if a non-scalar field has no resolver defined. Setting this to `true` can be helpful in catching errors, but defaults to `false` to avoid confusing behavior for those coming from other GraphQL libraries.

- `requireResolversForAllFields` asserts that *all* fields have a valid resolve function.
- `requireResolversForAllFields` asserts that *all* fields have valid resolvers.

- `requireResolversForResolveType` will require a `resolveType()` method for Interface and Union types. This can be passed in with the field resolvers as `__resolveType()`. False to disable the warning.

Expand Down
6 changes: 3 additions & 3 deletions docs/source/index.mdx
Expand Up @@ -3,13 +3,13 @@ title: graphql-tools
description: A set of utilities to build your JavaScript GraphQL schema in a concise and powerful way.
---

GraphQL Tools is an npm package and an opinionated structure for how to build a GraphQL schema and resolvers in JavaScript, following the GraphQL-first development workflow.
GraphQL Tools is an npm package and an opinionated structure for how to build a GraphQL schema and resolvers in JavaScript, following the GraphQL-first development workflow, authored originally by the Apollo team.

```txt
npm install graphql-tools graphql
```

Functions in the `graphql-tools` package are not just useful for building servers. They can also be used in the browser, for example to mock a backend during development or testing.
Functions in the `graphql-tools` packages are not just useful for building servers. They can also be used in the browser, for example to mock a backend during development or testing.

Even though we recommend a specific way of building GraphQL servers, you can use these tools even if you don't follow our structure; they work with any GraphQL-JS schema, and each tool can be useful on its own.

Expand All @@ -24,5 +24,5 @@ JavaScript GraphQL servers are often developed with `graphql-tools` and `apollo-
This package enables a specific workflow for developing a GraphQL server, where the GraphQL schema is the first thing you design, and acts as the contract between your frontend and backend. It's not necessarily for everyone, but it can be a great way to get a server up and running with a very clear separation of concerns. These concerns are aligned with Facebook's direction about the best way to use GraphQL, and our own findings after thinking about the best way to architect a JavaScript GraphQL API codebase.

1. **Use the GraphQL schema language.** The [official GraphQL documentation](http://graphql.org/learn/schema/) explains schema concepts using a concise and easy to read language. The [getting started guide](http://graphql.org/graphql-js/) for GraphQL.js now uses the schema to introduce new developers to GraphQL. `graphql-tools` enables you to use this language alongside with all of the features of GraphQL including resolvers, interfaces, custom scalars, and more, so that you can have a seamless flow from design to mocking to implementation. For a more complete overview of the benefits, check out Nick Nance's talk, [Managing GraphQL Development at Scale](https://www.youtube.com/watch?v=XOM8J4LaYFg).
2. **Separate business logic from the schema.** As Dan Schafer covered in his talk, [GraphQL at Facebook](https://medium.com/apollo-stack/graphql-at-facebook-by-dan-schafer-38d65ef075af#.jduhdwudr), it's a good idea to treat GraphQL as a thin API and routing layer. This means that your actual business logic, permissions, and other concerns should not be part of your GraphQL schema. For large apps, we suggest splitting your GraphQL server code into 4 components: Schema, Resolvers, Models, and Connectors, which each handle a specific part of the work.
2. **Separate business logic from the schema.** As Dan Schafer covered in his talk, [GraphQL at Facebook](https://medium.com/apollo-stack/graphql-at-facebook-by-dan-schafer-38d65ef075af#.jduhdwudr), it's a good idea to treat GraphQL as a thin API and routing layer. This means that your actual business logic, permissions, and other concerns should not be part of your GraphQL schema. For large apps, we suggest splitting your GraphQL server code into 4 components: Schema, Resolvers, Models, and Connectors, which each handle a specific part of the work. You can see this in action in the server part of our [GitHunt example app](https://github.com/apollostack/GitHunt-API/blob/master/api/schema.js).
3. **Use standard libraries for auth and other special concerns.** There's no need to reinvent the login process in GraphQL. Every server framework already has a wealth of technologies for auth, file uploads, and more. It's prudent to use those standard solutions even if your data is being served through a GraphQL endpoint, and it is okay to have non-GraphQL endpoints on your server when it's the most practical solution.
24 changes: 12 additions & 12 deletions docs/source/mocking.md
Expand Up @@ -14,7 +14,7 @@ Let's take a look at how we can mock a GraphQL schema with just one line of code
To start, let's grab the schema definition string from the `makeExecutableSchema` example [in the "Generating a schema" article](/generate-schema/#example).

```js
import { makeExecutableSchema, addMockFunctionsToSchema } from 'graphql-tools';
import { makeExecutableSchema, addMocksToSchema } from 'graphql-tools';
import { graphql } from 'graphql';

// Fill this in with the schema string
Expand All @@ -24,7 +24,7 @@ const schemaString = `...`;
const schema = makeExecutableSchema({ typeDefs: schemaString });

// Add mocks, modifies schema in place
addMockFunctionsToSchema({ schema });
addMocksToSchema({ schema });

const query = `
query tasksForUser {
Expand Down Expand Up @@ -126,13 +126,13 @@ You can read some background and flavor on this approach in our blog post, ["Moc

## Mocking interfaces

You will need resolvers to mock interfaces. By default [`addMockFunctionsToSchema`](#addmockfunctionstoschema) will overwrite resolver functions.
You will need resolvers to mock interfaces. By default [`addMocksToSchema`](#addmockfunctionstoschema) will overwrite resolver functions.
By setting the property `preserveResolvers` on the options object to `true`, the type resolvers will be preserved.

```js
import {
makeExecutableSchema,
addMockFunctionsToSchema
addMocksToSchema
} from 'graphql-tools'
import mocks from './mocks' // your mock functions

Expand Down Expand Up @@ -188,7 +188,7 @@ const schema = makeExecutableSchema({
typeResolvers
})

addMockFunctionsToSchema({
addMocksToSchema({
schema,
mocks,
preserveResolvers: true
Expand All @@ -209,24 +209,24 @@ import * as introspectionResult from 'schema.json';

const schema = buildClientSchema(introspectionResult);

addMockFunctionsToSchema({schema});
addMocksToSchema({schema});
```

## API

### addMockFunctionsToSchema
### addMocksToSchema

```js
import { addMockFunctionsToSchema } from 'graphql-tools';
import { addMocksToSchema } from 'graphql-tools';

addMockFunctionsToSchema({
addMocksToSchema({
schema,
mocks: {},
preserveResolvers: false,
});
```

Given an instance of GraphQLSchema and a mock object, `addMockFunctionsToSchema` modifies the schema in place to return mock data for any valid query that is sent to the server. If `mocks` is not passed, the defaults will be used for each of the scalar types. If `preserveResolvers` is set to `true`, existing resolve functions will not be overwritten to provide mock data. This can be used to mock some parts of the server and not others.
Given an instance of GraphQLSchema and a mock object, `addMocksToSchema` modifies the schema in place to return mock data for any valid query that is sent to the server. If `mocks` is not passed, the defaults will be used for each of the scalar types. If `preserveResolvers` is set to `true`, existing resolvers will not be overwritten to provide mock data. This can be used to mock some parts of the server and not others.

### MockList

Expand All @@ -247,7 +247,7 @@ import { mockServer } from 'graphql-tools';
// or a GraphQLSchema object (eg the result of `buildSchema` from `graphql`)
const schema = `...`

// Same mocks object that `addMockFunctionsToSchema` takes above
// Same mocks object that `addMocksToSchema` takes above
const mocks = {}
preserveResolvers = false

Expand All @@ -262,6 +262,6 @@ server.query(query, variables)
})
```

`mockServer` is just a convenience wrapper on top of `addMockFunctionsToSchema`. It adds your mock resolvers to your schema and returns a client that will correctly execute
`mockServer` is just a convenience wrapper on top of `addMocksToSchema`. It adds your mock resolvers to your schema and returns a client that will correctly execute
your query with variables. **Note**: when executing queries from the returned server,
`context` and `root` will both equal `{}`.

0 comments on commit ec9e16e

Please sign in to comment.