@dav3/gql-of-power 1.0.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.
Files changed (70) hide show
  1. package/.prettierrc +7 -0
  2. package/LICENSE +26 -0
  3. package/README.md +426 -0
  4. package/bunfig.toml +17 -0
  5. package/dist/src/entities/gql-entity.d.ts +39 -0
  6. package/dist/src/entities/gql-entity.js +381 -0
  7. package/dist/src/entities/index.d.ts +1 -0
  8. package/dist/src/entities/index.js +1 -0
  9. package/dist/src/index.d.ts +5 -0
  10. package/dist/src/index.js +5 -0
  11. package/dist/src/operations.d.ts +116 -0
  12. package/dist/src/operations.js +81 -0
  13. package/dist/src/queries/alias.d.ts +25 -0
  14. package/dist/src/queries/alias.js +66 -0
  15. package/dist/src/queries/filter-processor.d.ts +141 -0
  16. package/dist/src/queries/filter-processor.js +574 -0
  17. package/dist/src/queries/gql-to-sql-mapper.d.ts +44 -0
  18. package/dist/src/queries/gql-to-sql-mapper.js +309 -0
  19. package/dist/src/queries/index.d.ts +2 -0
  20. package/dist/src/queries/index.js +2 -0
  21. package/dist/src/queries/relationship-handler.d.ts +19 -0
  22. package/dist/src/queries/relationship-handler.js +144 -0
  23. package/dist/src/queries/sql-builder.d.ts +115 -0
  24. package/dist/src/queries/sql-builder.js +179 -0
  25. package/dist/src/queries/utils.d.ts +7 -0
  26. package/dist/src/queries/utils.js +58 -0
  27. package/dist/src/query-manager.d.ts +18 -0
  28. package/dist/src/query-manager.js +99 -0
  29. package/dist/src/types/access-control.d.ts +27 -0
  30. package/dist/src/types/access-control.js +7 -0
  31. package/dist/src/types/gql-to-sql-types.d.ts +27 -0
  32. package/dist/src/types/gql-to-sql-types.js +18 -0
  33. package/dist/src/types/gql-types.d.ts +86 -0
  34. package/dist/src/types/gql-types.js +102 -0
  35. package/dist/src/types/index.d.ts +4 -0
  36. package/dist/src/types/index.js +4 -0
  37. package/dist/src/types/sql-types.d.ts +135 -0
  38. package/dist/src/types/sql-types.js +12 -0
  39. package/dist/src/types/utils.d.ts +12 -0
  40. package/dist/src/types/utils.js +1 -0
  41. package/dist/src/utils/index.d.ts +1 -0
  42. package/dist/src/utils/index.js +1 -0
  43. package/dist/src/utils/object.d.ts +1 -0
  44. package/dist/src/utils/object.js +1 -0
  45. package/dist/src/variables.d.ts +2 -0
  46. package/dist/src/variables.js +77 -0
  47. package/jest.config.js +11 -0
  48. package/package.json +48 -0
  49. package/scripts/update-version.ts +19 -0
  50. package/src/entities/gql-entity.ts +472 -0
  51. package/src/entities/index.ts +1 -0
  52. package/src/index.ts +5 -0
  53. package/src/operations.ts +131 -0
  54. package/src/queries/alias.ts +70 -0
  55. package/src/queries/filter-processor.ts +1156 -0
  56. package/src/queries/gql-to-sql-mapper.ts +644 -0
  57. package/src/queries/index.ts +2 -0
  58. package/src/queries/relationship-handler.ts +354 -0
  59. package/src/queries/sql-builder.ts +282 -0
  60. package/src/queries/utils.ts +95 -0
  61. package/src/query-manager.ts +129 -0
  62. package/src/types/access-control.ts +35 -0
  63. package/src/types/gql-to-sql-types.ts +51 -0
  64. package/src/types/gql-types.ts +251 -0
  65. package/src/types/index.ts +4 -0
  66. package/src/types/sql-types.ts +204 -0
  67. package/src/types/utils.ts +27 -0
  68. package/src/utils/index.ts +1 -0
  69. package/src/utils/object.ts +2 -0
  70. package/src/variables.ts +81 -0
package/.prettierrc ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "useTabs": true,
3
+ "printWidth": 100,
4
+ "semi": true,
5
+ "singleQuote": true,
6
+ "trailingComma": "es5"
7
+ }
package/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ MIT NON-AI License
2
+
3
+ Copyright (c) 2023, <copyright holders>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of the software and associated documentation files (the "Software"),
6
+ to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
7
+ and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions.
8
+
9
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
+
11
+ In addition, the following restrictions apply:
12
+
13
+ 1. The Software and any modifications made to it may not be used for the purpose of training or improving machine learning algorithms,
14
+ including but not limited to artificial intelligence, natural language processing, or data mining. This condition applies to any derivatives,
15
+ modifications, or updates based on the Software code. Any usage of the Software in an AI-training dataset is considered a breach of this License.
16
+
17
+ 2. The Software may not be included in any dataset used for training or improving machine learning algorithms,
18
+ including but not limited to artificial intelligence, natural language processing, or data mining.
19
+
20
+ 3. Any person or organization found to be in violation of these restrictions will be subject to legal action and may be held liable
21
+ for any damages resulting from such use.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
25
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
26
+ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,426 @@
1
+ # ⚔️ GQL of Power
2
+
3
+ > **"One Query to Rule Them All"** — Master your data with the power of a single GraphQL query
4
+
5
+ ---
6
+
7
+ ## The Ring Bearer's Tale
8
+
9
+ In the age of microservices and data loaders, a shadow falls upon performance: _the N+1 query problem_. Weary developers traverse the lands of Middleware-earth, orchestrating countless queries to fetch interconnected data.
10
+
11
+ But what if there was another way? What if, with the power of a single query, you could bind all your data together?
12
+
13
+ **GQL of Power** is a TypeScript library that harnesses ancient sorcery to generate perfectly optimized SQL queries from your GraphQL operations. It eliminates the need for data loaders entirely—one query to fetch your complete data structure, no matter how deeply nested your relationships run.
14
+
15
+ Like the One Ring wielding dominion over all other Rings, GQL of Power commands your database with singular authority.
16
+
17
+ ---
18
+
19
+ ## Features
20
+
21
+ ### 🗡️ Query Unification
22
+
23
+ Generate a **single, optimized SQL query** from any GraphQL query structure—no matter how complex your relationships are.
24
+
25
+ - ✨ **Eliminate Data Loaders** – Replace the tedious choreography of multiple queries with one powerful statement
26
+ - 🏰 **Intelligent Relationship Handling** – Navigate 1:1, 1:m, m:1, and m:m relationships seamlessly
27
+ - 🔍 **Comprehensive Filtering** – Filter at any level of your nested query tree
28
+ - 📄 **Type-Safe Operations** – Full TypeScript support ensures your queries are error-free
29
+ - ⚡ **Performance Optimized** – UNION ALL for OR conditions, efficient JSONB aggregation, and strategic aliasing
30
+
31
+ ### 🧙 Core Powers
32
+
33
+ - **Recursive Query Mapping** – Transforms GraphQL field selections into SQL recursively
34
+ - **Automatic Join Generation** – Intelligently creates JOINs based on ORM entity relationships
35
+ - **Dynamic Filtering** – Support for field-level and class-level filter operations (`_eq`, `_in`, `_like`, `_gt`, `_and`, `_or`, etc.)
36
+ - **Pagination Support** – Native limit and offset handling through generated input types
37
+ - **Custom Fields** – Extend entities with computed properties, DataLoaders, and business logic
38
+ - **Framework Agnostic** – Works with any ORM through a simple MetadataProvider interface
39
+
40
+ ---
41
+
42
+ ## Installation
43
+
44
+ ```bash
45
+ # Using pnpm (recommended)
46
+ pnpm add @dav3/gql-of-power
47
+
48
+ # Using npm
49
+ npm install @dav3/gql-of-power
50
+
51
+ # Using yarn
52
+ yarn add @dav3/gql-of-power
53
+ ```
54
+
55
+ ---
56
+
57
+ ## Quick Start
58
+
59
+ ### 1. Define Your Entities
60
+
61
+ ```typescript
62
+ import { GQLEntity } from '@dav3/gql-of-power';
63
+ import { ObjectType, Field, Int } from 'type-graphql';
64
+
65
+ @ObjectType()
66
+ export class Author extends GQLEntity {
67
+ @Field(() => Int)
68
+ id: number;
69
+
70
+ @Field()
71
+ name: string;
72
+
73
+ @Field(() => [Book])
74
+ books: Book[];
75
+ }
76
+
77
+ @ObjectType()
78
+ export class Book extends GQLEntity {
79
+ @Field(() => Int)
80
+ id: number;
81
+
82
+ @Field()
83
+ title: string;
84
+
85
+ @Field()
86
+ publicationYear: number;
87
+
88
+ @Field(() => Author)
89
+ author: Author;
90
+ }
91
+ ```
92
+
93
+ ### 2. Configure Metadata
94
+
95
+ Provide ORM metadata that tells GQL of Power about your tables, columns, and relationships:
96
+
97
+ ```typescript
98
+ const metadataProvider = {
99
+ getEntityMetadata: (entity) => ({
100
+ tableName: 'authors',
101
+ primaryKey: 'id',
102
+ fields: {
103
+ id: { columnName: 'id' },
104
+ name: { columnName: 'name' },
105
+ },
106
+ }),
107
+ // ... implement for all entities
108
+ };
109
+ ```
110
+
111
+ ### 3. Execute Your Query
112
+
113
+ ```typescript
114
+ import { QueryManager } from '@dav3/gql-of-power';
115
+
116
+ const queryManager = new QueryManager(metadataProvider, knexInstance);
117
+
118
+ // Execute a complex query with a single SQL statement
119
+ const result = await queryManager.execute(
120
+ Author,
121
+ gqlInfo, // GraphQL resolve info
122
+ {
123
+ filter: { name: { _eq: 'Tolkien' } },
124
+ pagination: { limit: 10, offset: 0 },
125
+ }
126
+ );
127
+
128
+ // Returns all authors with all their books, published authors, and nested relationships
129
+ ```
130
+
131
+ ---
132
+
133
+ ## Architecture: The Rings of Power
134
+
135
+ ### The Fellowship: Core Components
136
+
137
+ | Component | Purpose |
138
+ | ------------------ | ----------------------------------------------------------------- |
139
+ | **GQLtoSQLMapper** | The main artifact—transforms GraphQL into SQL with proper joins |
140
+ | **QueryManager** | The orchestrator—manages the entire query execution flow |
141
+ | **EntitySystem** | The registry—defines GraphQL entities with auto-generated filters |
142
+ | **Operations** | The spells—defines all available filtering operations |
143
+
144
+ ### The Fellowship's Journey: Query Flow
145
+
146
+ 1. **Parsing** – GraphQL field selections are parsed using `graphql-fields`
147
+ 2. **Mapping** – `GQLtoSQLMapper.recursiveMap()` builds SQL recursively
148
+ 3. **Aggregation** – JSON aggregation combines nested results efficiently
149
+ 4. **Execution** – Final SQL is executed against your database
150
+
151
+ ---
152
+
153
+ ## Advanced Usage
154
+
155
+ ### Comprehensive Filtering
156
+
157
+ Filter at any nesting level with powerful operations:
158
+
159
+ ```typescript
160
+ // Find authors with published books
161
+ await queryManager.execute(Author, gqlInfo, {
162
+ filter: {
163
+ books: {
164
+ publicationYear: { _gte: 2000 },
165
+ },
166
+ },
167
+ });
168
+
169
+ // Complex nested AND/OR conditions
170
+ await queryManager.execute(Author, gqlInfo, {
171
+ filter: {
172
+ _and: [{ name: { _like: '%Tolkien%' } }, { books: { publicationYear: { _gte: 1950 } } }],
173
+ },
174
+ });
175
+ ```
176
+
177
+ ### Pagination & Sorting
178
+
179
+ ```typescript
180
+ await queryManager.execute(Author, gqlInfo, {
181
+ pagination: {
182
+ limit: 20,
183
+ offset: 40,
184
+ orderBy: 'name', // ASC by default
185
+ orderByDirection: 'DESC',
186
+ },
187
+ });
188
+ ```
189
+
190
+ ### Filter Operations
191
+
192
+ | Operation | Example | Meaning |
193
+ | -------------- | --------------------------------- | ---------------------------------- |
194
+ | `_eq` | `{ id: { _eq: 5 } }` | Equal to |
195
+ | `_ne` | `{ status: { _ne: 'inactive' } }` | Not equal to |
196
+ | `_in` | `{ id: { _in: [1, 2, 3] } }` | In array |
197
+ | `_like` | `{ name: { _like: '%Frodo%' } }` | String contains (case-insensitive) |
198
+ | `_gt` / `_gte` | `{ year: { _gte: 1900 } }` | Greater than (or equal) |
199
+ | `_lt` / `_lte` | `{ year: { _lte: 2000 } }` | Less than (or equal) |
200
+
201
+ ### Custom Fields
202
+
203
+ Beyond GQL of Power's automated query generation, you can add **custom fields** that execute custom logic alongside your data fetching. Perfect for computed properties, cross-cutting concerns, or batch loading.
204
+
205
+ ```typescript
206
+ // Define custom fields when creating GraphQL types
207
+ const FellowshipGQL = createGQLTypes(Fellowship, FellowshipFields, {
208
+ customFields: {
209
+ // Custom field that fetches the first fellowship member
210
+ firstMember: {
211
+ type: () => GraphQLJSON,
212
+ options: { nullable: true },
213
+ requires: ['id'], // Fields that must be fetched from the database for this resolver
214
+ resolveDecorators: [Root(), Ctx(), Info()], // TypeGraphQL parameter decorators for the resolve function
215
+ resolve: (root: Fellowship, ctx: any, info: any) => {
216
+ // Your custom logic—can use DataLoader for batch loading
217
+ return memberDataLoader.load(root.id);
218
+ },
219
+ },
220
+ },
221
+ });
222
+
223
+ // Export FieldsResolver to use in your resolver classes
224
+ export const FellowshipFieldsResolver = FellowshipGQL.FieldsResolver;
225
+ ```
226
+
227
+ #### Custom Field Configuration
228
+
229
+ | Property | Purpose | Connection |
230
+ |----------|---------|------------|
231
+ | `type` | Declares the GraphQL return type that appears in the schema | The type clients see when querying this field |
232
+ | `options` | TypeGraphQL field options like nullable, deprecation, descriptions | Controls field behavior in the GraphQL schema |
233
+ | `requires` | Specifies which fields from the main query must be present in the result | GQL of Power ensures these database columns are fetched alongside the optimized query |
234
+ | `resolve` | Function that receives the root entity object and returns the custom field value | Executed after the main query completes, receiving the fetched entity data |
235
+ | `resolveDecorators` | TypeGraphQL decorators that map function parameters | Determines which context parameters (`Root`, `Ctx`, `Info`) are injected into the resolve function |
236
+
237
+ #### Use Cases
238
+
239
+ 🧙 **DataLoader Integration** – Batch-load related data without N+1
240
+ ```typescript
241
+ firstMember: {
242
+ type: () => PersonGQL.GQLEntity,
243
+ resolve: (root: Fellowship) => memberDataLoader.load(root.id),
244
+ }
245
+ ```
246
+
247
+ ✨ **Computed Properties** – Calculate derived values
248
+ ```typescript
249
+ memberCount: {
250
+ type: () => Number,
251
+ resolve: (root: Fellowship) => root.members?.length || 0,
252
+ }
253
+ ```
254
+
255
+ 🎭 **Business Logic** – Apply formatting, ACL, or transformations
256
+ ```typescript
257
+ formattedName: {
258
+ type: () => String,
259
+ resolve: (root: Fellowship) => formatTitle(root.name),
260
+ }
261
+ ```
262
+
263
+ #### Using Custom Fields in Resolvers
264
+
265
+ To make custom fields available in your GraphQL resolvers, extend the generated `FieldsResolver` class:
266
+
267
+ ```typescript
268
+ import { Resolver, Query, Arg, Info } from 'type-graphql';
269
+ import { FellowshipGQL, FellowshipFieldsResolver } from './entities';
270
+
271
+ @Resolver(() => FellowshipGQL.GQLEntity)
272
+ export class FellowshipResolver extends FellowshipFieldsResolver {
273
+ @Query(() => [FellowshipGQL.GQLEntity])
274
+ async fellowships(
275
+ @Info() info: GraphQLResolveInfo,
276
+ @Arg('filter', () => FellowshipGQL.GQLEntityFilterInput, { nullable: true })
277
+ filter?: GQLEntityFilterInputFieldType<Fellowship>
278
+ ) {
279
+ return await queryManager.getQueryResultsForInfo(
280
+ metadataProvider,
281
+ Fellowship,
282
+ info,
283
+ filter
284
+ );
285
+ }
286
+ }
287
+ ```
288
+
289
+ The `FieldsResolver` automatically handles custom field resolution alongside the main query execution. When a client requests a custom field, it will be resolved using your custom resolver logic while the rest of the query is handled by GQL of Power's optimized SQL generation.
290
+
291
+ ---
292
+
293
+ ## Configuration
294
+
295
+ ### Environment Variables
296
+
297
+ ```bash
298
+ # Toggle between JSONB and string concatenation for JSON aggregation
299
+ D3GOP_USE_STRING_FOR_JSONB=true
300
+
301
+ # Control logging output
302
+ D3GOP_LOG_TYPE="debug" # Options: debug, disabled
303
+ ```
304
+
305
+ ---
306
+
307
+ ## Common Commands
308
+
309
+ ### Development
310
+
311
+ ```bash
312
+ # Install dependencies
313
+ pnpm install
314
+
315
+ # Build the library
316
+ pnpm run build
317
+
318
+ # Watch mode for development
319
+ pnpm run watch
320
+
321
+ # Run all tests
322
+ pnpm test
323
+
324
+ # Run unit tests only
325
+ pnpm test:unit
326
+
327
+ # Run integration tests only
328
+ pnpm test:integration
329
+
330
+ # Watch mode for tests
331
+ pnpm test:watch
332
+
333
+ # Generate coverage report
334
+ pnpm test:coverage
335
+
336
+ # Build for publishing
337
+ pnpm run prepublishOnly
338
+ ```
339
+
340
+ ---
341
+
342
+ ## Why GQL of Power?
343
+
344
+ ### The Problem It Solves
345
+
346
+ Traditional GraphQL + ORM combinations suffer from the **N+1 query problem**:
347
+
348
+ - Query 1: Fetch 10 authors
349
+ - Query 2-11: Fetch books for each author (10 queries)
350
+ - Query 12-21: Fetch publication details for each book (10 queries)
351
+ - **Total: 21 queries** ❌
352
+
353
+ ### The Solution
354
+
355
+ ```
356
+ GQL of Power: Fetch all data in **1 query** ✅
357
+ ```
358
+
359
+ By analyzing your GraphQL query structure and ORM relationships, GQL of Power generates a single, optimized SQL query with intelligent joins and aggregations that returns your complete data structure.
360
+
361
+ ---
362
+
363
+ ## Architecture Highlights
364
+
365
+ ### Relationship Handling
366
+
367
+ | Relationship | Strategy |
368
+ | ------------ | --------------------------------------- |
369
+ | **1:1** | Simple INNER/LEFT JOIN |
370
+ | **m:1** | INNER/LEFT JOIN to parent table |
371
+ | **1:m** | Subquery with JSON aggregation |
372
+ | **m:m** | Through junction table with aggregation |
373
+
374
+ ### Performance Optimizations
375
+
376
+ - **Alias Management** – Incremental aliases (`a1`, `a2`, ...) prevent naming conflicts
377
+ - **Set-Based Field Selection** – Eliminates duplicate fields automatically
378
+ - **OR to UNION ALL** – Converts OR conditions to UNION queries for optimal execution plans
379
+ - **JSONB Aggregation** – Efficient nested data structure building
380
+
381
+ ---
382
+
383
+ ## Known Limitations
384
+
385
+ These dragons still slumber in the cave—future challenges for brave developers:
386
+
387
+ - ⚠️ Class-level `NOT` conditions not yet supported
388
+ - ⚠️ Order by reference table columns (e.g., "order authors by their latest book publication")
389
+ - ⚠️ Access Control Lists (ACL) pending async refactoring
390
+
391
+ ---
392
+
393
+ ## Examples
394
+
395
+ See the `/examples` directory for complete, runnable examples:
396
+
397
+ - **Middle-earth Schema** – Full Author/Book relationship example inspired by Tolkien's lore
398
+ - **Database Integration** – Real PostgreSQL examples with TypeTypeORM metadata
399
+
400
+ ---
401
+
402
+ ## Contributing
403
+
404
+ Contributions are welcome! Whether you're fixing bugs, improving performance, or adding features, please submit a pull request.
405
+
406
+ ---
407
+
408
+ ## License
409
+
410
+ MIT NON-AI License
411
+
412
+ Forged by [Dav3](https://github.com/dave-palt) with the wisdom of Middle-earth.
413
+
414
+ ---
415
+
416
+ ## Support & Community
417
+
418
+ - 📖 Full documentation coming soon
419
+ - 🐛 Found a bug? [Open an issue](https://github.com/dave-palt/gql-of-power/issues)
420
+ - 💬 Have a question? Reach out to the fellowship
421
+
422
+ ---
423
+
424
+ > _"All we have to decide is what to do with the queries that are given us. And by using GQL of Power, that decision becomes much simpler."_
425
+ >
426
+ > — Adapted from J.R.R. Tolkien
package/bunfig.toml ADDED
@@ -0,0 +1,17 @@
1
+ [test]
2
+ coverage = true
3
+ # Only run tests from source directories, not dist
4
+ preload = ["./tests/setup.ts"]
5
+ testNamePattern = ".*\\.test\\.(ts|js)$"
6
+
7
+ # Explicitly exclude dist directory from test discovery
8
+ exclude = [
9
+ "dist/**/*",
10
+ "node_modules/**/*",
11
+ "coverage/**/*"
12
+ ]
13
+
14
+ # Include only tests from these directories
15
+ include = [
16
+ "tests/**/*.test.ts"
17
+ ]
@@ -0,0 +1,39 @@
1
+ import { getMetadataStorage } from 'type-graphql';
2
+ import { CustomFieldsSettings, FieldSettings, FieldsSettings, GQLEntityFilterInputFieldType, GQLEntityPaginationInputType, RelatedFieldSettings } from '../types';
3
+ import { AccessControlEntry } from '../types/access-control';
4
+ export declare const setGlobalConfig: (config: {
5
+ gqlTypesSuffix: string;
6
+ }) => void;
7
+ export declare const getFieldsOptionsFor: (name: string) => Record<string, string>;
8
+ export declare const getFieldByAlias: (entityName: string | undefined, alias: string) => string;
9
+ export declare const getCustomFieldsFor: (name: string) => CustomFieldsSettings<any>;
10
+ export declare const getACLFor: (name: string) => AccessControlEntry<any, any>;
11
+ export declare const getGQLEntityNameFor: (name: string) => string;
12
+ export declare const getGQLEntityNameForClass: <T>(classType: new () => T) => string;
13
+ export declare const getGQLEntityFieldResolverName: (gqlEntityName: string) => string;
14
+ export declare const getGQLEntityFieldResolverNameFor: <T extends Object>(classType: new () => T) => string;
15
+ export declare const getGQLEntityTypeFor: <T extends Object, K>(classType: new () => T) => string;
16
+ export declare function createGQLTypes<T extends Object, K>(classType: new () => T, opts: Partial<FieldsSettings<T>>, { customFields, acl, }?: {
17
+ customFields?: CustomFieldsSettings<T>;
18
+ acl?: AccessControlEntry<T, K>;
19
+ }): {
20
+ GQLEntity: {
21
+ new (): {
22
+ _____name: string;
23
+ };
24
+ };
25
+ GQLEntityFilterInput: GQLEntityFilterInputFieldType<T>;
26
+ GQLEntityPaginationInputField: GQLEntityPaginationInputType<T>;
27
+ /**
28
+ * this can be used alongside `getGQLEntityTypeFor` to get the type of the entity, not sure it will be ever needed
29
+ */
30
+ gqlEntityName: string;
31
+ relatedEntityName: string;
32
+ FieldsResolver: {
33
+ new (): {};
34
+ };
35
+ bindFieldResolvers: (c: any) => void;
36
+ };
37
+ type TypeGQLMetadataStorage = ReturnType<typeof getMetadataStorage>;
38
+ export declare function createGQLEntityFields<T, K>(fieldOptions: FieldSettings | RelatedFieldSettings<T>, fieldName: string, GQLEntity: new () => T, metadata: TypeGQLMetadataStorage, GQLEntityOrderBy: any, gqlEntityName: string, GQLEntityFilterInput: new () => K): void;
39
+ export {};