@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 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 ClientSchemaConfig> = {
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 ClientSchemaConfig>(options: DrizzleClientConfig<TSchema, TConfig>): GraphQLClient<SchemaDescriptor, InferEntityDefs<TSchema, TConfig>>;
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 w(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)_=` {
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 D(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=w(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=w(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 h,is as z,Many as N,One as u,Relations as m,Table as l}from"drizzle-orm";var O=(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(z(Z,l)){if($.has(A))continue;let _=h(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(!z(A,m))continue;let Z=h(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 Q=F,P=Q.referencedTableName;if(!P)continue;let B=C.get(P);if(!B)continue;let o=z(Q,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${O(A)}`,insertSingleName:`insertInto${O(A)}Single`,updateName:`update${O(A)}`,deleteName:`deleteFrom${O(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 D(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};
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 InferRelationFilterFields<TSchema, TRels> = {
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>> : InferEntityFilters<TSchema, TTarget> : never : never : never : never : never : never;
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.1",
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
  }
@@ -1,15 +1,3 @@
1
+ import type { BuildSchemaConfig } from '@drizzle-graphql-suite/schema';
1
2
  import type { SchemaDescriptor } from './types';
2
- export type ClientSchemaConfig = {
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;