@drizzle-graphql-suite/client 0.8.1 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client.d.ts +3 -3
- package/index.d.ts +1 -1
- package/index.js +2 -2
- package/infer.d.ts +12 -7
- package/package.json +2 -1
- package/schema-builder.d.ts +2 -14
package/client.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { BuildSchemaConfig } from '@drizzle-graphql-suite/schema';
|
|
1
2
|
import { type EntityClient } from './entity';
|
|
2
3
|
import type { InferEntityDefs } from './infer';
|
|
3
|
-
import { type ClientSchemaConfig } from './schema-builder';
|
|
4
4
|
import type { AnyEntityDefs, ClientConfig, SchemaDescriptor } from './types';
|
|
5
5
|
export declare class GraphQLClient<TSchema extends SchemaDescriptor, TDefs extends AnyEntityDefs = AnyEntityDefs> {
|
|
6
6
|
private url;
|
|
@@ -10,10 +10,10 @@ export declare class GraphQLClient<TSchema extends SchemaDescriptor, TDefs exten
|
|
|
10
10
|
entity<TEntityName extends string & keyof TSchema & keyof TDefs>(entityName: TEntityName): EntityClient<TDefs, TDefs[TEntityName]>;
|
|
11
11
|
execute(query: string, variables?: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
12
12
|
}
|
|
13
|
-
export type DrizzleClientConfig<TSchema extends Record<string, unknown>, TConfig extends
|
|
13
|
+
export type DrizzleClientConfig<TSchema extends Record<string, unknown>, TConfig extends BuildSchemaConfig> = {
|
|
14
14
|
schema: TSchema;
|
|
15
15
|
config: TConfig;
|
|
16
16
|
url: string | (() => string);
|
|
17
17
|
headers?: HeadersInit | (() => HeadersInit | Promise<HeadersInit>);
|
|
18
18
|
};
|
|
19
|
-
export declare function createDrizzleClient<TSchema extends Record<string, unknown>, const TConfig extends
|
|
19
|
+
export declare function createDrizzleClient<TSchema extends Record<string, unknown>, const TConfig extends BuildSchemaConfig>(options: DrizzleClientConfig<TSchema, TConfig>): GraphQLClient<SchemaDescriptor, InferEntityDefs<TSchema, TConfig>>;
|
package/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { GraphQLClient } from './client';
|
|
2
2
|
import type { AnyEntityDefs, ClientConfig, SchemaDescriptor } from './types';
|
|
3
3
|
export declare function createClient<TSchema extends SchemaDescriptor, TDefs extends AnyEntityDefs = AnyEntityDefs>(config: ClientConfig<TSchema>): GraphQLClient<TSchema, TDefs>;
|
|
4
|
+
export type { BuildSchemaConfig } from '@drizzle-graphql-suite/schema';
|
|
4
5
|
export type { DrizzleClientConfig } from './client';
|
|
5
6
|
export { createDrizzleClient, GraphQLClient } from './client';
|
|
6
7
|
export type { EntityClient } from './entity';
|
|
7
8
|
export { GraphQLClientError, NetworkError } from './errors';
|
|
8
9
|
export type { InferEntityDefs } from './infer';
|
|
9
|
-
export type { ClientSchemaConfig } from './schema-builder';
|
|
10
10
|
export { buildSchemaDescriptor } from './schema-builder';
|
|
11
11
|
export type { AnyEntityDefs, ClientConfig, EntityDef, EntityDescriptor, InferResult, SchemaDescriptor, SelectInput, } from './types';
|
package/index.js
CHANGED
|
@@ -9,7 +9,7 @@ ${U}
|
|
|
9
9
|
}
|
|
10
10
|
}`,variables:{},operationName:Z}}function b(E,x,$){let Y=x.countName;if(!Y)throw Error(`Entity '${E}' has no count query`);let J=L(E),C=`${j(Y)}Query`,H=[],R=[];if($)H.push(`$where: ${J}`),R.push("where: $where");let X=H.length?`(${H.join(", ")})`:"",A=R.length?`(${R.join(", ")})`:"";return{query:`query ${C}${X} {
|
|
11
11
|
${Y}${A}
|
|
12
|
-
}`,variables:{},operationName:C}}function
|
|
12
|
+
}`,variables:{},operationName:C}}function Q(E,x,$,Y,J){let C=J?x.insertSingleName:x.insertName;if(!C)throw Error(`Entity '${E}' has no ${J?"insertSingle":"insert"} mutation`);let H=p(E),R=`${j(C)}Mutation`,A=`($values: ${J?`${H}!`:`[${H}!]!`})`,Z="(values: $values)",_="";if(Y)_=` {
|
|
13
13
|
${G(Y,$,x)}
|
|
14
14
|
}`;return{query:`mutation ${R}${A} {
|
|
15
15
|
${C}${Z}${_}
|
|
@@ -21,4 +21,4 @@ ${G(Y,$,x)}
|
|
|
21
21
|
${G(Y,$,x)}
|
|
22
22
|
}`;return{query:`mutation ${R}${Z} {
|
|
23
23
|
${C}${_}${V}
|
|
24
|
-
}`,variables:{},operationName:R}}function
|
|
24
|
+
}`,variables:{},operationName:R}}function h(E,x,$,Y){return{async query(J){let{select:C,where:H,limit:R,offset:X,orderBy:A}=J,Z=T(E,x,$,C,H!=null,A!=null,R!=null,X!=null),_={};if(H!=null)_.where=H;if(A!=null)_.orderBy=A;if(R!=null)_.limit=R;if(X!=null)_.offset=X;return(await Y(Z.query,_))[x.queryListName]},async querySingle(J){let{select:C,where:H,offset:R,orderBy:X}=J,A=d(E,x,$,C,H!=null,X!=null,R!=null),Z={};if(H!=null)Z.where=H;if(X!=null)Z.orderBy=X;if(R!=null)Z.offset=R;return(await Y(A.query,Z))[x.queryName]??null},async count(J){let C=J?.where,H=b(E,x,C!=null),R={};if(C!=null)R.where=C;return(await Y(H.query,R))[x.countName]},async insert(J){let{values:C,returning:H}=J,R=Q(E,x,$,H,!1),X={values:C};return(await Y(R.query,X))[x.insertName]},async insertSingle(J){let{values:C,returning:H}=J,R=Q(E,x,$,H,!0),X={values:C};return(await Y(R.query,X))[x.insertSingleName]??null},async update(J){let{set:C,where:H,returning:R}=J,X=v(E,x,$,R,H!=null),A={set:C};if(H!=null)A.where=H;return(await Y(X.query,A))[x.updateName]},async delete(J){let{where:C,returning:H}=J,R=g(E,x,$,H,C!=null),X={};if(C!=null)X.where=C;return(await Y(R.query,X))[x.deleteName]}}}class K extends Error{errors;status;constructor(E,x=200){let $=E.map((Y)=>Y.message).join("; ");super($);this.name="GraphQLClientError",this.errors=E,this.status=x}}class W extends Error{status;constructor(E,x){super(E);this.name="NetworkError",this.status=x}}import{getTableColumns as f,getTableName as D,is as w,Many as N,One as u,Relations as m,Table as l}from"drizzle-orm";var z=(E)=>E.charAt(0).toUpperCase()+E.slice(1);function k(E,x={}){let $=new Set(x.tables?.exclude??[]),Y=x.suffixes?.list??"s",J=new Map,C=new Map;for(let[A,Z]of Object.entries(E))if(w(Z,l)){if($.has(A))continue;let _=D(Z),V=Object.keys(f(Z));J.set(A,{table:Z,dbName:_,columns:V}),C.set(_,A)}let H=new Map;for(let A of Object.values(E)){if(!w(A,m))continue;let Z=D(A.table),_=C.get(Z);if(!_||!J.has(_))continue;let V={one:(U,F)=>{return new u(A.table,U,F,!1)},many:(U,F)=>{return new N(A.table,U,F)}},I=A.config(V),q={};for(let[U,F]of Object.entries(I)){let O=F,P=O.referencedTableName;if(!P)continue;let B=C.get(P);if(!B)continue;let o=w(O,u)?"one":"many";q[U]={entity:B,type:o}}H.set(_,q)}let R=x.pruneRelations??{};for(let[A,Z]of H)for(let _ of Object.keys(Z)){let V=`${A}.${_}`;if(R[V]===!1)delete Z[_]}let X={};for(let[A,{columns:Z}]of J){let _=H.get(A)??{};X[A]={queryName:A,queryListName:`${A}${Y}`,countName:`${A}Count`,insertName:`insertInto${z(A)}`,insertSingleName:`insertInto${z(A)}Single`,updateName:`update${z(A)}`,deleteName:`deleteFrom${z(A)}`,fields:Z,relations:_}}return X}class M{url;schema;headers;constructor(E){this.url=E.url,this.schema=E.schema,this.headers=E.headers}entity(E){let x=this.schema[E];if(!x)throw Error(`Entity '${E}' not found in schema`);return h(E,x,this.schema,($,Y)=>this.execute($,Y))}async execute(E,x={}){let $=typeof this.url==="function"?this.url():this.url,Y={"Content-Type":"application/json",...typeof this.headers==="function"?await this.headers():this.headers??{}},J;try{J=await fetch($,{method:"POST",headers:Y,body:JSON.stringify({query:E,variables:x})})}catch(H){throw new W(H instanceof Error?H.message:"Network request failed",0)}if(!J.ok)throw new W(`HTTP ${J.status}: ${J.statusText}`,J.status);let C=await J.json();if(C.errors?.length)throw new K(C.errors,J.status);if(!C.data)throw new K([{message:"No data in response"}],J.status);return C.data}}function y(E){let x=k(E.schema,E.config);return new M({url:E.url,schema:x,headers:E.headers})}function HE(E){return new M(E)}export{y as createDrizzleClient,HE as createClient,k as buildSchemaDescriptor,W as NetworkError,K as GraphQLClientError,M as GraphQLClient};
|
package/infer.d.ts
CHANGED
|
@@ -47,14 +47,15 @@ type ManyRelationFilter<TFilter> = {
|
|
|
47
47
|
type IsResolvableRelation<TSchema, TRel> = TRel extends {
|
|
48
48
|
entity: infer E;
|
|
49
49
|
} ? E extends string ? KeyForDbName<TSchema, E> extends keyof ExtractTables<TSchema> ? true : false : false : false;
|
|
50
|
-
type
|
|
50
|
+
type Prev<T extends unknown[]> = T extends [unknown, ...infer Rest] ? Rest : [];
|
|
51
|
+
type InferRelationFilterFields<TSchema, TRels, TDepth extends unknown[]> = {
|
|
51
52
|
[K in keyof TRels as IsResolvableRelation<TSchema, TRels[K]> extends true ? K : never]?: TRels[K] extends {
|
|
52
53
|
entity: infer E;
|
|
53
54
|
type: infer TRelType;
|
|
54
|
-
} ? E extends string ? KeyForDbName<TSchema, E> extends infer RK ? RK extends keyof ExtractTables<TSchema> ? ExtractTables<TSchema>[RK] extends infer TTarget ? TTarget extends Table ? TRelType extends 'many' ? ManyRelationFilter<InferEntityFilters<TSchema, TTarget
|
|
55
|
+
} ? E extends string ? KeyForDbName<TSchema, E> extends infer RK ? RK extends keyof ExtractTables<TSchema> ? ExtractTables<TSchema>[RK] extends infer TTarget ? TTarget extends Table ? TRelType extends 'many' ? ManyRelationFilter<InferEntityFilters<TSchema, TTarget, Prev<TDepth>>> : InferEntityFilters<TSchema, TTarget, Prev<TDepth>> : never : never : never : never : never : never;
|
|
55
56
|
};
|
|
56
|
-
type InferEntityFilters<TSchema, T extends Table> = ScalarColumnFilters<WireFormat<T['$inferSelect']>> & InferRelationFilterFields<TSchema, InferRelationDefs<TSchema, TableDbName<T
|
|
57
|
-
OR?: InferEntityFilters<TSchema, T>[];
|
|
57
|
+
type InferEntityFilters<TSchema, T extends Table, TDepth extends unknown[] = [0]> = ScalarColumnFilters<WireFormat<T['$inferSelect']>> & (TDepth extends [] ? {} : InferRelationFilterFields<TSchema, InferRelationDefs<TSchema, TableDbName<T>>, TDepth>) & {
|
|
58
|
+
OR?: InferEntityFilters<TSchema, T, TDepth>[];
|
|
58
59
|
};
|
|
59
60
|
type InferInsertInput<T> = T extends Table ? WireFormat<T['$inferInsert']> : never;
|
|
60
61
|
type InferUpdateInput<T> = T extends Table ? {
|
|
@@ -71,6 +72,10 @@ type ExcludedNames<TConfig> = TConfig extends {
|
|
|
71
72
|
exclude: readonly (infer T)[];
|
|
72
73
|
};
|
|
73
74
|
} ? T : never;
|
|
75
|
+
type NumberToTuple<N extends number, T extends unknown[] = []> = T['length'] extends N ? T : T['length'] extends 5 ? T : NumberToTuple<N, [...T, 0]>;
|
|
76
|
+
type ExtractFilterDepth<TConfig> = TConfig extends {
|
|
77
|
+
limitRelationDepth: infer D;
|
|
78
|
+
} ? D extends number ? number extends D ? [0] : NumberToTuple<D> : [0] : [0];
|
|
74
79
|
type TableDbName<T> = T extends Table<infer TConfig> ? TConfig['name'] extends string ? TConfig['name'] : string : string;
|
|
75
80
|
type DbNameToKey<TSchema> = {
|
|
76
81
|
[K in keyof ExtractTables<TSchema>]: TableDbName<ExtractTables<TSchema>[K]>;
|
|
@@ -88,15 +93,15 @@ type ResolveRelationDefs<TSchema, TRels> = {
|
|
|
88
93
|
type: T;
|
|
89
94
|
} : TRels[K] : TRels[K];
|
|
90
95
|
};
|
|
91
|
-
type BuildEntityDef<TSchema, T> = T extends Table ? {
|
|
96
|
+
type BuildEntityDef<TSchema, T, TDepth extends unknown[]> = T extends Table ? {
|
|
92
97
|
fields: WireFormat<T['$inferSelect']>;
|
|
93
98
|
relations: ResolveRelationDefs<TSchema, InferRelationDefs<TSchema, TableDbName<T>>>;
|
|
94
|
-
filters: InferEntityFilters<TSchema, T>;
|
|
99
|
+
filters: InferEntityFilters<TSchema, T, TDepth>;
|
|
95
100
|
insertInput: InferInsertInput<T>;
|
|
96
101
|
updateInput: InferUpdateInput<T>;
|
|
97
102
|
orderBy: InferOrderBy<T>;
|
|
98
103
|
} : never;
|
|
99
104
|
export type InferEntityDefs<TSchema, TConfig = Record<string, never>> = {
|
|
100
|
-
[K in keyof ExtractTables<TSchema> as K extends ExcludedNames<TConfig> ? never : K extends string ? K : never]: BuildEntityDef<TSchema, ExtractTables<TSchema>[K]
|
|
105
|
+
[K in keyof ExtractTables<TSchema> as K extends ExcludedNames<TConfig> ? never : K extends string ? K : never]: BuildEntityDef<TSchema, ExtractTables<TSchema>[K], ExtractFilterDepth<TConfig>>;
|
|
101
106
|
};
|
|
102
107
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drizzle-graphql-suite/client",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "Type-safe GraphQL client with entity-based API and full Drizzle type inference",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "https://github.com/dmythro",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
|
+
"@drizzle-graphql-suite/schema": ">=0.8.0",
|
|
35
36
|
"drizzle-orm": ">=0.44.0"
|
|
36
37
|
}
|
|
37
38
|
}
|
package/schema-builder.d.ts
CHANGED
|
@@ -1,15 +1,3 @@
|
|
|
1
|
+
import type { BuildSchemaConfig } from '@drizzle-graphql-suite/schema';
|
|
1
2
|
import type { SchemaDescriptor } from './types';
|
|
2
|
-
export
|
|
3
|
-
mutations?: boolean;
|
|
4
|
-
suffixes?: {
|
|
5
|
-
list?: string;
|
|
6
|
-
single?: string;
|
|
7
|
-
};
|
|
8
|
-
tables?: {
|
|
9
|
-
exclude?: readonly string[];
|
|
10
|
-
};
|
|
11
|
-
pruneRelations?: Record<string, false | 'leaf' | {
|
|
12
|
-
only: string[];
|
|
13
|
-
}>;
|
|
14
|
-
};
|
|
15
|
-
export declare function buildSchemaDescriptor(schema: Record<string, unknown>, config?: ClientSchemaConfig): SchemaDescriptor;
|
|
3
|
+
export declare function buildSchemaDescriptor(schema: Record<string, unknown>, config?: BuildSchemaConfig): SchemaDescriptor;
|