@graphql-tools/mock
Version:
A set of utils for faster development of GraphQL tools
204 lines (203 loc) • 7.3 kB
text/typescript
import { GraphQLSchema } from 'graphql';
import { ExecutionResult, IResolvers } from '@graphql-tools/utils';
export type IMockFn = () => unknown;
export type IScalarMock = unknown | IMockFn;
export type ITypeMock = () => {
[fieldName: string]: unknown | IMockFn;
} | {
[fieldName: string]: IMockFn;
};
export type IMocks<TResolvers = IResolvers> = {
[TTypeName in keyof TResolvers]?: {
[TFieldName in keyof TResolvers[TTypeName]]: TResolvers[TTypeName][TFieldName] extends (args: any) => any ? () => ReturnType<TResolvers[TTypeName][TFieldName]> | ReturnType<TResolvers[TTypeName][TFieldName]> : TResolvers[TTypeName][TFieldName];
};
} & {
[typeOrScalarName: string]: IScalarMock | ITypeMock;
};
export type KeyTypeConstraints = string | number;
export type TypePolicy = {
/**
* The name of the field that should be used as store `key`.
*
* If `false`, no field will be used and `id` or `_id` will be used,
* otherwise we'll generate a random string
* as key.
*/
keyFieldName?: string | false;
};
export type GetArgs<KeyT extends KeyTypeConstraints = string> = {
typeName: string;
key?: KeyT;
fieldName?: string;
/**
* Optional arguments when querying the field.
*
* Querying the field with the same arguments will return
* the same value. Deep equality is checked.
*
* ```ts
* store.get('User', 1, 'friend', { id: 2 }) === store.get('User', 1, 'friend', { id: 2 })
* store.get('User', 1, 'friend', { id: 2 }) !== store.get('User', 1, 'friend')
* ```
*
* Args can be a record, just like `args` argument of field resolver or an
* arbitrary string.
*/
fieldArgs?: string | {
[argName: string]: any;
};
/**
* If no value found, insert the `defaultValue`.
*/
defaultValue?: unknown | {
[fieldName: string]: any;
};
};
export type SetArgs<KeyT extends KeyTypeConstraints = string> = {
typeName: string;
key: KeyT;
fieldName?: string;
/**
* Optional arguments when querying the field.
*
* @see GetArgs#fieldArgs
*/
fieldArgs?: string | {
[argName: string]: any;
};
value?: unknown | {
[fieldName: string]: any;
};
/**
* If the value for this field is already set, it won't
* be overridden.
*
* Propagates down do nested `set`.
*/
noOverride?: boolean;
};
export interface IMockStore {
schema: GraphQLSchema;
/**
* Get a field value from the store for the given type, key and field
* name — and optionally field arguments. If the field name is not given,
* a reference to the type will be returned.
*
* If the the value for this field is not set, a value will be
* generated according to field return type and mock functions.
*
* If the field's output type is a `ObjectType` (or list of `ObjectType`),
* it will return a `Ref` (or array of `Ref`), ie a reference to an entity
* in the store.
*
* Example:
* ```ts
* store.get('Query', 'ROOT', 'viewer');
* > { $ref: { key: 'abc-737dh-djdjd', typeName: 'User' } }
* store.get('User', 'abc-737dh-djdjd', 'name')
* > "Hello World"
* ```
*/
get<KeyT extends KeyTypeConstraints = string, ReturnKeyT extends KeyTypeConstraints = string>(args: GetArgs<KeyT>): unknown | Ref<ReturnKeyT>;
/**
* Shorthand for `get({typeName, key, fieldName, fieldArgs})`.
*/
get<KeyT extends KeyTypeConstraints = string, ReturnKeyT extends KeyTypeConstraints = string>(typeName: string, key: KeyT, fieldNameOrFieldNames: string | string[], fieldArgs?: string | {
[argName: string]: any;
}): unknown | Ref<ReturnKeyT>;
/**
* Get a reference to the type.
*/
get<KeyT extends KeyTypeConstraints = string>(typeName: string, keyOrDefaultValue?: KeyT | {
[fieldName: string]: any;
}, defaultValue?: {
[fieldName: string]: any;
}): unknown | Ref<KeyT>;
/**
* Shorthand for `get({typeName: ref.$ref.typeName, key: ref.$ref.key, fieldName, fieldArgs})`
* @param ref
* @param fieldNameOrFieldNames
* @param fieldArgs
*/
get<KeyT extends KeyTypeConstraints = string, ReturnKeyT extends KeyTypeConstraints = string>(ref: Ref<KeyT>, fieldNameOrFieldNames: string | string[], fieldArgs?: string | {
[argName: string]: any;
}): unknown | Ref<ReturnKeyT>;
/**
* Set a field value in the store for the given type, key and field
* name — and optionally field arguments.
*
* If the the field return type is an `ObjectType` or a list of
* `ObjectType`, you can set references to other entity as value:
*
* ```ts
* // set the viewer name
* store.set('User', 1, 'name', 'Alexandre);
* store.set('Query', 'ROOT', 'viewer', store.get('User', 1));
*
* // set the friends of viewer
* store.set('User', 2, 'name', 'Emily');
* store.set('User', 3, 'name', 'Caroline');
* store.set('User', 1, 'friends', [store.get('User', 2), store.get('User', 3)]);
* ```
*
* But it also supports nested set:
*
* ```ts
* store.set('Query', 'ROOT', 'viewer', {
* name: 'Alexandre',
* friends: [
* { name: 'Emily' }
* { name: 'Caroline }
* ]
* });
* ```
*/
set<KeyT extends KeyTypeConstraints = string>(args: SetArgs<KeyT>): void;
/**
* Shorthand for `set({typeName, key, fieldName, value})`.
*/
set<KeyT extends KeyTypeConstraints = string>(typeName: string, key: KeyT, fieldName: string, value?: unknown): void;
/**
* Set the given field values to the type with key.
*/
set<KeyT extends KeyTypeConstraints = string>(typeName: string, key: KeyT, values: {
[fieldName: string]: any;
}): void;
/**
* Shorthand for `set({ref.$ref.typeName, ref.$ref.key, fieldName, value})`.
*/
set<KeyT extends KeyTypeConstraints = string>(ref: Ref<KeyT>, fieldName: string, value?: unknown): void;
/**
* Set the given field values to the type with ref.
*/
set<KeyT extends KeyTypeConstraints = string>(ref: Ref<KeyT>, values: {
[fieldName: string]: any;
}): void;
/**
* Checks if a mock is present in the store for the given typeName and key.
*/
has<KeyT extends KeyTypeConstraints = string>(typeName: string, key: KeyT): boolean;
/**
* Resets the mock store
*/
reset(): void;
}
export type Ref<KeyT extends KeyTypeConstraints = string> = {
$ref: {
key: KeyT;
typeName: string;
};
};
export declare function isRef<KeyT extends KeyTypeConstraints = string>(maybeRef: unknown): maybeRef is Ref<KeyT>;
export declare function assertIsRef<KeyT extends KeyTypeConstraints = string>(maybeRef: unknown, message?: string): asserts maybeRef is Ref<KeyT>;
export declare function isRecord(obj: unknown): obj is {
[key: string]: unknown;
};
export interface IMockServer {
/**
* Executes the provided query against the mocked schema.
* @param query GraphQL query to execute
* @param vars Variables
*/
query: (query: string, vars?: Record<string, any>) => Promise<ExecutionResult>;
}