Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move from typed-graphql to @types/graphql #249

Merged
merged 2 commits into from
Jan 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

### vNEXT

* Migrate from `typed-graphql` to `@types/graphql`. [PR #249](https://github.com/apollostack/graphql-tools/pull/249)

* ...

### v0.8.4
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"graphql": "^0.5.0 || ^0.6.0 || ^0.7.0 || ^0.8.0"
},
"optionalDependencies": {
"typed-graphql": "^1.0.2"
"@types/graphql": "^0.8.5"
},
"devDependencies": {
"@types/bluebird": "^3.0.32",
Expand Down
24 changes: 12 additions & 12 deletions src/Interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {
GraphQLSchema,
GraphQLFieldDefinition,
GraphQLResult,
GraphQLField,
ExecutionResult,
GraphQLType,
GraphQLFieldResolveFn,
GraphQLFieldResolver,
GraphQLIsTypeOfFn,
GraphQLTypeResolveFn,
GraphQLTypeResolver,
GraphQLScalarType,
} from 'graphql';

Expand All @@ -18,14 +18,14 @@ export interface IResolverValidationOptions {
}

export interface IResolverOptions {
resolve?: GraphQLFieldResolveFn;
__resolveType?: GraphQLTypeResolveFn;
__isTypeOf?: GraphQLIsTypeOfFn;
resolve?: GraphQLFieldResolver<any, any>;
__resolveType?: GraphQLTypeResolver<any, any>;
__isTypeOf?: GraphQLIsTypeOfFn<any, any>;
};

export type ITypedef = (() => ITypedef[]) | string;
export type ITypeDefinitions = ITypedef | ITypedef[];
export type IResolverObject = { [key: string]: GraphQLFieldResolveFn | IResolverOptions };
export type IResolverObject = { [key: string]: GraphQLFieldResolver<any, any> | IResolverOptions };
export interface IResolvers {
[key: string]: (() => any) | IResolverObject | GraphQLScalarType;
};
Expand All @@ -50,12 +50,12 @@ export interface IExecutableSchemaDefinition {
resolverValidationOptions?: IResolverValidationOptions;
}

export type IFieldIteratorFn = (fieldDef: GraphQLFieldDefinition, typeName: string, fieldName: string) => void;
export type IFieldIteratorFn = (fieldDef: GraphQLField<any, any>, typeName: string, fieldName: string) => void;

/* XXX on mocks, args are optional, Not sure if a bug. */
export type IMockFn = GraphQLFieldResolveFn;
export type IMockFn = GraphQLFieldResolver<any, any>;
export type IMocks = { [key: string]: IMockFn };
export type IMockTypeFn = (type: GraphQLType, typeName?: string, fieldName?: string) => GraphQLFieldResolveFn;
export type IMockTypeFn = (type: GraphQLType, typeName?: string, fieldName?: string) => GraphQLFieldResolver<any, any>;

export interface IMockOptions {
schema: GraphQLSchema;
Expand All @@ -64,5 +64,5 @@ export interface IMockOptions {
}

export interface IMockServer {
query: (query: string, vars?: { [key: string]: any }) => Promise<GraphQLResult>;
query: (query: string, vars?: { [key: string]: any }) => Promise<ExecutionResult>;
}
3 changes: 1 addition & 2 deletions src/autopublish.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
GraphQLSchema,
GraphQLFieldDefinition,
GraphQLResolveInfo,
} from 'graphql';
import { PubSub } from 'graphql-subscriptions';
Expand All @@ -10,7 +9,7 @@ export function autopublishMutationResults(schema: GraphQLSchema, pubsub: PubSub
// decorate the mutations with your thingy
const mutationFields = schema.getMutationType().getFields();
Object.keys(mutationFields).forEach( fieldName => {
const field = mutationFields[fieldName] as GraphQLFieldDefinition;
const field = mutationFields[fieldName];

// define the function
const publishMutatedValue = (
Expand Down
22 changes: 11 additions & 11 deletions src/mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import {
GraphQLInterfaceType,
GraphQLList,
GraphQLType,
GraphQLFieldDefinition,
GraphQLField,
GraphQLResolveInfo,
getNullableType,
getNamedType,
GraphQLNamedType,
GraphQLFieldResolveFn,
GraphQLFieldResolver,
} from 'graphql';
import { graphql } from 'graphql';
import * as uuid from 'uuid';
Expand Down Expand Up @@ -140,7 +140,7 @@ function addMockFunctionsToSchema({ schema, mocks = {}, preserveResolvers = fals
}
}

const mockType = function mockType(type: GraphQLType, typeName?: string, fieldName?: string): GraphQLFieldResolveFn {
const mockType = function mockType(type: GraphQLType, typeName?: string, fieldName?: string): GraphQLFieldResolver<any, any> {
// order of precendence for mocking:
// 1. if the object passed in already has fieldName, just use that
// --> if it's a function, that becomes your resolver
Expand All @@ -160,7 +160,7 @@ function addMockFunctionsToSchema({ schema, mocks = {}, preserveResolvers = fals
if (typeof root[fieldName] === 'function') {
result = root[fieldName](root, args, context, info);
if (result instanceof MockList) {
result = result.mock(root, args, context, info, fieldType as GraphQLList, mockType);
result = result.mock(root, args, context, info, fieldType as GraphQLList<any>, mockType);
}
} else {
result = root[fieldName];
Expand Down Expand Up @@ -217,13 +217,13 @@ function addMockFunctionsToSchema({ schema, mocks = {}, preserveResolvers = fals
};
};

forEachField(schema, (field: GraphQLFieldDefinition, typeName: string, fieldName: string) => {
forEachField(schema, (field: GraphQLField<any, any>, typeName: string, fieldName: string) => {
assignResolveType(field.type);
let mockResolver: GraphQLFieldResolveFn;
let mockResolver: GraphQLFieldResolver<any, any>;

// we have to handle the root mutation and root query types differently,
// because no resolver is called at the root.
/* istanbul ignore next: Must provide schema definition with query type or a type named Query. */
/* istanbul ignore next: Must provide schema DefinitionNode with query type or a type named Query. */
const isOnQueryType: boolean = schema.getQueryType() ? (schema.getQueryType().name === typeName) : false;
const isOnMutationType: boolean = schema.getMutationType() ? (schema.getMutationType().name === typeName) : false;

Expand Down Expand Up @@ -285,10 +285,10 @@ function addMockFunctionsToSchema({ schema, mocks = {}, preserveResolvers = fals

class MockList {
private len: number | number[];
private wrappedFunction: GraphQLFieldResolveFn;
private wrappedFunction: GraphQLFieldResolver<any, any>;

// wrappedFunction can return another MockList or a value
constructor(len: number | number[], wrappedFunction?: GraphQLFieldResolveFn) {
constructor(len: number | number[], wrappedFunction?: GraphQLFieldResolver<any, any>) {
this.len = len;
if (typeof wrappedFunction !== 'undefined') {
if (typeof wrappedFunction !== 'function') {
Expand All @@ -302,7 +302,7 @@ class MockList {
args: { [key: string]: any },
context: any,
info: GraphQLResolveInfo,
fieldType: GraphQLList,
fieldType: GraphQLList<any>,
mockTypeFunc: IMockTypeFn) {
let arr: any[];
if (Array.isArray(this.len)) {
Expand All @@ -315,7 +315,7 @@ class MockList {
if (typeof this.wrappedFunction === 'function') {
const res = this.wrappedFunction(root, args, context, info);
if (res instanceof MockList) {
const nullableType = getNullableType(fieldType.ofType) as GraphQLList;
const nullableType = getNullableType(fieldType.ofType) as GraphQLList<any>;
arr[i] = res.mock(root, args, context, info, nullableType, mockTypeFunc);
} else {
arr[i] = res;
Expand Down
76 changes: 40 additions & 36 deletions src/schemaGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// TODO: we should refactor this file, rename it to makeExecutableSchema, and move
// a bunch of utility functions into a separate utitlities folder, one file per function.

import { Document, parse, Kind, Definition } from 'graphql';
import { DocumentNode, parse, Kind, DefinitionNode } from 'graphql';
import { uniq } from 'lodash';
import { buildASTSchema, extendSchema } from 'graphql';
import {
Expand All @@ -15,11 +15,11 @@ import {
GraphQLObjectType,
GraphQLSchema,
GraphQLResolveInfo,
GraphQLFieldDefinition,
GraphQLFieldResolveFn,
GraphQLField,
GraphQLFieldResolver,
GraphQLType,
GraphQLInterfaceType,
GraphQLFieldDefinitionMap,
GraphQLFieldMap,
} from 'graphql';
import {
IExecutableSchemaDefinition ,
Expand Down Expand Up @@ -100,7 +100,7 @@ function makeExecutableSchema({
if (typeof resolvers['__schema'] === 'function') {
// TODO a bit of a hack now, better rewrite generateSchema to attach it there.
// not doing that now, because I'd have to rewrite a lot of tests.
addSchemaLevelResolveFunction(jsSchema, resolvers['__schema'] as GraphQLFieldResolveFn);
addSchemaLevelResolveFunction(jsSchema, resolvers['__schema'] as GraphQLFieldResolver<any, any>);
}
if (connectors) {
// connectors are optional, at least for now. That means you can just import them in the resolve
Expand Down Expand Up @@ -141,7 +141,7 @@ function buildSchemaFromTypeDefinitions(typeDefinitions: ITypeDefinitions): Grap
myDefinitions = concatenateTypeDefs(myDefinitions);
}

const astDocument: Document = parse(myDefinitions);
const astDocument: DocumentNode = parse(myDefinitions);
let schema: GraphQLSchema = buildASTSchema(astDocument);

const extensionsAst = extractExtensionDefinitions(astDocument);
Expand All @@ -152,9 +152,9 @@ function buildSchemaFromTypeDefinitions(typeDefinitions: ITypeDefinitions): Grap
return schema;
}

function extractExtensionDefinitions(ast: Document) {
function extractExtensionDefinitions(ast: DocumentNode) {
const extensionDefs =
ast.definitions.filter((def: Definition) => def.kind === Kind.TYPE_EXTENSION_DEFINITION);
ast.definitions.filter((def: DefinitionNode) => def.kind === Kind.TYPE_EXTENSION_DEFINITION);

return Object.assign({}, ast, {
definitions: extensionDefs,
Expand Down Expand Up @@ -212,32 +212,33 @@ const attachConnectorsToContext = deprecated<Function>({
throw new Error('Connectors already attached to context, cannot attach more than once');
}
schema['_apolloConnectorsAttached'] = true;
const attachconnectorFn: GraphQLFieldResolveFn = (root: any, args: { [key: string]: any }, ctx: any) => {
if (typeof ctx !== 'object') {
// if in any way possible, we should throw an error when the attachconnectors
// function is called, not when a query is executed.
const contextType = typeof ctx;
throw new Error(`Cannot attach connector because context is not an object: ${contextType}`);
}
if (typeof ctx.connectors === 'undefined') {
ctx.connectors = {};
}
Object.keys(connectors).forEach((connectorName) => {
let connector: IConnector = connectors[connectorName];
if ( !!connector.prototype ) {
ctx.connectors[connectorName] = new (<IConnectorCls> connector)(ctx);
} else {
throw new Error(`Connector must be a function or an class`);
const attachconnectorFn: GraphQLFieldResolver<any, any> =
(root: any, args: { [key: string]: any }, ctx: any) => {
if (typeof ctx !== 'object') {
// if in any way possible, we should throw an error when the attachconnectors
// function is called, not when a query is executed.
const contextType = typeof ctx;
throw new Error(`Cannot attach connector because context is not an object: ${contextType}`);
}
});
return root;
};
if (typeof ctx.connectors === 'undefined') {
ctx.connectors = {};
}
Object.keys(connectors).forEach((connectorName) => {
let connector: IConnector = connectors[connectorName];
if ( !!connector.prototype ) {
ctx.connectors[connectorName] = new (<IConnectorCls> connector)(ctx);
} else {
throw new Error(`Connector must be a function or an class`);
}
});
return root;
};
addSchemaLevelResolveFunction(schema, attachconnectorFn);
});

// wraps all resolve functions of query, mutation or subscription fields
// with the provided function to simulate a root schema level resolve funciton
function addSchemaLevelResolveFunction(schema: GraphQLSchema, fn: GraphQLFieldResolveFn): void {
function addSchemaLevelResolveFunction(schema: GraphQLSchema, fn: GraphQLFieldResolver<any, any>): void {
// TODO test that schema is a schema, fn is a function
const rootTypes = ([
schema.getQueryType(),
Expand All @@ -261,7 +262,7 @@ function addSchemaLevelResolveFunction(schema: GraphQLSchema, fn: GraphQLFieldRe
});
}

function getFieldsForType(type: GraphQLType): GraphQLFieldDefinitionMap {
function getFieldsForType(type: GraphQLType): GraphQLFieldMap<any, any> {
if ((type instanceof GraphQLObjectType) ||
(type instanceof GraphQLInterfaceType)) {
return type.getFields();
Expand Down Expand Up @@ -319,7 +320,7 @@ function addResolveFunctionsToSchema(schema: GraphQLSchema, resolveFunctions: IR
});
}

function setFieldProperties(field: GraphQLFieldDefinition, propertiesObj: Object) {
function setFieldProperties(field: GraphQLField<any, any>, propertiesObj: Object) {
Object.keys(propertiesObj).forEach((propertyName) => {
field[propertyName] = propertiesObj[propertyName];
});
Expand Down Expand Up @@ -358,7 +359,7 @@ function assertResolveFunctionsPresent(schema: GraphQLSchema, resolverValidation
});
}

function expectResolveFunction(field: GraphQLFieldDefinition, typeName: string, fieldName: string) {
function expectResolveFunction(field: GraphQLField<any, any>, typeName: string, fieldName: string) {
if (!field.resolve) {
// tslint:disable-next-line: max-line-length
console.warn(`Resolve function missing for "${typeName}.${fieldName}". To disable this warning check https://github.com/apollostack/graphql-tools/issues/131`);
Expand All @@ -383,7 +384,10 @@ function addErrorLoggingToSchema(schema: GraphQLSchema, logger: ILogger): void {
}

// XXX badly named function. this doesn't really wrap, it just chains resolvers...
function wrapResolver(innerResolver: GraphQLFieldResolveFn | undefined, outerResolver: GraphQLFieldResolveFn): GraphQLFieldResolveFn {
function wrapResolver(
innerResolver: GraphQLFieldResolver<any, any> | undefined,
outerResolver: GraphQLFieldResolver<any, any>,
): GraphQLFieldResolver<any, any> {
return (obj, args, ctx, info) => {
return Promise.resolve(outerResolver(obj, args, ctx, info)).then(root => {
if (innerResolver) {
Expand All @@ -394,7 +398,7 @@ function wrapResolver(innerResolver: GraphQLFieldResolveFn | undefined, outerRes
};
}

function chainResolvers(resolvers: GraphQLFieldResolveFn[]) {
function chainResolvers(resolvers: GraphQLFieldResolver<any, any>[]) {
return (root: any, args: {[argName: string]: any}, ctx: any, info: GraphQLResolveInfo) => {
return resolvers.reduce(
(prev, curResolver) => {
Expand All @@ -414,7 +418,7 @@ function chainResolvers(resolvers: GraphQLFieldResolveFn[]) {
* logger: an object instance of type Logger
* hint: an optional hint to add to the error's message
*/
function decorateWithLogger(fn: GraphQLFieldResolveFn | undefined, logger: ILogger, hint: string): GraphQLFieldResolveFn {
function decorateWithLogger(fn: GraphQLFieldResolver<any, any> | undefined, logger: ILogger, hint: string): GraphQLFieldResolver<any, any> {
if (typeof fn === 'undefined') {
fn = defaultResolveFn;
}
Expand Down Expand Up @@ -445,7 +449,7 @@ function addCatchUndefinedToSchema(schema: GraphQLSchema): void {
});
}

function decorateToCatchUndefined(fn: GraphQLFieldResolveFn, hint: string): GraphQLFieldResolveFn {
function decorateToCatchUndefined(fn: GraphQLFieldResolver<any, any>, hint: string): GraphQLFieldResolver<any, any> {
if (typeof fn === 'undefined') {
fn = defaultResolveFn;
}
Expand All @@ -464,7 +468,7 @@ function decorateToCatchUndefined(fn: GraphQLFieldResolveFn, hint: string): Grap
// if people don't actually cache the operation.
// if they do cache the operation, they will have to
// manually remove the __runAtMostOnce before every request.
function runAtMostOncePerRequest(fn: GraphQLFieldResolveFn): GraphQLFieldResolveFn {
function runAtMostOncePerRequest(fn: GraphQLFieldResolver<any, any>): GraphQLFieldResolver<any, any> {
let value: any;
const randomNumber = Math.random();
return (root, args, ctx, info) => {
Expand Down
Loading