@constructive-io/graphql-query 3.2.5 → 3.3.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 (88) hide show
  1. package/README.md +411 -65
  2. package/ast.d.ts +4 -4
  3. package/ast.js +24 -9
  4. package/client/error.d.ts +95 -0
  5. package/client/error.js +277 -0
  6. package/client/execute.d.ts +57 -0
  7. package/client/execute.js +124 -0
  8. package/client/index.d.ts +8 -0
  9. package/client/index.js +20 -0
  10. package/client/typed-document.d.ts +31 -0
  11. package/client/typed-document.js +44 -0
  12. package/custom-ast.d.ts +22 -8
  13. package/custom-ast.js +16 -1
  14. package/esm/ast.js +22 -7
  15. package/esm/client/error.js +271 -0
  16. package/esm/client/execute.js +120 -0
  17. package/esm/client/index.js +8 -0
  18. package/esm/client/typed-document.js +40 -0
  19. package/esm/custom-ast.js +16 -1
  20. package/esm/generators/field-selector.js +381 -0
  21. package/esm/generators/index.js +13 -0
  22. package/esm/generators/mutations.js +200 -0
  23. package/esm/generators/naming-helpers.js +154 -0
  24. package/esm/generators/select.js +661 -0
  25. package/esm/index.js +30 -0
  26. package/esm/introspect/index.js +9 -0
  27. package/esm/introspect/infer-tables.js +697 -0
  28. package/esm/introspect/schema-query.js +120 -0
  29. package/esm/introspect/transform-schema.js +271 -0
  30. package/esm/introspect/transform.js +38 -0
  31. package/esm/meta-object/convert.js +3 -0
  32. package/esm/meta-object/format.json +11 -41
  33. package/esm/meta-object/validate.js +20 -4
  34. package/esm/query-builder.js +14 -18
  35. package/esm/types/index.js +18 -0
  36. package/esm/types/introspection.js +54 -0
  37. package/esm/types/mutation.js +4 -0
  38. package/esm/types/query.js +4 -0
  39. package/esm/types/schema.js +5 -0
  40. package/esm/types/selection.js +4 -0
  41. package/esm/utils.js +69 -0
  42. package/generators/field-selector.d.ts +30 -0
  43. package/generators/field-selector.js +387 -0
  44. package/generators/index.d.ts +9 -0
  45. package/generators/index.js +42 -0
  46. package/generators/mutations.d.ts +30 -0
  47. package/generators/mutations.js +238 -0
  48. package/generators/naming-helpers.d.ts +48 -0
  49. package/generators/naming-helpers.js +169 -0
  50. package/generators/select.d.ts +39 -0
  51. package/generators/select.js +705 -0
  52. package/index.d.ts +19 -0
  53. package/index.js +34 -1
  54. package/introspect/index.d.ts +9 -0
  55. package/introspect/index.js +25 -0
  56. package/introspect/infer-tables.d.ts +42 -0
  57. package/introspect/infer-tables.js +700 -0
  58. package/introspect/schema-query.d.ts +20 -0
  59. package/introspect/schema-query.js +123 -0
  60. package/introspect/transform-schema.d.ts +86 -0
  61. package/introspect/transform-schema.js +281 -0
  62. package/introspect/transform.d.ts +20 -0
  63. package/introspect/transform.js +43 -0
  64. package/meta-object/convert.d.ts +3 -0
  65. package/meta-object/convert.js +3 -0
  66. package/meta-object/format.json +11 -41
  67. package/meta-object/validate.d.ts +8 -3
  68. package/meta-object/validate.js +20 -4
  69. package/package.json +4 -3
  70. package/query-builder.d.ts +11 -12
  71. package/query-builder.js +25 -29
  72. package/{types.d.ts → types/core.d.ts} +25 -18
  73. package/types/index.d.ts +12 -0
  74. package/types/index.js +34 -0
  75. package/types/introspection.d.ts +121 -0
  76. package/types/introspection.js +62 -0
  77. package/types/mutation.d.ts +45 -0
  78. package/types/mutation.js +5 -0
  79. package/types/query.d.ts +91 -0
  80. package/types/query.js +5 -0
  81. package/types/schema.d.ts +265 -0
  82. package/types/schema.js +6 -0
  83. package/types/selection.d.ts +43 -0
  84. package/types/selection.js +5 -0
  85. package/utils.d.ts +17 -0
  86. package/utils.js +72 -0
  87. /package/esm/{types.js → types/core.js} +0 -0
  88. /package/{types.js → types/core.js} +0 -0
package/README.md CHANGED
@@ -12,7 +12,7 @@
12
12
  <a href="https://www.npmjs.com/package/@constructive-io/graphql-query"><img height="20" src="https://img.shields.io/github/package-json/v/constructive-io/constructive?filename=graphql%2Fquery%2Fpackage.json"/></a>
13
13
  </p>
14
14
 
15
- > Fluent GraphQL query and mutation builder for PostGraphile-based schemas.
15
+ > Browser-safe GraphQL query generation core for PostGraphile schemas. Build type-safe queries, mutations, and introspection pipelines — at runtime or build time.
16
16
 
17
17
  ## Installation
18
18
 
@@ -20,68 +20,71 @@
20
20
  npm install @constructive-io/graphql-query
21
21
  ```
22
22
 
23
- ## Why Use `@constructive-io/graphql-query`?
23
+ ## Overview
24
24
 
25
- * Build complex, nested GraphQL queries fluently
26
- * ✅ Schema-aware via introspection (PostGraphile optimized)
27
- * 🧠 Prevents common query syntax issues
28
- * 🧩 Designed for composability and clean syntax
25
+ This package is the **canonical source** for PostGraphile query generation logic. It provides:
29
26
 
30
- ## Usage
27
+ - **Query generators** — `buildSelect`, `buildFindOne`, `buildCount` for read operations
28
+ - **Mutation generators** — `buildPostGraphileCreate`, `buildPostGraphileUpdate`, `buildPostGraphileDelete`
29
+ - **Introspection pipeline** — `inferTablesFromIntrospection` to convert a GraphQL schema into `CleanTable` metadata
30
+ - **AST builders** — low-level `getAll`, `getMany`, `getOne`, `createOne`, `patchOne`, `deleteOne`
31
+ - **Client utilities** — `TypedDocumentString`, `execute`, `DataError` for type-safe execution and error handling
32
+ - **Naming helpers** — server-aware inflection functions that respect PostGraphile's schema naming
31
33
 
32
- ```ts
33
- import { QueryBuilder } from '@constructive-io/graphql-query';
34
+ All modules are **browser-safe** (no Node.js APIs). `@constructive-io/graphql-codegen` depends on this package for the core logic and adds Node.js-only features (CLI, file output, watch mode).
35
+
36
+ ---
37
+
38
+ ## Quick Start: Generate Queries from a Schema
39
+
40
+ The most common workflow: introspect a GraphQL schema, then generate queries and mutations for any table.
34
41
 
35
- const builder = new QueryBuilder({
36
- introspection: { ...queries, ...mutations } // provide your GraphQL schema metadata
42
+ ### Step 1 Introspect
43
+
44
+ ```ts
45
+ import {
46
+ inferTablesFromIntrospection,
47
+ SCHEMA_INTROSPECTION_QUERY,
48
+ } from '@constructive-io/graphql-query';
49
+
50
+ // Fetch introspection from any GraphQL endpoint
51
+ const response = await fetch('/graphql', {
52
+ method: 'POST',
53
+ headers: { 'Content-Type': 'application/json' },
54
+ body: JSON.stringify({ query: SCHEMA_INTROSPECTION_QUERY }),
37
55
  });
56
+ const { data } = await response.json();
38
57
 
39
- const result = builder
40
- .query('Action')
41
- .edges(true)
42
- .getMany({
43
- select: {
44
- id: true,
45
- name: true,
46
- photo: true,
47
- title: true,
48
- actionResults: {
49
- select: {
50
- id: true,
51
- actionId: true
52
- },
53
- variables: {
54
- first: 10,
55
- before: null,
56
- filter: {
57
- name: {
58
- in: ['abc', 'def']
59
- },
60
- actionId: {
61
- equalTo: 'dc310161-7a42-4b93-6a56-9fa48adcad7e'
62
- }
63
- }
64
- }
65
- }
66
- }
67
- })
68
- .print();
58
+ // Convert to CleanTable metadata
59
+ const tables = inferTablesFromIntrospection(data);
60
+ // tables = [{ name: 'User', fields: [...], relations: {...}, query: {...}, inflection: {...} }, ...]
69
61
  ```
70
62
 
71
- ## Output
63
+ ### Step 2 — Generate a SELECT query
64
+
65
+ ```ts
66
+ import { buildSelect } from '@constructive-io/graphql-query';
67
+
68
+ const userTable = tables.find(t => t.name === 'User')!;
69
+ const query = buildSelect(userTable, tables);
70
+
71
+ console.log(query.toString());
72
+ ```
73
+
74
+ **Generated GraphQL:**
72
75
 
73
76
  ```graphql
74
- query getActionsQuery(
77
+ query getUsersQuery(
75
78
  $first: Int
76
79
  $last: Int
77
80
  $after: Cursor
78
81
  $before: Cursor
79
82
  $offset: Int
80
- $condition: ActionCondition
81
- $filter: ActionFilter
82
- $orderBy: [ActionsOrderBy!]
83
+ $condition: UserCondition
84
+ $filter: UserFilter
85
+ $orderBy: [UsersOrderBy!]
83
86
  ) {
84
- actions(
87
+ users(
85
88
  first: $first
86
89
  last: $last
87
90
  offset: $offset
@@ -98,32 +101,375 @@ query getActionsQuery(
98
101
  endCursor
99
102
  startCursor
100
103
  }
101
- edges {
102
- cursor
103
- node {
104
+ nodes {
105
+ id
106
+ name
107
+ email
108
+ createdAt
109
+ }
110
+ }
111
+ }
112
+ ```
113
+
114
+ ### Step 3 — Generate mutations
115
+
116
+ ```ts
117
+ import {
118
+ buildPostGraphileCreate,
119
+ buildPostGraphileUpdate,
120
+ buildPostGraphileDelete,
121
+ } from '@constructive-io/graphql-query';
122
+
123
+ const createQuery = buildPostGraphileCreate(userTable, tables);
124
+ const updateQuery = buildPostGraphileUpdate(userTable, tables);
125
+ const deleteQuery = buildPostGraphileDelete(userTable, tables);
126
+ ```
127
+
128
+ **Generated CREATE mutation:**
129
+
130
+ ```graphql
131
+ mutation createUserMutation($input: CreateUserInput!) {
132
+ createUser(input: $input) {
133
+ user {
134
+ id
135
+ name
136
+ email
137
+ createdAt
138
+ }
139
+ }
140
+ }
141
+ ```
142
+
143
+ **Generated UPDATE mutation:**
144
+
145
+ ```graphql
146
+ mutation updateUserMutation($input: UpdateUserInput!) {
147
+ updateUser(input: $input) {
148
+ user {
149
+ id
150
+ name
151
+ email
152
+ createdAt
153
+ }
154
+ }
155
+ }
156
+ ```
157
+
158
+ **Generated DELETE mutation:**
159
+
160
+ ```graphql
161
+ mutation deleteUserMutation($input: DeleteUserInput!) {
162
+ deleteUser(input: $input) {
163
+ clientMutationId
164
+ }
165
+ }
166
+ ```
167
+
168
+ ---
169
+
170
+ ## Nested Relations
171
+
172
+ Include related tables in your query with automatic Connection wrapping for hasMany relations:
173
+
174
+ ```ts
175
+ import { buildSelect } from '@constructive-io/graphql-query';
176
+
177
+ const actionTable = tables.find(t => t.name === 'Action')!;
178
+
179
+ const query = buildSelect(actionTable, tables, {
180
+ fieldSelection: {
181
+ select: ['id', 'name', 'photo', 'title'],
182
+ include: {
183
+ actionResults: ['id', 'actionId'], // hasMany → wrapped in nodes { ... }
184
+ category: true, // belongsTo → direct nesting
185
+ },
186
+ },
187
+ });
188
+ ```
189
+
190
+ **Generated GraphQL:**
191
+
192
+ ```graphql
193
+ query actionsQuery {
194
+ actions {
195
+ totalCount
196
+ nodes {
197
+ id
198
+ name
199
+ photo
200
+ title
201
+ actionResults(first: 20) {
202
+ nodes {
203
+ id
204
+ actionId
205
+ }
206
+ }
207
+ category {
104
208
  id
105
209
  name
106
- photo
107
- title
108
- actionResults(
109
- first: 10
110
- before: null
111
- filter: {
112
- name: { in: ["abc", "def"] }
113
- actionId: { equalTo: "dc310161-7a42-4b93-6a56-9fa48adcad7e" }
114
- }
115
- ) {
116
- nodes {
117
- id
118
- actionId
119
- }
120
- }
121
210
  }
122
211
  }
123
212
  }
124
213
  }
125
214
  ```
126
215
 
216
+ > **hasMany** relations are automatically wrapped in the PostGraphile Connection pattern (`nodes { ... }` with a default `first: 20` limit).
217
+ > **belongsTo** relations are nested directly.
218
+
219
+ ---
220
+
221
+ ## FindOne Query
222
+
223
+ ```ts
224
+ import { buildFindOne } from '@constructive-io/graphql-query';
225
+
226
+ const findOneQuery = buildFindOne(userTable);
227
+ console.log(findOneQuery.toString());
228
+ ```
229
+
230
+ **Generated GraphQL:**
231
+
232
+ ```graphql
233
+ query getUserQuery($id: UUID!) {
234
+ user(id: $id) {
235
+ id
236
+ name
237
+ email
238
+ createdAt
239
+ }
240
+ }
241
+ ```
242
+
243
+ ---
244
+
245
+ ## Count Query
246
+
247
+ ```ts
248
+ import { buildCount } from '@constructive-io/graphql-query';
249
+
250
+ const countQuery = buildCount(userTable);
251
+ console.log(countQuery.toString());
252
+ ```
253
+
254
+ **Generated GraphQL:**
255
+
256
+ ```graphql
257
+ query getUsersCountQuery(
258
+ $condition: UserCondition
259
+ $filter: UserFilter
260
+ ) {
261
+ users(condition: $condition, filter: $filter) {
262
+ totalCount
263
+ }
264
+ }
265
+ ```
266
+
267
+ ---
268
+
269
+ ## Field Selection
270
+
271
+ Control which fields and relations are included using presets or custom selection:
272
+
273
+ ```ts
274
+ import { buildSelect } from '@constructive-io/graphql-query';
275
+
276
+ // Preset: just id + a few display fields
277
+ const minimal = buildSelect(userTable, tables, { fieldSelection: 'minimal' });
278
+
279
+ // Preset: all scalar fields (no relations)
280
+ const allFields = buildSelect(userTable, tables, { fieldSelection: 'all' });
281
+
282
+ // Preset: everything including relations
283
+ const full = buildSelect(userTable, tables, { fieldSelection: 'full' });
284
+
285
+ // Custom: pick specific fields + exclude some + include specific relations
286
+ const custom = buildSelect(userTable, tables, {
287
+ fieldSelection: {
288
+ select: ['id', 'name', 'email'],
289
+ exclude: ['internalNotes'],
290
+ include: { posts: ['id', 'title'] },
291
+ },
292
+ });
293
+ ```
294
+
295
+ ---
296
+
297
+ ## Relation Field Mapping (Aliases)
298
+
299
+ Remap relation field names when the server-side name differs from what your consumer expects:
300
+
301
+ ```ts
302
+ const query = buildSelect(userTable, tables, {
303
+ relationFieldMap: {
304
+ contact: 'contactByOwnerId', // emits: contact: contactByOwnerId { ... }
305
+ internalNotes: null, // omits this relation entirely
306
+ },
307
+ });
308
+ ```
309
+
310
+ ---
311
+
312
+ ## Type-Safe Execution
313
+
314
+ ```ts
315
+ import { createGraphQLClient } from '@constructive-io/graphql-query';
316
+
317
+ const client = createGraphQLClient({
318
+ url: '/graphql',
319
+ headers: { Authorization: `Bearer ${token}` },
320
+ });
321
+
322
+ const { data, errors } = await client.execute(query, {
323
+ first: 10,
324
+ filter: { name: { includesInsensitive: 'search' } },
325
+ });
326
+ ```
327
+
328
+ ---
329
+
330
+ ## Error Handling
331
+
332
+ ```ts
333
+ import { DataError, parseGraphQLError, DataErrorType } from '@constructive-io/graphql-query';
334
+
335
+ try {
336
+ const result = await client.execute(createQuery, { input: { user: { name: 'Alice' } } });
337
+ if (result.errors) {
338
+ const error = parseGraphQLError(result.errors[0]);
339
+ if (error.type === DataErrorType.UNIQUE_VIOLATION) {
340
+ console.log('Duplicate entry:', error.constraintName);
341
+ }
342
+ }
343
+ } catch (err) {
344
+ if (err instanceof DataError) {
345
+ console.log(err.type, err.message);
346
+ }
347
+ }
348
+ ```
349
+
350
+ ---
351
+
352
+ ## Server-Aware Naming
353
+
354
+ All generators automatically use server-inferred names from introspection when available, falling back to local inflection conventions:
355
+
356
+ ```ts
357
+ import {
358
+ toCamelCaseSingular,
359
+ toCamelCasePlural,
360
+ toCreateMutationName,
361
+ toPatchFieldName,
362
+ toFilterTypeName,
363
+ } from '@constructive-io/graphql-query';
364
+
365
+ // Uses table.query/table.inflection if available, falls back to convention
366
+ toCamelCaseSingular('DeliveryZone', table); // "deliveryZone" (from table.inflection.tableFieldName)
367
+ toCamelCasePlural('DeliveryZone', table); // "deliveryZones" (from table.query.all)
368
+ toCreateMutationName('User', table); // "createUser" (from table.query.create)
369
+ toPatchFieldName('User', table); // "userPatch" (from table.query.patchFieldName)
370
+ toFilterTypeName('User', table); // "UserFilter" (from table.inflection.filterType)
371
+ ```
372
+
373
+ ---
374
+
375
+ ## Architecture
376
+
377
+ ```
378
+ GraphQL Schema (introspection or _meta)
379
+ |
380
+ v
381
+ inferTablesFromIntrospection()
382
+ |
383
+ v
384
+ CleanTable[] (normalized metadata with inflection + query names)
385
+ |
386
+ v
387
+ buildSelect / buildFindOne / buildCount / buildPostGraphileCreate / ...
388
+ |
389
+ v
390
+ gql-ast (AST node factories)
391
+ |
392
+ v
393
+ graphql print() -> query string
394
+ |
395
+ v
396
+ TypedDocumentString (type-safe wrapper)
397
+ ```
398
+
399
+ ### Package Relationship
400
+
401
+ ```
402
+ @constructive-io/graphql-query (this package — browser-safe core)
403
+ |
404
+ v
405
+ @constructive-io/graphql-codegen (Node.js CLI — depends on graphql-query)
406
+ + CLI entry points
407
+ + File output (writes .ts files to disk)
408
+ + Watch mode
409
+ + Database introspection
410
+ + React Query hook generation
411
+ + Babel codegen templates
412
+ ```
413
+
414
+ ---
415
+
416
+ ## API Reference
417
+
418
+ ### Generators
419
+
420
+ | Function | Description |
421
+ |---|---|
422
+ | `buildSelect(table, allTables, options?)` | Build a paginated SELECT query with filters, sorting, field selection |
423
+ | `buildFindOne(table, pkField?)` | Build a single-row query by primary key |
424
+ | `buildCount(table)` | Build a count query with optional condition/filter |
425
+ | `buildPostGraphileCreate(table, allTables, options?)` | Build a CREATE mutation |
426
+ | `buildPostGraphileUpdate(table, allTables, options?)` | Build an UPDATE mutation |
427
+ | `buildPostGraphileDelete(table, allTables, options?)` | Build a DELETE mutation |
428
+
429
+ ### Introspection
430
+
431
+ | Function | Description |
432
+ |---|---|
433
+ | `inferTablesFromIntrospection(data, options?)` | Convert GraphQL introspection to `CleanTable[]` |
434
+ | `transformSchemaToOperations(types, queryType, mutationType)` | Extract operations from schema types |
435
+ | `SCHEMA_INTROSPECTION_QUERY` | Full introspection query string |
436
+
437
+ ### Client
438
+
439
+ | Export | Description |
440
+ |---|---|
441
+ | `TypedDocumentString` | Type-safe GraphQL document wrapper (compatible with codegen client) |
442
+ | `createGraphQLClient(options)` | Create a typed GraphQL client |
443
+ | `execute(url, query, variables, options?)` | Execute a GraphQL query |
444
+ | `DataError` | Structured error class with PG SQLSTATE classification |
445
+ | `parseGraphQLError(error)` | Parse raw GraphQL error into `DataError` |
446
+
447
+ ### Naming Helpers
448
+
449
+ | Function | Description |
450
+ |---|---|
451
+ | `toCamelCaseSingular(name, table?)` | Server-aware singular name |
452
+ | `toCamelCasePlural(name, table?)` | Server-aware plural name |
453
+ | `toCreateMutationName(name, table?)` | Create mutation operation name |
454
+ | `toUpdateMutationName(name, table?)` | Update mutation operation name |
455
+ | `toDeleteMutationName(name, table?)` | Delete mutation operation name |
456
+ | `toPatchFieldName(name, table?)` | Patch field name in update input |
457
+ | `toFilterTypeName(name, table?)` | Filter type name |
458
+ | `toOrderByEnumValue(fieldName)` | Convert field name to OrderBy enum value |
459
+ | `normalizeInflectionValue(value, fallback)` | Safe inflection value lookup |
460
+
461
+ ### Types
462
+
463
+ | Type | Description |
464
+ |---|---|
465
+ | `CleanTable` | Normalized table metadata with fields, relations, inflection, query names |
466
+ | `CleanField` | Field with type info, `isNotNull`, `hasDefault` |
467
+ | `QueryOptions` | Options for `buildSelect` (pagination, filters, field selection, relation mapping) |
468
+ | `MutationOptions` | Options for mutation builders |
469
+ | `FieldSelection` | Field selection presets and custom configuration |
470
+ | `ConnectionResult<T>` | Relay-style connection result type |
471
+ | `Filter` | PostGraphile connection filter type |
472
+
127
473
  ---
128
474
 
129
475
  ## Education and Tutorials
package/ast.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { type DocumentNode, type FieldNode } from 'graphql';
2
- import type { ASTFunctionParams, FieldSelection, MutationASTParams } from './types';
3
- export declare const getAll: ({ queryName, operationName, query: _query, selection, }: ASTFunctionParams) => DocumentNode;
1
+ import type { DocumentNode, FieldNode } from 'graphql';
2
+ import type { ASTFunctionParams, MutationASTParams, QueryFieldSelection } from './types';
3
+ export declare const getAll: ({ queryName, operationName, selection, }: ASTFunctionParams) => DocumentNode;
4
4
  export declare const getCount: ({ queryName, operationName, query, }: Omit<ASTFunctionParams, "selection">) => DocumentNode;
5
5
  export declare const getMany: ({ builder, queryName, operationName, query, selection, }: ASTFunctionParams) => DocumentNode;
6
6
  export declare const getOne: ({ queryName, operationName, query, selection, }: ASTFunctionParams) => DocumentNode;
7
7
  export declare const createOne: ({ mutationName, operationName, mutation, selection, }: MutationASTParams) => DocumentNode;
8
8
  export declare const patchOne: ({ mutationName, operationName, mutation, selection, }: MutationASTParams) => DocumentNode;
9
9
  export declare const deleteOne: ({ mutationName, operationName, mutation, }: Omit<MutationASTParams, "selection">) => DocumentNode;
10
- export declare function getSelections(selection?: FieldSelection[]): FieldNode[];
10
+ export declare function getSelections(selection?: QueryFieldSelection[]): FieldNode[];
package/ast.js CHANGED
@@ -37,7 +37,7 @@ exports.deleteOne = exports.patchOne = exports.createOne = exports.getOne = expo
37
37
  exports.getSelections = getSelections;
38
38
  const t = __importStar(require("gql-ast"));
39
39
  const graphql_1 = require("graphql");
40
- const inflection_1 = require("inflection");
40
+ const inflekt_1 = require("inflekt");
41
41
  const custom_ast_1 = require("./custom-ast");
42
42
  const NON_MUTABLE_PROPS = ['createdAt', 'createdBy', 'updatedAt', 'updatedBy'];
43
43
  const objectToArray = (obj) => Object.keys(obj).map((k) => ({
@@ -85,7 +85,7 @@ const createGqlMutation = ({ operationName, mutationName, selectArgs, selections
85
85
  ],
86
86
  });
87
87
  };
88
- const getAll = ({ queryName, operationName, query: _query, selection, }) => {
88
+ const getAll = ({ queryName, operationName, selection, }) => {
89
89
  const selections = getSelections(selection);
90
90
  const opSel = [
91
91
  t.field({
@@ -209,7 +209,10 @@ const getMany = ({ builder, queryName, operationName, query, selection, }) => {
209
209
  t.argument({ name: 'offset', value: t.variable({ name: 'offset' }) }),
210
210
  t.argument({ name: 'after', value: t.variable({ name: 'after' }) }),
211
211
  t.argument({ name: 'before', value: t.variable({ name: 'before' }) }),
212
- t.argument({ name: 'condition', value: t.variable({ name: 'condition' }) }),
212
+ t.argument({
213
+ name: 'condition',
214
+ value: t.variable({ name: 'condition' }),
215
+ }),
213
216
  t.argument({ name: 'filter', value: t.variable({ name: 'filter' }) }),
214
217
  t.argument({ name: 'orderBy', value: t.variable({ name: 'orderBy' }) }),
215
218
  ];
@@ -318,7 +321,7 @@ const createOne = ({ mutationName, operationName, mutation, selection, }) => {
318
321
  if (!mutation.properties?.input?.properties) {
319
322
  throw new Error(`No input field for mutation: ${mutationName}`);
320
323
  }
321
- const modelName = (0, inflection_1.camelize)([(0, inflection_1.singularize)(mutation.model)].join('_'), true);
324
+ const modelName = (0, inflekt_1.camelize)([(0, inflekt_1.singularize)(mutation.model)].join('_'), true);
322
325
  const inputProperties = mutation.properties.input
323
326
  .properties;
324
327
  const modelProperties = inputProperties[modelName];
@@ -364,7 +367,7 @@ const patchOne = ({ mutationName, operationName, mutation, selection, }) => {
364
367
  if (!mutation.properties?.input?.properties) {
365
368
  throw new Error(`No input field for mutation: ${mutationName}`);
366
369
  }
367
- const modelName = (0, inflection_1.camelize)([(0, inflection_1.singularize)(mutation.model)].join('_'), true);
370
+ const modelName = (0, inflekt_1.camelize)([(0, inflekt_1.singularize)(mutation.model)].join('_'), true);
368
371
  const inputProperties = mutation.properties.input
369
372
  .properties;
370
373
  const patchProperties = inputProperties['patch'];
@@ -417,7 +420,7 @@ const deleteOne = ({ mutationName, operationName, mutation, }) => {
417
420
  if (!mutation.properties?.input?.properties) {
418
421
  throw new Error(`No input field for mutation: ${mutationName}`);
419
422
  }
420
- const modelName = (0, inflection_1.camelize)([(0, inflection_1.singularize)(mutation.model)].join('_'), true);
423
+ const modelName = (0, inflekt_1.camelize)([(0, inflekt_1.singularize)(mutation.model)].join('_'), true);
421
424
  const inputProperties = mutation.properties.input
422
425
  .properties;
423
426
  const deleteAttrs = objectToArray(inputProperties);
@@ -463,9 +466,21 @@ const deleteOne = ({ mutationName, operationName, mutation, }) => {
463
466
  exports.deleteOne = deleteOne;
464
467
  function getSelections(selection = []) {
465
468
  const selectionAst = (field) => {
466
- return typeof field === 'string'
467
- ? t.field({ name: field })
468
- : (0, custom_ast_1.getCustomAst)(field.fieldDefn) || t.field({ name: field.name });
469
+ if (typeof field === 'string') {
470
+ return t.field({ name: field });
471
+ }
472
+ // Check if fieldDefn has MetaField shape (has type.pgType)
473
+ const fieldDefn = field.fieldDefn;
474
+ if (fieldDefn &&
475
+ 'type' in fieldDefn &&
476
+ fieldDefn.type &&
477
+ typeof fieldDefn.type === 'object' &&
478
+ 'pgType' in fieldDefn.type) {
479
+ const customAst = (0, custom_ast_1.getCustomAst)(fieldDefn);
480
+ if (customAst)
481
+ return customAst;
482
+ }
483
+ return t.field({ name: field.name });
469
484
  };
470
485
  return selection
471
486
  .map((selectionDefn) => {