mirror of
https://github.com/gosticks/DefinitelyTyped.git
synced 2026-08-15 22:40:21 +00:00
add graphql-relay typings
This commit is contained in:
@@ -0,0 +1,230 @@
|
||||
import {
|
||||
GraphQLString,
|
||||
GraphQLObjectType,
|
||||
GraphQLFieldResolver,
|
||||
GraphQLFieldConfigMap,
|
||||
GraphQLResolveInfo,
|
||||
GraphQLTypeResolver,
|
||||
GraphQLFieldConfig,
|
||||
GraphQLInterfaceType,
|
||||
GraphQLInputType,
|
||||
GraphQLInputFieldConfigMap,
|
||||
GraphQLNonNull,
|
||||
GraphQLID,
|
||||
} from "graphql";
|
||||
import {
|
||||
// Connections
|
||||
connectionArgs,
|
||||
forwardConnectionArgs,
|
||||
backwardConnectionArgs,
|
||||
connectionDefinitions,
|
||||
connectionFromArray,
|
||||
connectionFromPromisedArray,
|
||||
cursorForObjectInConnection,
|
||||
// Object Identification
|
||||
nodeDefinitions,
|
||||
toGlobalId,
|
||||
fromGlobalId,
|
||||
globalIdField,
|
||||
pluralIdentifyingRootField,
|
||||
// Mutations
|
||||
mutationWithClientMutationId,
|
||||
} from ".";
|
||||
// Connections
|
||||
// connectionArgs returns the arguments that fields should provide when they return a connection type that supports bidirectional pagination.
|
||||
connectionArgs.first = 10;
|
||||
connectionArgs.after = "a";
|
||||
connectionArgs.before = "b";
|
||||
connectionArgs.last = 10;
|
||||
// forwardConnectionArgs returns the arguments that fields should provide when they return a connection type that only supports forward pagination.
|
||||
forwardConnectionArgs.after = "a";
|
||||
forwardConnectionArgs.first = 10;
|
||||
// backwardConnectionArgs returns the arguments that fields should provide when they return a connection type that only supports backward pagination.
|
||||
backwardConnectionArgs.before = "b";
|
||||
backwardConnectionArgs.last = 10;
|
||||
// connectionDefinitions returns a connectionType and its associated edgeType, given a node type.
|
||||
let resolve: GraphQLFieldResolver<any, any> = (source, args, context, info) => {
|
||||
info.fieldName = "f";
|
||||
};
|
||||
const fields: GraphQLFieldConfigMap<any, any> = {};
|
||||
let t: GraphQLObjectType;
|
||||
let e: GraphQLObjectType;
|
||||
let def = connectionDefinitions({
|
||||
connectionFields: fields,
|
||||
edgeFields: fields,
|
||||
name: "N",
|
||||
nodeType: new GraphQLObjectType({
|
||||
name: "N",
|
||||
fields: {},
|
||||
}),
|
||||
resolveCursor: resolve,
|
||||
resolveNode: resolve,
|
||||
});
|
||||
t = def.connectionType;
|
||||
e = def.edgeType;
|
||||
// connectionFromArray is a helper method that takes an array and the arguments from connectionArgs, does pagination and filtering, and returns an object in the shape expected by a connectionType's resolve function.
|
||||
const conn = connectionFromArray([1, 2, 3], {
|
||||
after: "a",
|
||||
before: "b",
|
||||
first: 1,
|
||||
last: 5,
|
||||
});
|
||||
conn.edges.map((e) => { e.cursor.toLowerCase(); e.node.toExponential(); });
|
||||
conn.pageInfo.endCursor = "e";
|
||||
conn.pageInfo.hasNextPage = true;
|
||||
conn.pageInfo.hasPreviousPage = true;
|
||||
conn.pageInfo.startCursor = "s";
|
||||
// connectionFromPromisedArray is similar to connectionFromArray, but it takes a promise that resolves to an array, and returns a promise that resolves to the expected shape by connectionType.
|
||||
const conn2 = connectionFromPromisedArray(new Promise<number[]>((resolve) => {
|
||||
resolve();
|
||||
}), {
|
||||
after: "a",
|
||||
before: "b",
|
||||
first: 1,
|
||||
last: 5,
|
||||
});
|
||||
conn2.then((res) => {
|
||||
res = conn;
|
||||
});
|
||||
// cursorForObjectInConnection is a helper method that takes an array and a member object, and returns a cursor for use in the mutation payload.
|
||||
cursorForObjectInConnection(["a"], "b").toLowerCase();
|
||||
// An example usage of these methods from the test schema:
|
||||
let shipType: GraphQLObjectType = new GraphQLObjectType({
|
||||
name: "ShipType",
|
||||
fields: {},
|
||||
});
|
||||
const {connectionType: ShipConnection} =
|
||||
connectionDefinitions({ nodeType: shipType });
|
||||
const factionType = new GraphQLObjectType({
|
||||
name: "Faction",
|
||||
fields: () => ({
|
||||
ships: {
|
||||
type: ShipConnection,
|
||||
args: connectionArgs,
|
||||
resolve: (faction, args) => connectionFromArray(
|
||||
faction.ships.map((id: any) => id),
|
||||
args
|
||||
),
|
||||
}
|
||||
}),
|
||||
});
|
||||
// Object Identification
|
||||
// nodeDefinitions returns the Node interface that objects can implement, and returns the node root field to include on the query type. To implement this, it takes a function to resolve an ID to an object, and to determine the type of a given object.
|
||||
const resolver: GraphQLTypeResolver<any, any> = () => {
|
||||
return new GraphQLObjectType({
|
||||
name: "T",
|
||||
fields: {},
|
||||
});
|
||||
};
|
||||
const idFetcher = (id: string, context: number, info: GraphQLResolveInfo) => {
|
||||
info.fieldName = "f";
|
||||
};
|
||||
const nodeDef = nodeDefinitions<number>(idFetcher, resolver);
|
||||
const fieldConfig: GraphQLFieldConfig<any, any> = nodeDef.nodeField;
|
||||
const interfaceType: GraphQLInterfaceType = nodeDef.nodeInterface;
|
||||
// toGlobalId takes a type name and an ID specific to that type name, and returns a "global ID" that is unique among all types.
|
||||
toGlobalId("t", "i").toLowerCase();
|
||||
// fromGlobalId takes the "global ID" created by toGlobalID, and returns the type name and ID used to create it.
|
||||
const fgi = fromGlobalId("gid");
|
||||
fgi.id.toLowerCase();
|
||||
fgi.type.toUpperCase();
|
||||
// globalIdField creates the configuration for an id field on a node.
|
||||
const idFetcher2 = (object: any, context: any, info: GraphQLResolveInfo) => {
|
||||
return "";
|
||||
};
|
||||
const gif: GraphQLFieldConfig<any, any> = globalIdField("t", idFetcher2);
|
||||
// pluralIdentifyingRootField creates a field that accepts a list of non-ID identifiers (like a username) and maps them to their corresponding objects.
|
||||
const input: GraphQLInputType = GraphQLString;
|
||||
const prf: GraphQLFieldConfig<any, any> = pluralIdentifyingRootField({
|
||||
argName: "a",
|
||||
inputType: input,
|
||||
outputType: input,
|
||||
resolveSingleInput: (input: any, context: any, info: GraphQLResolveInfo) => {
|
||||
return "";
|
||||
},
|
||||
description: "d",
|
||||
});
|
||||
// An example usage of these methods from the test schema:
|
||||
const {nodeInterface, nodeField} = nodeDefinitions(
|
||||
(globalId) => {
|
||||
var {type, id} = fromGlobalId(globalId);
|
||||
return "data[type][id]";
|
||||
},
|
||||
(obj) => {
|
||||
return obj.ships ? factionType : shipType;
|
||||
}
|
||||
);
|
||||
|
||||
const factionType2 = new GraphQLObjectType({
|
||||
name: 'Faction',
|
||||
fields: () => ({
|
||||
id: globalIdField(),
|
||||
}),
|
||||
interfaces: [nodeInterface]
|
||||
});
|
||||
|
||||
const queryType = new GraphQLObjectType({
|
||||
name: 'Query',
|
||||
fields: () => ({
|
||||
node: nodeField
|
||||
})
|
||||
});
|
||||
// Mutations
|
||||
// mutationWithClientMutationId takes a name, input fields, output fields, and a mutation method to map from the input fields to the output fields, performing the mutation along the way. It then creates and returns a field configuration that can be used as a top-level field on the mutation type.
|
||||
const gifcm: GraphQLInputFieldConfigMap = {};
|
||||
const gfcm: GraphQLFieldConfigMap<any, any> = {};
|
||||
mutationWithClientMutationId({
|
||||
name: "M",
|
||||
description: "D",
|
||||
inputFields: gifcm,
|
||||
mutateAndGetPayload: (object: any,
|
||||
ctx: any,
|
||||
info: GraphQLResolveInfo) => {
|
||||
return new Promise<string>((resolve) => {
|
||||
resolve(info.fieldName);
|
||||
});
|
||||
},
|
||||
outputFields: gfcm,
|
||||
});
|
||||
// An example usage of these methods from the test schema:
|
||||
const data: any = {};
|
||||
var shipMutation = mutationWithClientMutationId({
|
||||
name: 'IntroduceShip',
|
||||
inputFields: {
|
||||
shipName: {
|
||||
type: new GraphQLNonNull(GraphQLString)
|
||||
},
|
||||
factionId: {
|
||||
type: new GraphQLNonNull(GraphQLID)
|
||||
}
|
||||
},
|
||||
outputFields: {
|
||||
ship: {
|
||||
type: shipType,
|
||||
resolve: (payload) => data['Ship'][payload.shipId]
|
||||
},
|
||||
faction: {
|
||||
type: factionType,
|
||||
resolve: (payload) => data['Faction'][payload.factionId]
|
||||
}
|
||||
},
|
||||
mutateAndGetPayload: ({shipName, factionId}) => {
|
||||
var newShip = {
|
||||
id: "11",
|
||||
name: shipName
|
||||
};
|
||||
// data.Ship[newShip.id] = newShip;
|
||||
// data.Faction[factionId].ships.push(newShip.id);
|
||||
return {
|
||||
shipId: newShip.id,
|
||||
factionId,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
var mutationType = new GraphQLObjectType({
|
||||
name: 'Mutation',
|
||||
fields: () => ({
|
||||
introduceShip: shipMutation
|
||||
})
|
||||
});
|
||||
Vendored
+310
@@ -0,0 +1,310 @@
|
||||
// Type definitions for graphql-relay 0.4
|
||||
// Project: https://github.com/graphql/graphql-relay-js
|
||||
// Definitions by: Arvitaly <https://github.com/arvitaly>, nitintutlani <https://github.com/nitintutlani>, Grelinfo <https://github.com/Grelinfo>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
|
||||
import {
|
||||
GraphQLBoolean,
|
||||
GraphQLInt,
|
||||
GraphQLNonNull,
|
||||
GraphQLList,
|
||||
GraphQLObjectType,
|
||||
GraphQLString,
|
||||
GraphQLFieldConfig,
|
||||
GraphQLInputFieldConfigMap,
|
||||
GraphQLFieldConfigMap,
|
||||
GraphQLFieldConfigArgumentMap,
|
||||
GraphQLResolveInfo,
|
||||
GraphQLInterfaceType,
|
||||
GraphQLInputType,
|
||||
GraphQLOutputType,
|
||||
GraphQLFieldResolver,
|
||||
GraphQLTypeResolver,
|
||||
Thunk
|
||||
} from "graphql";
|
||||
|
||||
// connection/connection.js
|
||||
|
||||
/**
|
||||
* Returns a GraphQLFieldConfigArgumentMap appropriate to include on a field
|
||||
* whose return type is a connection type with forward pagination.
|
||||
*/
|
||||
type ForwardConnectionArgs = {
|
||||
after: ConnectionCursor;
|
||||
first: number;
|
||||
}
|
||||
export const forwardConnectionArgs: GraphQLFieldConfigArgumentMap & {
|
||||
after: ConnectionCursor;
|
||||
first: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a GraphQLFieldConfigArgumentMap appropriate to include on a field
|
||||
* whose return type is a connection type with backward pagination.
|
||||
*/
|
||||
type BackwardConnectionArgs = {
|
||||
before: ConnectionCursor;
|
||||
last: number;
|
||||
}
|
||||
export const backwardConnectionArgs: GraphQLFieldConfigArgumentMap & {
|
||||
before: ConnectionCursor;
|
||||
last: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a GraphQLFieldConfigArgumentMap appropriate to include on a field
|
||||
* whose return type is a connection type with bidirectional pagination.
|
||||
*/
|
||||
export const connectionArgs: GraphQLFieldConfigArgumentMap & ForwardConnectionArgs & BackwardConnectionArgs;
|
||||
|
||||
type ConnectionConfig = {
|
||||
name?: string | null,
|
||||
nodeType: GraphQLObjectType,
|
||||
resolveNode?: GraphQLFieldResolver<any, any> | null,
|
||||
resolveCursor?: GraphQLFieldResolver<any, any> | null,
|
||||
edgeFields?: Thunk<GraphQLFieldConfigMap<any, any>> | null,
|
||||
connectionFields?: Thunk<GraphQLFieldConfigMap<any, any>> | null
|
||||
};
|
||||
|
||||
type GraphQLConnectionDefinitions = {
|
||||
edgeType: GraphQLObjectType,
|
||||
connectionType: GraphQLObjectType
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a GraphQLObjectType for a connection with the given name,
|
||||
* and whose nodes are of the specified type.
|
||||
*/
|
||||
export function connectionDefinitions(
|
||||
config: ConnectionConfig
|
||||
): GraphQLConnectionDefinitions;
|
||||
|
||||
// connection/connectiontypes.js
|
||||
|
||||
/**
|
||||
* An flow type alias for cursors in this implementation.
|
||||
*/
|
||||
export type ConnectionCursor = string;
|
||||
|
||||
/**
|
||||
* A flow type designed to be exposed as `PageInfo` over GraphQL.
|
||||
*/
|
||||
export type PageInfo = {
|
||||
startCursor: ConnectionCursor,
|
||||
endCursor: ConnectionCursor,
|
||||
hasPreviousPage: boolean,
|
||||
hasNextPage: boolean
|
||||
};
|
||||
|
||||
/**
|
||||
* A flow type designed to be exposed as a `Connection` over GraphQL.
|
||||
*/
|
||||
export type Connection<T> = {
|
||||
edges: Array<Edge<T>>;
|
||||
pageInfo: PageInfo;
|
||||
};
|
||||
|
||||
/**
|
||||
* A flow type designed to be exposed as a `Edge` over GraphQL.
|
||||
*/
|
||||
type Edge<T> = {
|
||||
node: T;
|
||||
cursor: ConnectionCursor;
|
||||
};
|
||||
|
||||
/**
|
||||
* A flow type describing the arguments a connection field receives in GraphQL.
|
||||
*/
|
||||
type ConnectionArguments = {
|
||||
before?: ConnectionCursor;
|
||||
after?: ConnectionCursor;
|
||||
first?: number;
|
||||
last?: number;
|
||||
};
|
||||
|
||||
|
||||
// connection/arrayconnection.js
|
||||
|
||||
type ArraySliceMetaInfo = {
|
||||
sliceStart: number;
|
||||
arrayLength: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* A simple function that accepts an array and connection arguments, and returns
|
||||
* a connection object for use in GraphQL. It uses array offsets as pagination,
|
||||
* so pagination will only work if the array is static.
|
||||
*/
|
||||
export function connectionFromArray<T>(
|
||||
data: Array<T>,
|
||||
args: ConnectionArguments
|
||||
): Connection<T>;
|
||||
|
||||
/**
|
||||
* A version of `connectionFromArray` that takes a promised array, and returns a
|
||||
* promised connection.
|
||||
*/
|
||||
export function connectionFromPromisedArray<T>(
|
||||
dataPromise: Promise<Array<T>>,
|
||||
args: ConnectionArguments
|
||||
): Promise<Connection<T>>;
|
||||
|
||||
/**
|
||||
* Given a slice (subset) of an array, returns a connection object for use in
|
||||
* GraphQL.
|
||||
*
|
||||
* This function is similar to `connectionFromArray`, but is intended for use
|
||||
* cases where you know the cardinality of the connection, consider it too large
|
||||
* to materialize the entire array, and instead wish pass in a slice of the
|
||||
* total result large enough to cover the range specified in `args`.
|
||||
*/
|
||||
export function connectionFromArraySlice<T>(
|
||||
arraySlice: Array<T>,
|
||||
args: ConnectionArguments,
|
||||
meta: ArraySliceMetaInfo
|
||||
): Connection<T>;
|
||||
|
||||
/**
|
||||
* A version of `connectionFromArraySlice` that takes a promised array slice,
|
||||
* and returns a promised connection.
|
||||
*/
|
||||
export function connectionFromPromisedArraySlice<T>(
|
||||
dataPromise: Promise<Array<T>>,
|
||||
args: ConnectionArguments,
|
||||
arrayInfo: ArraySliceMetaInfo
|
||||
): Promise<Connection<T>>;
|
||||
|
||||
/**
|
||||
* Creates the cursor string from an offset.
|
||||
*/
|
||||
export function offsetToCursor(offset: number): ConnectionCursor;
|
||||
|
||||
/**
|
||||
* Rederives the offset from the cursor string.
|
||||
*/
|
||||
export function cursorToOffset(cursor: ConnectionCursor): number;
|
||||
|
||||
/**
|
||||
* Return the cursor associated with an object in an array.
|
||||
*/
|
||||
export function cursorForObjectInConnection<T>(
|
||||
data: Array<T>,
|
||||
object: T
|
||||
): ConnectionCursor;
|
||||
|
||||
/**
|
||||
* Given an optional cursor and a default offset, returns the offset
|
||||
* to use; if the cursor contains a valid offset, that will be used,
|
||||
* otherwise it will be the default.
|
||||
*/
|
||||
export function getOffsetWithDefault(
|
||||
cursor?: ConnectionCursor,
|
||||
defaultOffset?: number
|
||||
): number;
|
||||
|
||||
// mutation/mutation.js
|
||||
|
||||
type mutationFn = (
|
||||
object: any,
|
||||
ctx: any,
|
||||
info: GraphQLResolveInfo
|
||||
) => Promise<any> | any;
|
||||
|
||||
/**
|
||||
* A description of a mutation consumable by mutationWithClientMutationId
|
||||
* to create a GraphQLFieldConfig for that mutation.
|
||||
*
|
||||
* The inputFields and outputFields should not include `clientMutationId`,
|
||||
* as this will be provided automatically.
|
||||
*
|
||||
* An input object will be created containing the input fields, and an
|
||||
* object will be created containing the output fields.
|
||||
*
|
||||
* mutateAndGetPayload will receieve an Object with a key for each
|
||||
* input field, and it should return an Object with a key for each
|
||||
* output field. It may return synchronously, or return a Promise.
|
||||
*/
|
||||
type MutationConfig = {
|
||||
name: string,
|
||||
description?: string
|
||||
inputFields: Thunk<GraphQLInputFieldConfigMap>,
|
||||
outputFields: Thunk<GraphQLFieldConfigMap<any, any>>,
|
||||
mutateAndGetPayload: mutationFn,
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a GraphQLFieldConfig for the mutation described by the
|
||||
* provided MutationConfig.
|
||||
*/
|
||||
export function mutationWithClientMutationId(
|
||||
config: MutationConfig
|
||||
): GraphQLFieldConfig<any, any>;
|
||||
|
||||
// node/node.js
|
||||
|
||||
type GraphQLNodeDefinitions = {
|
||||
nodeInterface: GraphQLInterfaceType,
|
||||
nodeField: GraphQLFieldConfig<any, any>
|
||||
};
|
||||
|
||||
type typeResolverFn = ((any: any) => GraphQLObjectType) |
|
||||
((any: any) => Promise<GraphQLObjectType>);
|
||||
|
||||
/**
|
||||
* Given a function to map from an ID to an underlying object, and a function
|
||||
* to map from an underlying object to the concrete GraphQLObjectType it
|
||||
* corresponds to, constructs a `Node` interface that objects can implement,
|
||||
* and a field config for a `node` root field.
|
||||
*
|
||||
* If the typeResolver is omitted, object resolution on the interface will be
|
||||
* handled with the `isTypeOf` method on object types, as with any GraphQL
|
||||
* interface without a provided `resolveType` method.
|
||||
*/
|
||||
export function nodeDefinitions<TContext>(
|
||||
idFetcher: ((id: string, context: TContext, info: GraphQLResolveInfo) => any),
|
||||
typeResolver?: GraphQLTypeResolver<any, TContext>
|
||||
): GraphQLNodeDefinitions;
|
||||
|
||||
type ResolvedGlobalId = {
|
||||
type: string,
|
||||
id: string
|
||||
};
|
||||
|
||||
/**
|
||||
* Takes a type name and an ID specific to that type name, and returns a
|
||||
* "global ID" that is unique among all types.
|
||||
*/
|
||||
export function toGlobalId(type: string, id: string): string;
|
||||
|
||||
/**
|
||||
* Takes the "global ID" created by toGlobalID, and returns the type name and ID
|
||||
* used to create it.
|
||||
*/
|
||||
export function fromGlobalId(globalId: string): ResolvedGlobalId;
|
||||
|
||||
/**
|
||||
* Creates the configuration for an id field on a node, using `toGlobalId` to
|
||||
* construct the ID from the provided typename. The type-specific ID is fetched
|
||||
* by calling idFetcher on the object, or if not provided, by accessing the `id`
|
||||
* property on the object.
|
||||
*/
|
||||
export function globalIdField(
|
||||
typeName?: string,
|
||||
idFetcher?: (object: any, context: any, info: GraphQLResolveInfo) => string
|
||||
): GraphQLFieldConfig<any, any>;
|
||||
|
||||
|
||||
// node/plural.js
|
||||
|
||||
type PluralIdentifyingRootFieldConfig = {
|
||||
argName: string,
|
||||
inputType: GraphQLInputType,
|
||||
outputType: GraphQLOutputType,
|
||||
resolveSingleInput: (input: any, context: any, info: GraphQLResolveInfo) => any,
|
||||
description?: string,
|
||||
};
|
||||
|
||||
export function pluralIdentifyingRootField(
|
||||
config: PluralIdentifyingRootFieldConfig
|
||||
): GraphQLFieldConfig<any, any>;
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"noImplicitAny": true,
|
||||
"strictNullChecks": true,
|
||||
"baseUrl": "../",
|
||||
"typeRoots": [
|
||||
"../"
|
||||
],
|
||||
"types": [
|
||||
"graphql"
|
||||
],
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"graphql-relay-tests.ts"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{ "extends": "../tslint.json" }
|
||||
Reference in New Issue
Block a user