@drizzle-graphql-suite/schema 0.8.3 → 0.9.0

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/package.json CHANGED
@@ -1,24 +1,14 @@
1
1
  {
2
2
  "name": "@drizzle-graphql-suite/schema",
3
- "version": "0.8.3",
4
- "description": "GraphQL schema builder with CRUD operations, relation filtering, and hooks from Drizzle ORM",
3
+ "version": "0.9.0",
4
+ "description": "[DEPRECATED] Use @graphql-suite/schema instead. GraphQL schema builder with CRUD operations, relation filtering, and hooks from Drizzle ORM",
5
5
  "license": "MIT",
6
6
  "author": "https://github.com/dmythro",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "git+https://github.com/annexare/drizzle-graphql-suite.git",
10
- "directory": "packages/schema"
9
+ "url": "https://github.com/annexare/graphql-suite.git"
11
10
  },
12
- "homepage": "https://github.com/annexare/drizzle-graphql-suite/tree/main/packages/schema#readme",
13
- "keywords": [
14
- "drizzle",
15
- "graphql",
16
- "schema",
17
- "orm",
18
- "postgresql",
19
- "crud",
20
- "typescript"
21
- ],
11
+ "homepage": "https://graphql-suite.annexare.com",
22
12
  "type": "module",
23
13
  "publishConfig": {
24
14
  "access": "public"
@@ -32,10 +22,6 @@
32
22
  }
33
23
  },
34
24
  "dependencies": {
35
- "graphql-parse-resolve-info": "4.14.1"
36
- },
37
- "peerDependencies": {
38
- "drizzle-orm": ">=0.44.0",
39
- "graphql": ">=16.3.0"
25
+ "@graphql-suite/schema": "0.9.0"
40
26
  }
41
27
  }
package/adapters/pg.d.ts DELETED
@@ -1,10 +0,0 @@
1
- import { type Column, type SQL, type Table } from 'drizzle-orm';
2
- import { type PgDatabase } from 'drizzle-orm/pg-core';
3
- import type { DbAdapter } from './types';
4
- export declare class PgAdapter implements DbAdapter {
5
- readonly supportsReturning = true;
6
- isTable(value: unknown): boolean;
7
- executeInsert(db: PgDatabase<any, any, any>, table: Table, values: Record<string, any>[], returningColumns?: Record<string, Column>): Promise<any[]>;
8
- executeUpdate(db: PgDatabase<any, any, any>, table: Table, set: Record<string, any>, where: SQL | undefined, returningColumns?: Record<string, Column>): Promise<any[]>;
9
- executeDelete(db: PgDatabase<any, any, any>, table: Table, where: SQL | undefined, returningColumns?: Record<string, Column>): Promise<any[]>;
10
- }
@@ -1,11 +0,0 @@
1
- import type { Column, SQL, Table } from 'drizzle-orm';
2
- import type { PgDatabase } from 'drizzle-orm/pg-core';
3
- export interface DbAdapter {
4
- /** Identifies tables in the schema (e.g., is(value, PgTable)) */
5
- isTable(value: unknown): boolean;
6
- /** Whether mutations can return data (PG: yes via RETURNING, MySQL: no) */
7
- readonly supportsReturning: boolean;
8
- executeInsert(db: PgDatabase<any, any, any>, table: Table, values: Record<string, any>[], returningColumns?: Record<string, Column>): Promise<any[]>;
9
- executeUpdate(db: PgDatabase<any, any, any>, table: Table, set: Record<string, any>, where: SQL | undefined, returningColumns?: Record<string, Column>): Promise<any[]>;
10
- executeDelete(db: PgDatabase<any, any, any>, table: Table, where: SQL | undefined, returningColumns?: Record<string, Column>): Promise<any[]>;
11
- }
package/case-ops.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export declare const uncapitalize: <T extends string>(input: T) => Uncapitalize<T>;
2
- export declare const capitalize: <T extends string>(input: T) => Capitalize<T>;
package/codegen.d.ts DELETED
@@ -1,12 +0,0 @@
1
- import type { GraphQLSchema } from 'graphql';
2
- export type CodegenOptions = {
3
- drizzle?: {
4
- /** Import path for Drizzle schema types (e.g. '@ir/core/db/schema') */
5
- importPath: string;
6
- /** Override mapping: Drizzle table name → export type name (e.g. { overrideToAsset: 'OverrideAsset' }) */
7
- typeNames?: Record<string, string>;
8
- };
9
- };
10
- export declare function generateSDL(schema: GraphQLSchema): string;
11
- export declare function generateTypes(schema: GraphQLSchema, options?: CodegenOptions): string;
12
- export declare function generateEntityDefs(schema: GraphQLSchema, options?: CodegenOptions): string;
package/data-mappers.d.ts DELETED
@@ -1,12 +0,0 @@
1
- import type { Relation } from 'drizzle-orm';
2
- import { type Column, type Table } from 'drizzle-orm';
3
- export type TableNamedRelations = {
4
- relation: Relation;
5
- targetTableName: string;
6
- };
7
- export declare const remapToGraphQLCore: (key: string, value: any, tableName: string, column: Column, relationMap?: Record<string, Record<string, TableNamedRelations>>) => any;
8
- export declare const remapToGraphQLSingleOutput: (queryOutput: Record<string, any>, tableName: string, table: Table, relationMap?: Record<string, Record<string, TableNamedRelations>>) => Record<string, any>;
9
- export declare const remapToGraphQLArrayOutput: (queryOutput: Record<string, any>[], tableName: string, table: Table, relationMap?: Record<string, Record<string, TableNamedRelations>>) => Record<string, any>[];
10
- export declare const remapFromGraphQLCore: (value: any, column: Column, columnName: string) => any;
11
- export declare const remapFromGraphQLSingleInput: (queryInput: Record<string, any>, table: Table) => Record<string, any>;
12
- export declare const remapFromGraphQLArrayInput: (queryInput: Record<string, any>[], table: Table) => Record<string, any>[];
@@ -1,2 +0,0 @@
1
- import { GraphQLScalarType } from 'graphql';
2
- export declare const GraphQLJSON: GraphQLScalarType<any, unknown>;
@@ -1,7 +0,0 @@
1
- import type { Column } from 'drizzle-orm';
2
- import { GraphQLEnumType, GraphQLInputObjectType, GraphQLList, GraphQLNonNull, GraphQLObjectType, type GraphQLScalarType } from 'graphql';
3
- export type ConvertedColumn<TIsInput extends boolean = false> = {
4
- type: GraphQLScalarType | GraphQLEnumType | GraphQLNonNull<GraphQLScalarType> | GraphQLNonNull<GraphQLEnumType> | GraphQLList<GraphQLScalarType> | GraphQLList<GraphQLNonNull<GraphQLScalarType>> | GraphQLNonNull<GraphQLList<GraphQLScalarType>> | GraphQLNonNull<GraphQLList<GraphQLNonNull<GraphQLScalarType>>> | (TIsInput extends true ? GraphQLInputObjectType | GraphQLNonNull<GraphQLInputObjectType> : GraphQLObjectType | GraphQLNonNull<GraphQLObjectType>);
5
- description?: string;
6
- };
7
- export declare const drizzleColumnToGraphQLType: <TColumn extends Column, TIsInput extends boolean>(column: TColumn, columnName: string, tableName: string, forceNullable?: boolean, defaultIsNullable?: boolean, isInput?: TIsInput) => ConvertedColumn<TIsInput>;
package/permissions.d.ts DELETED
@@ -1,25 +0,0 @@
1
- import type { GraphQLFieldConfig } from 'graphql';
2
- import type { BuildSchemaConfig, PermissionConfig, TableAccess } from './types';
3
- export declare const readOnly: () => TableAccess;
4
- export declare const permissive: (id: string, tables?: Record<string, boolean | TableAccess>) => PermissionConfig;
5
- export declare const restricted: (id: string, tables?: Record<string, boolean | TableAccess>) => PermissionConfig;
6
- type MergeResult = {
7
- config: BuildSchemaConfig;
8
- /** Tables that need individual mutation entry points filtered after build */
9
- mutationFilter: Record<string, {
10
- insert: boolean;
11
- update: boolean;
12
- delete: boolean;
13
- }>;
14
- };
15
- /**
16
- * Converts a PermissionConfig into BuildSchemaConfig overrides.
17
- * Returns the merged config + a map of tables needing post-build mutation filtering.
18
- */
19
- export declare function mergePermissionsIntoConfig(baseConfig: BuildSchemaConfig, permissions: PermissionConfig, allTableNames: string[]): MergeResult;
20
- /**
21
- * Removes disallowed mutation entry points from the mutations record.
22
- * Mutates and returns the same record.
23
- */
24
- export declare function postFilterMutations(mutations: Record<string, GraphQLFieldConfig<any, any>>, mutationFilter: MergeResult['mutationFilter']): void;
25
- export {};
package/row-security.d.ts DELETED
@@ -1,21 +0,0 @@
1
- import type { HooksConfig } from './types';
2
- type RowSecurityRule = (context: any) => Record<string, unknown>;
3
- /**
4
- * Generates a HooksConfig that injects WHERE clauses from row-level security rules.
5
- * Rules are applied as `before` hooks on query, querySingle, count, update, and delete operations.
6
- *
7
- * ```ts
8
- * const hooks = withRowSecurity({
9
- * posts: (context) => ({ authorId: { eq: context.user.id } }),
10
- * })
11
- * ```
12
- */
13
- export declare function withRowSecurity(rules: Record<string, RowSecurityRule>): HooksConfig;
14
- /**
15
- * Deep-merges multiple HooksConfig objects.
16
- * - `before` hooks are chained: each runs sequentially, passing the modified args forward.
17
- * - `after` hooks are chained: each runs sequentially, passing the modified result forward.
18
- * - `resolve` hooks: last one wins (cannot be composed).
19
- */
20
- export declare function mergeHooks(...configs: (HooksConfig | undefined)[]): HooksConfig;
21
- export {};
@@ -1,72 +0,0 @@
1
- import type { Column, Relation, Table, TablesRelationalConfig } from 'drizzle-orm';
2
- import { type SQL } from 'drizzle-orm';
3
- import { type PgDatabase, PgTable } from 'drizzle-orm/pg-core';
4
- import { GraphQLSchema } from 'graphql';
5
- import type { ResolveTree } from 'graphql-parse-resolve-info';
6
- import { type TableNamedRelations } from './data-mappers';
7
- import type { BuildSchemaConfig, GeneratedEntities, PermissionConfig } from './types';
8
- export declare class SchemaBuilder {
9
- protected db: PgDatabase<any, any, any>;
10
- protected tables: Record<string, PgTable>;
11
- protected relationMap: Record<string, Record<string, TableNamedRelations>>;
12
- protected relationalSchema: TablesRelationalConfig;
13
- protected tableNamesMap: Record<string, string>;
14
- private config;
15
- private hooks;
16
- private adapter;
17
- private suffixes;
18
- private limitRelationDepth;
19
- private limitSelfRelationDepth;
20
- private allTableNames;
21
- private excludedTables;
22
- private tableOperations;
23
- private pruneRelations;
24
- private filterTypes;
25
- private orderByTypes;
26
- private filterValueTypes;
27
- private selectFieldTypes;
28
- private innerOrder;
29
- constructor(db: PgDatabase<any, any, any>, config?: BuildSchemaConfig);
30
- private toFieldMap;
31
- buildEntities(): GeneratedEntities;
32
- build(): {
33
- schema: GraphQLSchema;
34
- entities: GeneratedEntities;
35
- withPermissions: (permissions: PermissionConfig) => GraphQLSchema;
36
- clearPermissionCache: (id?: string) => void;
37
- };
38
- private logDebugInfo;
39
- private extractTables;
40
- private getTable;
41
- private buildRelationMap;
42
- private getFilterType;
43
- private getOrderByType;
44
- private getFilterValues;
45
- private getSelectFields;
46
- private generateColumnFilterValues;
47
- private generateSelectFields;
48
- private generateTableTypes;
49
- private buildRelationFilterFields;
50
- private createQueryResolver;
51
- private createSingleQueryResolver;
52
- private createCountResolver;
53
- private createInsertResolver;
54
- private createInsertSingleResolver;
55
- private createUpdateResolver;
56
- private createDeleteResolver;
57
- protected extractColumnFilters(column: Column, columnName: string, operators: any): SQL | undefined;
58
- protected extractTableColumnFilters(table: Table, tableName: string, filters: any): SQL | undefined;
59
- /** Combined filter extraction: column filters + relation filters */
60
- private extractAllFilters;
61
- protected extractRelationFilters(table: Table, tableName: string, relationName: string, filterValue: any): SQL | undefined;
62
- protected buildExistsSubquery(parentTable: Table, targetTable: Table, relation: Relation, targetTableName: string, filterValue: any, quantifier: 'some' | 'every' | 'none'): SQL | undefined;
63
- protected buildJoinCondition(parentTable: Table, _targetTable: Table, relation: Relation): SQL | undefined;
64
- protected extractOrderBy(table: Table, orderArgs: any): SQL[];
65
- protected extractColumns(tree: Record<string, ResolveTree>, table: Table): Record<string, true>;
66
- private extractColumnsSQLFormat;
67
- private getFieldsByTypeName;
68
- private extractRelationsParams;
69
- private extractRelationsParamsInner;
70
- private executeWithHooks;
71
- private executeCountQuery;
72
- }
package/types.d.ts DELETED
@@ -1,253 +0,0 @@
1
- import type { GraphQLFieldConfig, GraphQLInputObjectType, GraphQLObjectType, GraphQLResolveInfo } from 'graphql';
2
- export type GeneratedEntities = {
3
- queries: Record<string, GraphQLFieldConfig<any, any>>;
4
- mutations: Record<string, GraphQLFieldConfig<any, any>>;
5
- inputs: Record<string, GraphQLInputObjectType>;
6
- types: Record<string, GraphQLObjectType>;
7
- };
8
- export type OperationType = 'query' | 'querySingle' | 'count' | 'insert' | 'insertSingle' | 'update' | 'delete';
9
- export type HookContext = {
10
- args: any;
11
- context: any;
12
- info: GraphQLResolveInfo;
13
- };
14
- export type BeforeHookResult = {
15
- args?: any;
16
- data?: any;
17
- };
18
- export type BeforeHookFn = (ctx: HookContext) => Promise<BeforeHookResult | undefined> | BeforeHookResult | undefined;
19
- export type AfterHookContext = {
20
- result: any;
21
- beforeData: any;
22
- context: any;
23
- info: GraphQLResolveInfo;
24
- };
25
- export type AfterHookFn = (ctx: AfterHookContext) => Promise<any> | any;
26
- export type ResolveHookContext = HookContext & {
27
- defaultResolve: (overrideArgs?: any) => Promise<any>;
28
- };
29
- export type ResolveHookFn = (ctx: ResolveHookContext) => Promise<any> | any;
30
- export type OperationHooks = {
31
- before?: BeforeHookFn;
32
- after?: AfterHookFn;
33
- } | {
34
- resolve: ResolveHookFn;
35
- };
36
- export type TableHookConfig = {
37
- [K in OperationType]?: OperationHooks;
38
- };
39
- export type HooksConfig = {
40
- [tableName: string]: TableHookConfig;
41
- };
42
- export type TableAccess = {
43
- query?: boolean;
44
- insert?: boolean;
45
- update?: boolean;
46
- delete?: boolean;
47
- };
48
- export type PermissionConfig = {
49
- id: string;
50
- mode: 'permissive' | 'restricted';
51
- tables?: Record<string, boolean | TableAccess>;
52
- };
53
- export type TableOperations = {
54
- /** Generate query operations (list, single, count). @default true */
55
- queries?: boolean;
56
- /** Generate mutation operations (insert, insertSingle, update, delete). @default follows global `mutations` */
57
- mutations?: boolean;
58
- };
59
- /**
60
- * Controls how a specific relation expands in the schema.
61
- * - `false`: relation field omitted entirely from parent type
62
- * - `'leaf'`: relation expands with scalar columns only (no child relations)
63
- * - `{ only: string[] }`: relation expands with only the listed child relation fields
64
- */
65
- export type RelationPruneRule = false | 'leaf' | {
66
- only: string[];
67
- };
68
- /**
69
- * Configuration for both the GraphQL schema builder (server) and the
70
- * type-safe client. Shared across `drizzle-graphql-suite/schema` and
71
- * `drizzle-graphql-suite/client` so a single config object drives both
72
- * the runtime schema and the inferred TypeScript types.
73
- *
74
- * @example
75
- * ```ts
76
- * const config = {
77
- * mutations: true,
78
- * limitRelationDepth: 5,
79
- * limitSelfRelationDepth: 2,
80
- * suffixes: { list: 's', single: '' },
81
- * tables: { exclude: ['session', 'account'] },
82
- * pruneRelations: {
83
- * 'asset.childAssets': false,
84
- * 'override.asset': 'leaf',
85
- * 'attribute.asset': { only: ['selectedVariant'] },
86
- * },
87
- * } as const satisfies BuildSchemaConfig
88
- * ```
89
- */
90
- export type BuildSchemaConfig = {
91
- /**
92
- * Whether to generate GraphQL mutation operations (insert, update, delete).
93
- * Set to `false` for a read-only schema.
94
- * On the client side, controls whether mutation helpers are generated.
95
- * @default true
96
- */
97
- mutations?: boolean;
98
- /**
99
- * Maximum depth for expanding relation fields in the generated schema
100
- * and in client-side filter types (`InferEntityFilters`).
101
- *
102
- * - **Server**: limits how many levels of nested relations appear in
103
- * GraphQL object types. `undefined` means no limit.
104
- * - **Client**: limits recursive relation filter type expansion to
105
- * prevent TS7056 on circular schemas. Capped at 5.
106
- *
107
- * Set to `0` to omit relations altogether.
108
- *
109
- * @example
110
- * ```ts
111
- * // Allow up to 5 levels of nesting
112
- * { limitRelationDepth: 5 }
113
- * ```
114
- * @default 3 (server) / 1 (client filter types)
115
- */
116
- limitRelationDepth?: number;
117
- /**
118
- * Max occurrences of the same table via direct self-relations in a
119
- * single type path. Only applies to relations where source and target
120
- * table are identical (e.g., `asset.parent → asset`).
121
- *
122
- * - `1` = self-relation fields are omitted entirely
123
- * - `2` = one level of self-relation expansion (the nested type has
124
- * no further self-relation fields)
125
- *
126
- * Cross-table cycles that revisit a table are governed by
127
- * `limitRelationDepth` instead.
128
- *
129
- * @example
130
- * ```ts
131
- * // category.parent → category (expanded), but nested category
132
- * // won't have parent/children fields
133
- * { limitSelfRelationDepth: 2 }
134
- * ```
135
- * @default 1
136
- */
137
- limitSelfRelationDepth?: number;
138
- /**
139
- * Customizes the suffixes appended to auto-generated query names.
140
- *
141
- * Given a table named `asset`:
142
- * - List query: `asset` + `list` suffix → e.g. `"assets"` or `"assetList"`
143
- * - Single query: `asset` + `single` suffix → e.g. `"asset"` or `"assetSingle"`
144
- *
145
- * @example
146
- * ```ts
147
- * // "assets" / "asset" (pluralize list, no suffix for single)
148
- * { suffixes: { list: 's', single: '' } }
149
- *
150
- * // "assetList" / "assetSingle" (explicit suffixes)
151
- * { suffixes: { list: 'List', single: 'Single' } }
152
- * ```
153
- * @default { list: '', single: 'Single' }
154
- */
155
- suffixes?: {
156
- list?: string;
157
- single?: string;
158
- };
159
- /**
160
- * Per-table lifecycle hooks for queries and mutations.
161
- * Keys are table names as they appear in the Drizzle schema object.
162
- *
163
- * **Server-only** — hooks are executed during GraphQL resolution and have
164
- * no effect on the client package. The client imports `BuildSchemaConfig`
165
- * for type-level inference only (`limitRelationDepth`, `tables`, etc.)
166
- * and ignores `hooks` entirely.
167
- *
168
- * @example
169
- * ```ts
170
- * {
171
- * hooks: {
172
- * asset: {
173
- * query: { before: (ctx) => { ... } },
174
- * insert: { after: (ctx, result) => { ... } },
175
- * },
176
- * },
177
- * }
178
- * ```
179
- */
180
- hooks?: HooksConfig;
181
- /**
182
- * Per-table configuration: exclude tables entirely or limit which
183
- * operations are generated per table.
184
- *
185
- * Table names must match the keys in the Drizzle schema object.
186
- *
187
- * @example
188
- * ```ts
189
- * {
190
- * tables: {
191
- * // Remove auth tables from the GraphQL schema
192
- * exclude: ['session', 'account', 'verification'],
193
- * // Make 'auditLog' read-only
194
- * config: { auditLog: { queries: true, mutations: false } },
195
- * },
196
- * }
197
- * ```
198
- */
199
- tables?: {
200
- /** Tables to completely exclude (no types, no operations, relations to them skipped). */
201
- exclude?: readonly string[];
202
- /** Per-table operation overrides. Tables not listed get default behavior. */
203
- config?: Record<string, TableOperations>;
204
- };
205
- /**
206
- * Fine-grained per-relation pruning rules that control how each
207
- * relation expands in the generated schema.
208
- *
209
- * **Server-only** — pruning shapes the generated GraphQL schema.
210
- * The client builds queries from the schema descriptor, which already
211
- * reflects pruning (pruned relations are absent), so the client
212
- * cannot generate queries for pruned fields.
213
- *
214
- * Keys use `tableName.relationName` format. Values:
215
- * - `false` — relation field is omitted entirely from the parent type
216
- * - `'leaf'` — relation expands with scalar columns only (no nested relations)
217
- * - `{ only: string[] }` — relation expands with only the listed child relations
218
- *
219
- * @example
220
- * ```ts
221
- * {
222
- * pruneRelations: {
223
- * // Remove back-reference completely
224
- * 'assetType.assets': false,
225
- * // Show override.asset but don't expand its relations
226
- * 'override.asset': 'leaf',
227
- * // Only keep selectedVariant on attribute.asset
228
- * 'attribute.asset': { only: ['selectedVariant'] },
229
- * },
230
- * }
231
- * ```
232
- */
233
- pruneRelations?: Record<string, RelationPruneRule>;
234
- /**
235
- * Enable debug logging for schema diagnostics (server-side only).
236
- *
237
- * - `true` — logs SDL byte size and type count
238
- * - `{ schemaSize?: boolean; relationTree?: boolean }` — selective logging
239
- *
240
- * @example
241
- * ```ts
242
- * // Log everything
243
- * { debug: true }
244
- *
245
- * // Only log the relation expansion tree
246
- * { debug: { relationTree: true } }
247
- * ```
248
- */
249
- debug?: boolean | {
250
- schemaSize?: boolean;
251
- relationTree?: boolean;
252
- };
253
- };