@incubrain/client
Version:
A type-safe GraphQL client for Hasura, optimized for Node.js and Nuxt environments with full TypeScript support.
173 lines (172 loc) • 4.98 kB
TypeScript
import type { Logger } from "@incubrain/logger";
import { BaseClient } from "./base.client.js";
import type { Client } from "urql";
import type { DocumentNode } from "graphql";
export type Primitive = string | number | boolean | null;
export type DeepPartial<T> = {
[P in keyof T]?: T[P] extends Primitive ? T[P] : T[P] extends Array<infer U> ? Array<DeepPartial<U>> : T[P] extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>> : DeepPartial<T[P]>;
};
export interface ClientConfig {
endpoint: string;
headers?: Record<string, string>;
exchanges?: any[];
plugins?: ClientPlugin[];
logger?: Logger;
defaultPluginOptions?: DefaultPluginOptions;
}
export interface DefaultPluginOptions {
retry?: RetryPluginConfig;
cache?: CachePluginConfig;
logging?: LoggingPluginConfig;
}
export interface ClientPlugin {
name: string;
onInit?: (client: BaseClient) => Promise<void> | void;
beforeRequest?: (requestConfig: RequestConfig) => Promise<RequestConfig> | RequestConfig;
afterRequest?: (response: any, requestConfig: RequestConfig) => Promise<any> | any;
onError?: (error: Error, requestConfig: RequestConfig) => Promise<any> | void;
extends?: Record<string, Function>;
}
export interface RetryPluginConfig {
enabled?: boolean;
maxRetries?: number;
retryDelay?: number;
retryOnNetworkError?: boolean;
retryOnTimeout?: boolean;
retryableStatusCodes?: number[];
}
export interface CachePluginConfig {
enabled?: boolean;
ttl?: number;
exclude?: string[];
maxSize?: number;
invalidateOnMutation?: boolean;
}
export interface LoggingPluginConfig {
enabled?: boolean;
logLevel?: "debug" | "info" | "warn" | "error";
logRequests?: boolean;
logResponses?: boolean;
logErrors?: boolean;
maskHeaders?: string[];
}
export interface Operation {
key: string;
document: DocumentNode;
}
export interface RequestConfig {
operation: Operation;
variables?: Record<string, any>;
context?: Record<string, any>;
client: Client;
}
export interface EntityField {
type: string;
nullable: boolean;
list: boolean;
}
export interface EntityFields {
[fieldName: string]: EntityField;
}
export interface Entity {
name: string;
fields: EntityFields;
}
export interface WhereInput {
[key: string]: any;
}
export interface WhereUniqueInput {
id?: string | number;
[key: string]: any;
}
export interface OrderByInput {
[key: string]: "asc" | "desc";
}
export type SelectionMap<T> = {
[K in keyof T]?: boolean | SelectionMap<T[K]>;
};
export type IncludeMap<T> = {
[K in keyof T]?: boolean | {
select?: SelectionMap<T[K]>;
};
};
type WhereCondition<T> = {
[P in keyof T]?: T[P] extends (infer U)[] ? WhereCondition<U> | {
_in: U[];
} : T[P] extends object ? WhereCondition<T[P]> : {
_eq?: T[P];
_neq?: T[P];
_in?: T[P][];
_nin?: T[P][];
_gt?: T[P];
_gte?: T[P];
_lt?: T[P];
_lte?: T[P];
_like?: T[P] extends string ? string : never;
_ilike?: T[P] extends string ? string : never;
};
};
type WhereConditionWithLogicalOperators<T> = WhereCondition<T> & {
AND?: WhereCondition<T>[];
OR?: WhereCondition<T>[];
};
export interface FindManyArgs<TEntity> {
where?: WhereConditionWithLogicalOperators<TEntity>;
orderBy?: Record<keyof TEntity, "asc" | "desc">;
take?: number;
skip?: number;
select?: SelectionMap<TEntity>;
include?: IncludeMap<TEntity>;
options?: QueryOptions;
}
export interface CreateArgs<TData, TEntity> {
data: TData;
select?: SelectionMap<TEntity>;
include?: IncludeMap<TEntity>;
options?: QueryOptions;
}
export interface UpdateArgs<TData, TEntity> {
where: WhereUniqueInput;
data: Partial<TData>;
select?: SelectionMap<TEntity>;
include?: IncludeMap<TEntity>;
options?: QueryOptions;
}
export interface DeleteArgs<TEntity, TSelect> {
where: WhereUniqueInput;
select?: SelectionMap<TEntity>;
include?: IncludeMap<TEntity>;
options?: QueryOptions;
}
export interface QueryOptions {
cache?: boolean;
cacheTTL?: number;
variables?: Record<string, any>;
}
export type FieldSelection<T> = {
[K in keyof T]?: boolean | FieldSelection<T[K]>;
};
type WhereUnique = {
id: string | number;
} | {
[key: string]: string | number;
};
export interface FindUniqueArgs<TEntity> {
where: WhereUnique;
select?: FieldSelection<TEntity>;
include?: Record<string, boolean>;
options?: QueryOptions;
}
export interface ClientConfig {
url: string;
fetchOptions?: RequestInit;
logger?: Logger;
}
export interface RelationField<T> {
select?: SelectionMap<T>;
include?: IncludeMap<T>;
}
export type WithRelations<T> = {
[K in keyof T]: T[K] extends Array<infer U> ? Array<WithRelations<U>> : T[K] extends object ? WithRelations<T[K]> : T[K];
};
export {};