@constructive-io/graphql-codegen 3.2.0 → 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 (216) hide show
  1. package/README.md +25 -30
  2. package/cli/index.js +36 -41
  3. package/cli/shared.d.ts +15 -17
  4. package/cli/shared.js +113 -21
  5. package/client/error.js +31 -9
  6. package/client/execute.js +2 -2
  7. package/client/index.d.ts +3 -3
  8. package/client/index.js +6 -6
  9. package/core/ast.d.ts +1 -1
  10. package/core/ast.js +1 -1
  11. package/core/codegen/babel-ast.d.ts +1 -1
  12. package/core/codegen/babel-ast.js +2 -2
  13. package/core/codegen/barrel.d.ts +0 -6
  14. package/core/codegen/barrel.js +22 -19
  15. package/core/codegen/client.d.ts +2 -12
  16. package/core/codegen/client.js +7 -21
  17. package/core/codegen/custom-mutations.d.ts +0 -14
  18. package/core/codegen/custom-mutations.js +139 -88
  19. package/core/codegen/custom-queries.d.ts +0 -14
  20. package/core/codegen/custom-queries.js +483 -193
  21. package/core/codegen/hooks-ast.d.ts +75 -0
  22. package/core/codegen/hooks-ast.js +522 -0
  23. package/core/codegen/index.d.ts +16 -18
  24. package/core/codegen/index.js +42 -88
  25. package/core/codegen/invalidation.d.ts +1 -7
  26. package/core/codegen/invalidation.js +50 -16
  27. package/core/codegen/mutation-keys.d.ts +1 -10
  28. package/core/codegen/mutation-keys.js +22 -8
  29. package/core/codegen/mutations.d.ts +0 -13
  30. package/core/codegen/mutations.js +301 -366
  31. package/core/codegen/orm/barrel.d.ts +0 -5
  32. package/core/codegen/orm/barrel.js +5 -0
  33. package/core/codegen/orm/client-generator.d.ts +0 -5
  34. package/core/codegen/orm/client-generator.js +7 -2
  35. package/core/codegen/orm/client.js +3 -1
  36. package/core/codegen/orm/custom-ops-generator.d.ts +0 -6
  37. package/core/codegen/orm/custom-ops-generator.js +104 -51
  38. package/core/codegen/orm/index.d.ts +4 -4
  39. package/core/codegen/orm/index.js +28 -15
  40. package/core/codegen/orm/input-types-generator.d.ts +1 -13
  41. package/core/codegen/orm/input-types-generator.js +85 -23
  42. package/core/codegen/orm/model-generator.d.ts +0 -5
  43. package/core/codegen/orm/model-generator.js +309 -131
  44. package/core/codegen/orm/select-types.d.ts +19 -14
  45. package/core/codegen/queries.d.ts +0 -8
  46. package/core/codegen/queries.js +360 -559
  47. package/core/codegen/query-keys.d.ts +1 -1
  48. package/core/codegen/query-keys.js +37 -23
  49. package/core/codegen/scalars.js +3 -1
  50. package/core/codegen/schema-types-generator.d.ts +1 -1
  51. package/core/codegen/schema-types-generator.js +17 -2
  52. package/core/codegen/select-helpers.d.ts +19 -0
  53. package/core/codegen/select-helpers.js +40 -0
  54. package/core/codegen/selection.d.ts +4 -0
  55. package/core/codegen/selection.js +65 -0
  56. package/core/codegen/shared/index.d.ts +2 -15
  57. package/core/codegen/shared/index.js +17 -4
  58. package/core/codegen/templates/hooks-client.ts +49 -0
  59. package/core/codegen/templates/hooks-selection.ts +58 -0
  60. package/core/codegen/templates/orm-client.ts +8 -6
  61. package/core/codegen/templates/query-builder.ts +250 -46
  62. package/core/codegen/templates/select-types.ts +31 -14
  63. package/core/codegen/type-resolver.d.ts +1 -5
  64. package/core/codegen/type-resolver.js +0 -22
  65. package/core/codegen/types.d.ts +0 -3
  66. package/core/codegen/types.js +71 -14
  67. package/core/codegen/utils.d.ts +1 -4
  68. package/core/codegen/utils.js +4 -1
  69. package/core/config/index.d.ts +1 -1
  70. package/core/config/resolver.js +1 -3
  71. package/core/generate.js +38 -50
  72. package/core/index.d.ts +3 -3
  73. package/core/index.js +3 -4
  74. package/core/introspect/index.d.ts +6 -6
  75. package/core/introspect/index.js +5 -8
  76. package/core/introspect/infer-tables.d.ts +0 -14
  77. package/core/introspect/infer-tables.js +15 -1
  78. package/core/introspect/source/database.js +1 -1
  79. package/core/introspect/source/endpoint.d.ts +0 -6
  80. package/core/introspect/source/endpoint.js +7 -1
  81. package/core/introspect/source/index.d.ts +4 -4
  82. package/core/introspect/source/index.js +5 -9
  83. package/core/introspect/source/pgpm-module.js +3 -3
  84. package/core/introspect/transform-schema.d.ts +2 -2
  85. package/core/introspect/transform-schema.js +2 -2
  86. package/core/output/index.d.ts +1 -1
  87. package/core/output/index.js +2 -2
  88. package/core/output/writer.d.ts +3 -0
  89. package/core/output/writer.js +20 -1
  90. package/core/pipeline/index.d.ts +2 -2
  91. package/core/query-builder.d.ts +2 -2
  92. package/core/query-builder.js +1 -1
  93. package/core/watch/index.d.ts +4 -4
  94. package/core/watch/index.js +9 -9
  95. package/core/watch/orchestrator.js +5 -3
  96. package/esm/cli/index.js +37 -42
  97. package/esm/cli/shared.d.ts +15 -17
  98. package/esm/cli/shared.js +103 -20
  99. package/esm/client/error.js +31 -9
  100. package/esm/client/execute.js +2 -2
  101. package/esm/client/index.d.ts +3 -3
  102. package/esm/client/index.js +3 -3
  103. package/esm/core/ast.d.ts +1 -1
  104. package/esm/core/ast.js +1 -1
  105. package/esm/core/codegen/babel-ast.d.ts +1 -1
  106. package/esm/core/codegen/babel-ast.js +2 -2
  107. package/esm/core/codegen/barrel.d.ts +0 -6
  108. package/esm/core/codegen/barrel.js +23 -20
  109. package/esm/core/codegen/client.d.ts +2 -12
  110. package/esm/core/codegen/client.js +7 -21
  111. package/esm/core/codegen/custom-mutations.d.ts +0 -14
  112. package/esm/core/codegen/custom-mutations.js +141 -90
  113. package/esm/core/codegen/custom-queries.d.ts +0 -14
  114. package/esm/core/codegen/custom-queries.js +486 -196
  115. package/esm/core/codegen/hooks-ast.d.ts +75 -0
  116. package/esm/core/codegen/hooks-ast.js +424 -0
  117. package/esm/core/codegen/index.d.ts +16 -18
  118. package/esm/core/codegen/index.js +26 -71
  119. package/esm/core/codegen/invalidation.d.ts +1 -7
  120. package/esm/core/codegen/invalidation.js +51 -17
  121. package/esm/core/codegen/mutation-keys.d.ts +1 -10
  122. package/esm/core/codegen/mutation-keys.js +23 -9
  123. package/esm/core/codegen/mutations.d.ts +0 -13
  124. package/esm/core/codegen/mutations.js +302 -367
  125. package/esm/core/codegen/orm/barrel.d.ts +0 -5
  126. package/esm/core/codegen/orm/barrel.js +6 -1
  127. package/esm/core/codegen/orm/client-generator.d.ts +0 -5
  128. package/esm/core/codegen/orm/client-generator.js +7 -2
  129. package/esm/core/codegen/orm/client.js +3 -1
  130. package/esm/core/codegen/orm/custom-ops-generator.d.ts +0 -6
  131. package/esm/core/codegen/orm/custom-ops-generator.js +103 -50
  132. package/esm/core/codegen/orm/index.d.ts +4 -4
  133. package/esm/core/codegen/orm/index.js +25 -12
  134. package/esm/core/codegen/orm/input-types-generator.d.ts +1 -13
  135. package/esm/core/codegen/orm/input-types-generator.js +85 -23
  136. package/esm/core/codegen/orm/model-generator.d.ts +0 -5
  137. package/esm/core/codegen/orm/model-generator.js +310 -132
  138. package/esm/core/codegen/orm/select-types.d.ts +19 -14
  139. package/esm/core/codegen/queries.d.ts +0 -8
  140. package/esm/core/codegen/queries.js +362 -561
  141. package/esm/core/codegen/query-keys.d.ts +1 -1
  142. package/esm/core/codegen/query-keys.js +38 -24
  143. package/esm/core/codegen/scalars.js +3 -1
  144. package/esm/core/codegen/schema-types-generator.d.ts +1 -1
  145. package/esm/core/codegen/schema-types-generator.js +17 -2
  146. package/esm/core/codegen/select-helpers.d.ts +19 -0
  147. package/esm/core/codegen/select-helpers.js +35 -0
  148. package/esm/core/codegen/selection.d.ts +4 -0
  149. package/esm/core/codegen/selection.js +29 -0
  150. package/esm/core/codegen/shared/index.d.ts +2 -15
  151. package/esm/core/codegen/shared/index.js +16 -3
  152. package/esm/core/codegen/type-resolver.d.ts +1 -5
  153. package/esm/core/codegen/type-resolver.js +1 -22
  154. package/esm/core/codegen/types.d.ts +0 -3
  155. package/esm/core/codegen/types.js +72 -15
  156. package/esm/core/codegen/utils.d.ts +1 -4
  157. package/esm/core/codegen/utils.js +4 -1
  158. package/esm/core/config/index.d.ts +1 -1
  159. package/esm/core/config/resolver.js +2 -4
  160. package/esm/core/generate.js +38 -50
  161. package/esm/core/index.d.ts +3 -3
  162. package/esm/core/index.js +2 -3
  163. package/esm/core/introspect/index.d.ts +6 -6
  164. package/esm/core/introspect/index.js +3 -6
  165. package/esm/core/introspect/infer-tables.d.ts +0 -14
  166. package/esm/core/introspect/infer-tables.js +16 -2
  167. package/esm/core/introspect/source/database.js +2 -2
  168. package/esm/core/introspect/source/endpoint.d.ts +0 -6
  169. package/esm/core/introspect/source/endpoint.js +7 -1
  170. package/esm/core/introspect/source/index.d.ts +4 -4
  171. package/esm/core/introspect/source/index.js +6 -10
  172. package/esm/core/introspect/source/pgpm-module.js +3 -3
  173. package/esm/core/introspect/transform-schema.d.ts +2 -2
  174. package/esm/core/introspect/transform-schema.js +2 -2
  175. package/esm/core/output/index.d.ts +1 -1
  176. package/esm/core/output/index.js +1 -1
  177. package/esm/core/output/writer.d.ts +3 -0
  178. package/esm/core/output/writer.js +20 -1
  179. package/esm/core/pipeline/index.d.ts +2 -2
  180. package/esm/core/pipeline/index.js +2 -2
  181. package/esm/core/query-builder.d.ts +2 -2
  182. package/esm/core/query-builder.js +2 -2
  183. package/esm/core/watch/index.d.ts +4 -4
  184. package/esm/core/watch/index.js +3 -3
  185. package/esm/core/watch/orchestrator.js +5 -3
  186. package/esm/generators/index.d.ts +3 -3
  187. package/esm/generators/index.js +3 -3
  188. package/esm/generators/mutations.d.ts +1 -1
  189. package/esm/generators/select.d.ts +1 -1
  190. package/esm/index.d.ts +3 -3
  191. package/esm/index.js +1 -4
  192. package/esm/types/config.d.ts +0 -10
  193. package/esm/types/config.js +0 -2
  194. package/esm/types/index.d.ts +6 -6
  195. package/esm/types/index.js +1 -1
  196. package/generators/index.d.ts +3 -3
  197. package/generators/index.js +8 -8
  198. package/generators/mutations.d.ts +1 -1
  199. package/generators/select.d.ts +1 -1
  200. package/index.d.ts +3 -3
  201. package/index.js +11 -5
  202. package/package.json +11 -11
  203. package/types/config.d.ts +0 -10
  204. package/types/config.js +0 -2
  205. package/types/index.d.ts +6 -6
  206. package/types/index.js +2 -2
  207. package/core/codegen/gql-ast.d.ts +0 -41
  208. package/core/codegen/gql-ast.js +0 -353
  209. package/core/codegen/schema-gql-ast.d.ts +0 -51
  210. package/core/codegen/schema-gql-ast.js +0 -385
  211. package/core/codegen/templates/client.browser.ts +0 -271
  212. package/core/codegen/templates/client.node.ts +0 -337
  213. package/esm/core/codegen/gql-ast.d.ts +0 -41
  214. package/esm/core/codegen/gql-ast.js +0 -312
  215. package/esm/core/codegen/schema-gql-ast.d.ts +0 -51
  216. package/esm/core/codegen/schema-gql-ast.js +0 -343
@@ -1,385 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.buildVariableDefinitions = buildVariableDefinitions;
37
- exports.buildFieldSelections = buildFieldSelections;
38
- exports.buildCustomQueryAST = buildCustomQueryAST;
39
- exports.buildCustomMutationAST = buildCustomMutationAST;
40
- exports.printGraphQL = printGraphQL;
41
- exports.buildCustomQueryString = buildCustomQueryString;
42
- exports.buildCustomMutationString = buildCustomMutationString;
43
- /**
44
- * Dynamic GraphQL AST builders for custom operations
45
- *
46
- * Generates GraphQL query/mutation documents from CleanOperation data
47
- * using gql-ast library for proper AST construction.
48
- */
49
- const t = __importStar(require("gql-ast"));
50
- const graphql_1 = require("graphql");
51
- const type_resolver_1 = require("./type-resolver");
52
- // ============================================================================
53
- // Type Node Builders (GraphQL Type AST)
54
- // ============================================================================
55
- /**
56
- * Build a GraphQL type node from CleanTypeRef
57
- * Handles NON_NULL, LIST, and named types
58
- */
59
- function buildTypeNode(typeRef) {
60
- switch (typeRef.kind) {
61
- case 'NON_NULL':
62
- if (typeRef.ofType) {
63
- const innerType = buildTypeNode(typeRef.ofType);
64
- // Can't wrap NON_NULL in NON_NULL
65
- if (innerType.kind === 'NonNullType') {
66
- return innerType;
67
- }
68
- return t.nonNullType({ type: innerType });
69
- }
70
- return t.namedType({ type: 'String' });
71
- case 'LIST':
72
- if (typeRef.ofType) {
73
- return t.listType({ type: buildTypeNode(typeRef.ofType) });
74
- }
75
- return t.listType({ type: t.namedType({ type: 'String' }) });
76
- case 'SCALAR':
77
- case 'ENUM':
78
- case 'OBJECT':
79
- case 'INPUT_OBJECT':
80
- return t.namedType({ type: typeRef.name ?? 'String' });
81
- default:
82
- return t.namedType({ type: typeRef.name ?? 'String' });
83
- }
84
- }
85
- // ============================================================================
86
- // Variable Definition Builders
87
- // ============================================================================
88
- /**
89
- * Build variable definitions from operation arguments
90
- */
91
- function buildVariableDefinitions(args) {
92
- return args.map((arg) => t.variableDefinition({
93
- variable: t.variable({ name: arg.name }),
94
- type: buildTypeNode(arg.type),
95
- }));
96
- }
97
- /**
98
- * Build argument nodes that reference variables
99
- */
100
- function buildArgumentNodes(args) {
101
- return args.map((arg) => t.argument({
102
- name: arg.name,
103
- value: t.variable({ name: arg.name }),
104
- }));
105
- }
106
- // ============================================================================
107
- // Field Selection Builders
108
- // ============================================================================
109
- /**
110
- * Check if a type should have selections (is an object type)
111
- */
112
- function typeNeedsSelections(typeRef) {
113
- const baseKind = (0, type_resolver_1.getBaseTypeKind)(typeRef);
114
- return baseKind === 'OBJECT';
115
- }
116
- /**
117
- * Get the resolved fields for a type reference
118
- * Uses type registry for deep resolution
119
- */
120
- function getResolvedFields(typeRef, typeRegistry) {
121
- // First check if fields are directly on the typeRef
122
- if (typeRef.fields) {
123
- return typeRef.fields;
124
- }
125
- // For wrapper types, unwrap and check
126
- if (typeRef.ofType) {
127
- return getResolvedFields(typeRef.ofType, typeRegistry);
128
- }
129
- // Look up in type registry
130
- if (typeRegistry && typeRef.name) {
131
- const resolved = typeRegistry.get(typeRef.name);
132
- if (resolved?.fields) {
133
- return resolved.fields;
134
- }
135
- }
136
- return undefined;
137
- }
138
- /**
139
- * Build field selections for an object type
140
- * Recursively handles nested objects up to maxDepth
141
- */
142
- function buildFieldSelections(typeRef, config, currentDepth = 0) {
143
- const { maxDepth, skipQueryField, typeRegistry } = config;
144
- // Stop recursion at max depth
145
- if (currentDepth >= maxDepth) {
146
- return [];
147
- }
148
- const fields = getResolvedFields(typeRef, typeRegistry);
149
- if (!fields || fields.length === 0) {
150
- return [];
151
- }
152
- const selections = [];
153
- for (const field of fields) {
154
- // Skip internal fields
155
- if ((0, type_resolver_1.shouldSkipField)(field.name, skipQueryField)) {
156
- continue;
157
- }
158
- const fieldKind = (0, type_resolver_1.getBaseTypeKind)(field.type);
159
- // For scalar and enum types, just add the field
160
- if (fieldKind === 'SCALAR' || fieldKind === 'ENUM') {
161
- selections.push(t.field({ name: field.name }));
162
- continue;
163
- }
164
- // For object types, recurse if within depth limit
165
- if (fieldKind === 'OBJECT' && currentDepth < maxDepth - 1) {
166
- const nestedSelections = buildFieldSelections(field.type, config, currentDepth + 1);
167
- if (nestedSelections.length > 0) {
168
- selections.push(t.field({
169
- name: field.name,
170
- selectionSet: t.selectionSet({ selections: nestedSelections }),
171
- }));
172
- }
173
- }
174
- }
175
- return selections;
176
- }
177
- /**
178
- * Build selections for a return type, handling connections and payloads
179
- */
180
- function buildReturnTypeSelections(returnType, config) {
181
- const fields = getResolvedFields(returnType, config.typeRegistry);
182
- if (!fields || fields.length === 0) {
183
- return [];
184
- }
185
- // Check if this is a connection type
186
- const hasNodes = fields.some((f) => f.name === 'nodes');
187
- const hasTotalCount = fields.some((f) => f.name === 'totalCount');
188
- if (hasNodes && hasTotalCount) {
189
- return buildConnectionSelections(fields, config);
190
- }
191
- // Check if this is a mutation payload (has clientMutationId)
192
- const hasClientMutationId = fields.some((f) => f.name === 'clientMutationId');
193
- if (hasClientMutationId) {
194
- return buildPayloadSelections(fields, config);
195
- }
196
- // Regular object - build normal selections
197
- return buildFieldSelections(returnType, config);
198
- }
199
- /**
200
- * Build selections for a connection type
201
- */
202
- function buildConnectionSelections(fields, config) {
203
- const selections = [];
204
- // Add totalCount
205
- const totalCountField = fields.find((f) => f.name === 'totalCount');
206
- if (totalCountField) {
207
- selections.push(t.field({ name: 'totalCount' }));
208
- }
209
- // Add nodes with nested selections
210
- const nodesField = fields.find((f) => f.name === 'nodes');
211
- if (nodesField) {
212
- const nodeSelections = buildFieldSelections(nodesField.type, config);
213
- if (nodeSelections.length > 0) {
214
- selections.push(t.field({
215
- name: 'nodes',
216
- selectionSet: t.selectionSet({ selections: nodeSelections }),
217
- }));
218
- }
219
- }
220
- // Add pageInfo
221
- const pageInfoField = fields.find((f) => f.name === 'pageInfo');
222
- if (pageInfoField) {
223
- selections.push(t.field({
224
- name: 'pageInfo',
225
- selectionSet: t.selectionSet({
226
- selections: [
227
- t.field({ name: 'hasNextPage' }),
228
- t.field({ name: 'hasPreviousPage' }),
229
- t.field({ name: 'startCursor' }),
230
- t.field({ name: 'endCursor' }),
231
- ],
232
- }),
233
- }));
234
- }
235
- return selections;
236
- }
237
- /**
238
- * Build selections for a mutation payload type
239
- */
240
- function buildPayloadSelections(fields, config) {
241
- const selections = [];
242
- for (const field of fields) {
243
- // Skip query field
244
- if ((0, type_resolver_1.shouldSkipField)(field.name, config.skipQueryField)) {
245
- continue;
246
- }
247
- const fieldKind = (0, type_resolver_1.getBaseTypeKind)(field.type);
248
- // Add scalar fields directly
249
- if (fieldKind === 'SCALAR' || fieldKind === 'ENUM') {
250
- selections.push(t.field({ name: field.name }));
251
- continue;
252
- }
253
- // For object fields (like the returned entity), add with selections
254
- if (fieldKind === 'OBJECT') {
255
- const nestedSelections = buildFieldSelections(field.type, config);
256
- if (nestedSelections.length > 0) {
257
- selections.push(t.field({
258
- name: field.name,
259
- selectionSet: t.selectionSet({ selections: nestedSelections }),
260
- }));
261
- }
262
- }
263
- }
264
- return selections;
265
- }
266
- /**
267
- * Build a custom query AST from a CleanOperation
268
- */
269
- function buildCustomQueryAST(config) {
270
- const { operation, typeRegistry, maxDepth = 2, skipQueryField = true, } = config;
271
- const operationName = `${ucFirst(operation.name)}Query`;
272
- // Build variable definitions
273
- const variableDefinitions = buildVariableDefinitions(operation.args);
274
- // Build arguments that reference the variables
275
- const args = buildArgumentNodes(operation.args);
276
- // Build return type selections
277
- const fieldSelectionConfig = {
278
- maxDepth,
279
- skipQueryField,
280
- typeRegistry,
281
- };
282
- const returnTypeNeedsSelections = typeNeedsSelections(operation.returnType);
283
- let selections = [];
284
- if (returnTypeNeedsSelections) {
285
- selections = buildReturnTypeSelections(operation.returnType, fieldSelectionConfig);
286
- }
287
- // Build the query field
288
- const queryField = selections.length > 0
289
- ? t.field({
290
- name: operation.name,
291
- args: args.length > 0 ? args : undefined,
292
- selectionSet: t.selectionSet({ selections }),
293
- })
294
- : t.field({
295
- name: operation.name,
296
- args: args.length > 0 ? args : undefined,
297
- });
298
- return t.document({
299
- definitions: [
300
- t.operationDefinition({
301
- operation: 'query',
302
- name: operationName,
303
- variableDefinitions: variableDefinitions.length > 0 ? variableDefinitions : undefined,
304
- selectionSet: t.selectionSet({
305
- selections: [queryField],
306
- }),
307
- }),
308
- ],
309
- });
310
- }
311
- /**
312
- * Build a custom mutation AST from a CleanOperation
313
- */
314
- function buildCustomMutationAST(config) {
315
- const { operation, typeRegistry, maxDepth = 2, skipQueryField = true, } = config;
316
- const operationName = `${ucFirst(operation.name)}Mutation`;
317
- // Build variable definitions
318
- const variableDefinitions = buildVariableDefinitions(operation.args);
319
- // Build arguments that reference the variables
320
- const args = buildArgumentNodes(operation.args);
321
- // Build return type selections
322
- const fieldSelectionConfig = {
323
- maxDepth,
324
- skipQueryField,
325
- typeRegistry,
326
- };
327
- const returnTypeNeedsSelections = typeNeedsSelections(operation.returnType);
328
- let selections = [];
329
- if (returnTypeNeedsSelections) {
330
- selections = buildReturnTypeSelections(operation.returnType, fieldSelectionConfig);
331
- }
332
- // Build the mutation field
333
- const mutationField = selections.length > 0
334
- ? t.field({
335
- name: operation.name,
336
- args: args.length > 0 ? args : undefined,
337
- selectionSet: t.selectionSet({ selections }),
338
- })
339
- : t.field({
340
- name: operation.name,
341
- args: args.length > 0 ? args : undefined,
342
- });
343
- return t.document({
344
- definitions: [
345
- t.operationDefinition({
346
- operation: 'mutation',
347
- name: operationName,
348
- variableDefinitions: variableDefinitions.length > 0 ? variableDefinitions : undefined,
349
- selectionSet: t.selectionSet({
350
- selections: [mutationField],
351
- }),
352
- }),
353
- ],
354
- });
355
- }
356
- // ============================================================================
357
- // Print Utilities
358
- // ============================================================================
359
- /**
360
- * Print a document AST to GraphQL string
361
- */
362
- function printGraphQL(ast) {
363
- return (0, graphql_1.print)(ast);
364
- }
365
- /**
366
- * Build and print a custom query in one call
367
- */
368
- function buildCustomQueryString(config) {
369
- return printGraphQL(buildCustomQueryAST(config));
370
- }
371
- /**
372
- * Build and print a custom mutation in one call
373
- */
374
- function buildCustomMutationString(config) {
375
- return printGraphQL(buildCustomMutationAST(config));
376
- }
377
- // ============================================================================
378
- // Helper Utilities
379
- // ============================================================================
380
- /**
381
- * Uppercase first character
382
- */
383
- function ucFirst(str) {
384
- return str.charAt(0).toUpperCase() + str.slice(1);
385
- }
@@ -1,271 +0,0 @@
1
- /**
2
- * GraphQL client configuration and execution (Browser-compatible)
3
- *
4
- * This is the RUNTIME code that gets copied to generated output.
5
- * Uses native W3C fetch API for browser compatibility.
6
- *
7
- * NOTE: This file is read at codegen time and written to output.
8
- * Any changes here will affect all generated clients.
9
- */
10
-
11
- // ============================================================================
12
- // Configuration
13
- // ============================================================================
14
-
15
- export interface GraphQLClientConfig {
16
- /** GraphQL endpoint URL */
17
- endpoint: string;
18
- /** Default headers to include in all requests */
19
- headers?: Record<string, string>;
20
- /** Dynamic headers callback called on every request */
21
- getHeaders?: () => Record<string, string>;
22
- }
23
-
24
- let globalConfig: GraphQLClientConfig | null = null;
25
-
26
- /**
27
- * Configure the GraphQL client
28
- *
29
- * @example
30
- * ```ts
31
- * import { configure } from './generated';
32
- *
33
- * configure({
34
- * endpoint: 'https://api.example.com/graphql',
35
- * headers: {
36
- * Authorization: 'Bearer <token>',
37
- * },
38
- * });
39
- * ```
40
- */
41
- export function configure(config: GraphQLClientConfig): void {
42
- globalConfig = config;
43
- }
44
-
45
- /**
46
- * Get the current configuration
47
- * @throws Error if not configured
48
- */
49
- export function getConfig(): GraphQLClientConfig {
50
- if (!globalConfig) {
51
- throw new Error(
52
- 'GraphQL client not configured. Call configure() before making requests.'
53
- );
54
- }
55
- return globalConfig;
56
- }
57
-
58
- /**
59
- * Set a single header value
60
- * Useful for updating Authorization after login
61
- *
62
- * @example
63
- * ```ts
64
- * setHeader('Authorization', 'Bearer <new-token>');
65
- * ```
66
- */
67
- export function setHeader(key: string, value: string): void {
68
- const config = getConfig();
69
- globalConfig = {
70
- ...config,
71
- headers: { ...config.headers, [key]: value },
72
- };
73
- }
74
-
75
- /**
76
- * Merge multiple headers into the current configuration
77
- *
78
- * @example
79
- * ```ts
80
- * setHeaders({ Authorization: 'Bearer <token>', 'X-Custom': 'value' });
81
- * ```
82
- */
83
- export function setHeaders(headers: Record<string, string>): void {
84
- const config = getConfig();
85
- globalConfig = {
86
- ...config,
87
- headers: { ...config.headers, ...headers },
88
- };
89
- }
90
-
91
- // ============================================================================
92
- // Error handling
93
- // ============================================================================
94
-
95
- export interface GraphQLError {
96
- message: string;
97
- locations?: Array<{ line: number; column: number }>;
98
- path?: Array<string | number>;
99
- extensions?: Record<string, unknown>;
100
- }
101
-
102
- export class GraphQLClientError extends Error {
103
- constructor(
104
- message: string,
105
- public errors: GraphQLError[],
106
- public response?: Response
107
- ) {
108
- super(message);
109
- this.name = 'GraphQLClientError';
110
- }
111
- }
112
-
113
- // ============================================================================
114
- // Execution
115
- // ============================================================================
116
-
117
- export interface ExecuteOptions {
118
- /** Override headers for this request */
119
- headers?: Record<string, string>;
120
- /** AbortSignal for request cancellation */
121
- signal?: AbortSignal;
122
- }
123
-
124
- /**
125
- * Execute a GraphQL operation
126
- *
127
- * @example
128
- * ```ts
129
- * const result = await execute<CarsQueryResult, CarsQueryVariables>(
130
- * carsQueryDocument,
131
- * { first: 10 }
132
- * );
133
- * ```
134
- */
135
- export async function execute<
136
- TData = unknown,
137
- TVariables = Record<string, unknown>,
138
- >(
139
- document: string,
140
- variables?: TVariables,
141
- options?: ExecuteOptions
142
- ): Promise<TData> {
143
- const config = getConfig();
144
- const dynamicHeaders = config.getHeaders?.() ?? {};
145
-
146
- const response = await fetch(config.endpoint, {
147
- method: 'POST',
148
- headers: {
149
- 'Content-Type': 'application/json',
150
- ...config.headers,
151
- ...dynamicHeaders,
152
- ...options?.headers,
153
- },
154
- body: JSON.stringify({
155
- query: document,
156
- variables,
157
- }),
158
- signal: options?.signal,
159
- });
160
-
161
- const json = await response.json();
162
-
163
- if (json.errors && json.errors.length > 0) {
164
- throw new GraphQLClientError(
165
- json.errors[0].message || 'GraphQL request failed',
166
- json.errors,
167
- response
168
- );
169
- }
170
-
171
- return json.data as TData;
172
- }
173
-
174
- /**
175
- * Execute a GraphQL operation with full response (data + errors)
176
- * Useful when you want to handle partial data with errors
177
- */
178
- export async function executeWithErrors<
179
- TData = unknown,
180
- TVariables = Record<string, unknown>,
181
- >(
182
- document: string,
183
- variables?: TVariables,
184
- options?: ExecuteOptions
185
- ): Promise<{ data: TData | null; errors: GraphQLError[] | null }> {
186
- const config = getConfig();
187
- const dynamicHeaders = config.getHeaders?.() ?? {};
188
-
189
- const response = await fetch(config.endpoint, {
190
- method: 'POST',
191
- headers: {
192
- 'Content-Type': 'application/json',
193
- ...config.headers,
194
- ...dynamicHeaders,
195
- ...options?.headers,
196
- },
197
- body: JSON.stringify({
198
- query: document,
199
- variables,
200
- }),
201
- signal: options?.signal,
202
- });
203
-
204
- const json = await response.json();
205
-
206
- return {
207
- data: json.data ?? null,
208
- errors: json.errors ?? null,
209
- };
210
- }
211
-
212
- // ============================================================================
213
- // QueryClient Factory
214
- // ============================================================================
215
-
216
- /**
217
- * Default QueryClient configuration optimized for GraphQL
218
- *
219
- * These defaults provide a good balance between freshness and performance:
220
- * - staleTime: 1 minute - data considered fresh, won't refetch
221
- * - gcTime: 5 minutes - unused data kept in cache
222
- * - refetchOnWindowFocus: false - don't refetch when tab becomes active
223
- * - retry: 1 - retry failed requests once
224
- */
225
- export const defaultQueryClientOptions = {
226
- defaultOptions: {
227
- queries: {
228
- staleTime: 1000 * 60, // 1 minute
229
- gcTime: 1000 * 60 * 5, // 5 minutes
230
- refetchOnWindowFocus: false,
231
- retry: 1,
232
- },
233
- },
234
- };
235
-
236
- /**
237
- * QueryClient options type for createQueryClient
238
- */
239
- export interface CreateQueryClientOptions {
240
- defaultOptions?: {
241
- queries?: {
242
- staleTime?: number;
243
- gcTime?: number;
244
- refetchOnWindowFocus?: boolean;
245
- retry?: number | boolean;
246
- retryDelay?: number | ((attemptIndex: number) => number);
247
- };
248
- mutations?: {
249
- retry?: number | boolean;
250
- retryDelay?: number | ((attemptIndex: number) => number);
251
- };
252
- };
253
- }
254
-
255
- // Note: createQueryClient is available when using with @tanstack/react-query
256
- // Import QueryClient from '@tanstack/react-query' and use these options:
257
- //
258
- // import { QueryClient } from '@tanstack/react-query';
259
- // const queryClient = new QueryClient(defaultQueryClientOptions);
260
- //
261
- // Or merge with your own options:
262
- // const queryClient = new QueryClient({
263
- // ...defaultQueryClientOptions,
264
- // defaultOptions: {
265
- // ...defaultQueryClientOptions.defaultOptions,
266
- // queries: {
267
- // ...defaultQueryClientOptions.defaultOptions.queries,
268
- // staleTime: 30000, // Override specific options
269
- // },
270
- // },
271
- // });