Skip to content

Commit

Permalink
compat: minimal changes to support graphql@15 within Apollo Server (#…
Browse files Browse the repository at this point in the history
…1284)

* Inline `PrintSchemaOptions` type, whose parent module has been moved.

This option will likely be deprecated in `graphql@16`.  For now, we'll
inline this type into this module to continue emitting it into the
declaration file for `makeRemoteExecutableSchema`.

This is necessary since the TypeScript compiler can no longer resolve its
previous location as `graphql` has moved the location of the `schemaPrinter`
module to `printSchema` in graphql/graphql-js#2426.

cc @IvanGoncharov

* Fix incompatibility between `iterall` and newer TypeScript types.

This wouldn't be necessary if this project had a `package-lock.json`, but...

* compat: filter extensions prior to passing to `buildASTSchema`.

.@IvanGoncharov originally brought this to my attention when he pointed me to
yaacovCR#32 (comment)
and suggested stripping extension nodes prior to invoking `buildASTSchema`
as a cross-version (v14 <=> v15) approach for interim compatibility on the
v4 series of `graphql-tools`.

The most urgent and pertinent need here from my perspective is to allow
user-exploration of the new `graphql@15` release candidate within Apollo
Server which currently re-exports the entirety of `graphql-tools` (even
though it only relies on small portions of it).

Upon further investigation of the above-referenced issue, it appears that
@yaacovCR had already crafted the solution that @IvanGoncharov had suggested
to me, which I found in 2280eef within the
well-organized #1206
(which I am thankful for the continued updates on!).

My commit here merely grabs a sub-set of that commit that seemed most
pertinent; I certainly don't claim that this solution is nearly as
comprehensive as the original 2280eef.  My
hope is that by using the same code/implementation here, it will marginally
lessen future merge conflicts.

Since this is basically a re-working of @yaacovCR's commit, I've attributed
co-authorship of this commit accordingly.  (Thank you, again!)

Ref: #1272
Co-authored-by: yaacovCR <yaacovCR@gmail.com>

* Add CHANGELOG for #1284.

Co-authored-by: Yaacov Rydzinski  <yaacovCR@gmail.com>
  • Loading branch information
abernix and yaacovCR committed Feb 19, 2020
1 parent 972024f commit a9965ec
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Change log

### vNEXT

* 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)

### 4.0.6

* Use `getIntrospectionQuery` instead of deprecated `introspectionQuery` constant from graphql-js
Expand Down
4 changes: 3 additions & 1 deletion src/generate/buildSchemaFromTypeDefinitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
concatenateTypeDefs,
SchemaError,
} from '.';
import filterExtensionDefinitions from './filterExtensionDefinitions';

function buildSchemaFromTypeDefinitions(
typeDefinitions: ITypeDefinitions,
Expand All @@ -38,10 +39,11 @@ function buildSchemaFromTypeDefinitions(
}

const backcompatOptions = { commentDescriptions: true };
const typesAst = filterExtensionDefinitions(astDocument);

// TODO fix types https://github.com/apollographql/graphql-tools/issues/542
let schema: GraphQLSchema = (buildASTSchema as any)(
astDocument,
typesAst,
backcompatOptions,
);

Expand Down
19 changes: 19 additions & 0 deletions src/generate/filterExtensionDefinitions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { DocumentNode, DefinitionNode, Kind } from 'graphql';

export default function filterExtensionDefinitions(ast: DocumentNode) {
const extensionDefs = ast.definitions.filter(
(def: DefinitionNode) =>
def.kind !== Kind.OBJECT_TYPE_EXTENSION &&
def.kind !== Kind.INTERFACE_TYPE_EXTENSION &&
def.kind !== Kind.INPUT_OBJECT_TYPE_EXTENSION &&
def.kind !== Kind.UNION_TYPE_EXTENSION &&
def.kind !== Kind.ENUM_TYPE_EXTENSION &&
def.kind !== Kind.SCALAR_TYPE_EXTENSION &&
def.kind !== Kind.SCHEMA_EXTENSION,
);

return {
...ast,
definitions: extensionDefs,
};
}
22 changes: 21 additions & 1 deletion src/stitching/makeRemoteExecutableSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import resolveParentFromTypename from './resolveFromParentTypename';
import defaultMergedResolver from './defaultMergedResolver';
import { checkResultAndHandleErrors } from './errors';
import { observableToAsyncIterable } from './observableToAsyncIterable';
import { Options as PrintSchemaOptions } from 'graphql/utilities/schemaPrinter';

export type ResolverFn = (
rootValue?: any,
Expand All @@ -49,6 +48,27 @@ export type FetcherOperation = {
context?: { [key: string]: any };
};

/**
* This type has been copied inline from its source on `@types/graphql`:
*
* https://git.io/Jv8NX
*
* Previously, it was imported from `graphql/utilities/schemaPrinter`, however
* that module has been removed in `graphql@15`. Furthermore, the sole property
* on this type is due to be deprecated in `graphql@16`.
*/
interface PrintSchemaOptions {
/**
* Descriptions are defined as preceding string literals, however an older
* experimental version of the SDL supported preceding comments as
* descriptions. Set to true to enable this deprecated behavior.
* This option is provided to ease adoption and will be removed in v16.
*
* Default: false
*/
commentDescriptions?: boolean;
}

export default function makeRemoteExecutableSchema({
schema,
link,
Expand Down
6 changes: 5 additions & 1 deletion src/stitching/observableToAsyncIterable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import { Observable } from 'apollo-link';
import { $$asyncIterator } from 'iterall';
type Callback = (value?: any) => any;

export function observableToAsyncIterable<T>(observable: Observable<T>): AsyncIterator<T> {
export function observableToAsyncIterable<T>(
observable: Observable<T>
): AsyncIterator<T> & {
[$$asyncIterator]: () => AsyncIterator<T>;
} {
const pullQueue: Callback[] = [];
const pushQueue: any[] = [];

Expand Down

0 comments on commit a9965ec

Please sign in to comment.