@constructive-io/graphql-codegen 2.19.0 → 2.20.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 (301) hide show
  1. package/README.md +1818 -113
  2. package/__tests__/codegen/input-types-generator.test.d.ts +1 -0
  3. package/__tests__/codegen/input-types-generator.test.js +635 -0
  4. package/cli/codegen/barrel.d.ts +27 -0
  5. package/cli/codegen/barrel.js +163 -0
  6. package/cli/codegen/client.d.ts +4 -0
  7. package/cli/codegen/client.js +170 -0
  8. package/cli/codegen/custom-mutations.d.ts +38 -0
  9. package/cli/codegen/custom-mutations.js +149 -0
  10. package/cli/codegen/custom-queries.d.ts +38 -0
  11. package/cli/codegen/custom-queries.js +358 -0
  12. package/cli/codegen/filters.d.ts +27 -0
  13. package/cli/codegen/filters.js +357 -0
  14. package/cli/codegen/gql-ast.d.ts +41 -0
  15. package/cli/codegen/gql-ast.js +329 -0
  16. package/cli/codegen/index.d.ts +71 -0
  17. package/cli/codegen/index.js +147 -0
  18. package/cli/codegen/mutations.d.ts +30 -0
  19. package/cli/codegen/mutations.js +410 -0
  20. package/cli/codegen/orm/barrel.d.ts +18 -0
  21. package/cli/codegen/orm/barrel.js +48 -0
  22. package/cli/codegen/orm/client-generator.d.ts +45 -0
  23. package/cli/codegen/orm/client-generator.js +646 -0
  24. package/cli/codegen/orm/custom-ops-generator.d.ts +30 -0
  25. package/cli/codegen/orm/custom-ops-generator.js +350 -0
  26. package/cli/codegen/orm/index.d.ts +38 -0
  27. package/cli/codegen/orm/index.js +88 -0
  28. package/cli/codegen/orm/input-types-generator.d.ts +21 -0
  29. package/cli/codegen/orm/input-types-generator.js +705 -0
  30. package/cli/codegen/orm/input-types-generator.test.d.ts +1 -0
  31. package/cli/codegen/orm/input-types-generator.test.js +75 -0
  32. package/cli/codegen/orm/model-generator.d.ts +32 -0
  33. package/cli/codegen/orm/model-generator.js +264 -0
  34. package/cli/codegen/orm/query-builder.d.ts +161 -0
  35. package/cli/codegen/orm/query-builder.js +366 -0
  36. package/cli/codegen/orm/select-types.d.ts +169 -0
  37. package/cli/codegen/orm/select-types.js +16 -0
  38. package/cli/codegen/orm/select-types.test.d.ts +11 -0
  39. package/cli/codegen/orm/select-types.test.js +22 -0
  40. package/cli/codegen/queries.d.ts +25 -0
  41. package/cli/codegen/queries.js +438 -0
  42. package/cli/codegen/scalars.d.ts +12 -0
  43. package/cli/codegen/scalars.js +71 -0
  44. package/cli/codegen/schema-gql-ast.d.ts +51 -0
  45. package/cli/codegen/schema-gql-ast.js +385 -0
  46. package/cli/codegen/ts-ast.d.ts +122 -0
  47. package/cli/codegen/ts-ast.js +280 -0
  48. package/cli/codegen/type-resolver.d.ts +96 -0
  49. package/cli/codegen/type-resolver.js +246 -0
  50. package/cli/codegen/types.d.ts +12 -0
  51. package/cli/codegen/types.js +69 -0
  52. package/cli/codegen/utils.d.ts +163 -0
  53. package/cli/codegen/utils.js +326 -0
  54. package/cli/commands/generate-orm.d.ts +37 -0
  55. package/cli/commands/generate-orm.js +195 -0
  56. package/cli/commands/generate.d.ts +39 -0
  57. package/cli/commands/generate.js +299 -0
  58. package/cli/commands/index.d.ts +7 -0
  59. package/cli/commands/index.js +12 -0
  60. package/cli/commands/init.d.ts +35 -0
  61. package/cli/commands/init.js +176 -0
  62. package/cli/index.d.ts +4 -0
  63. package/cli/index.js +291 -0
  64. package/cli/introspect/fetch-meta.d.ts +31 -0
  65. package/cli/introspect/fetch-meta.js +108 -0
  66. package/cli/introspect/fetch-schema.d.ts +21 -0
  67. package/cli/introspect/fetch-schema.js +86 -0
  68. package/cli/introspect/index.d.ts +8 -0
  69. package/cli/introspect/index.js +16 -0
  70. package/cli/introspect/meta-query.d.ts +111 -0
  71. package/cli/introspect/meta-query.js +191 -0
  72. package/cli/introspect/schema-query.d.ts +20 -0
  73. package/cli/introspect/schema-query.js +123 -0
  74. package/cli/introspect/transform-schema.d.ts +74 -0
  75. package/cli/introspect/transform-schema.js +269 -0
  76. package/cli/introspect/transform-schema.test.d.ts +1 -0
  77. package/cli/introspect/transform-schema.test.js +67 -0
  78. package/cli/introspect/transform.d.ts +21 -0
  79. package/cli/introspect/transform.js +216 -0
  80. package/cli/watch/cache.d.ts +45 -0
  81. package/cli/watch/cache.js +111 -0
  82. package/cli/watch/debounce.d.ts +19 -0
  83. package/cli/watch/debounce.js +89 -0
  84. package/cli/watch/hash.d.ts +17 -0
  85. package/cli/watch/hash.js +48 -0
  86. package/cli/watch/index.d.ts +10 -0
  87. package/cli/watch/index.js +22 -0
  88. package/cli/watch/orchestrator.d.ts +63 -0
  89. package/cli/watch/orchestrator.js +228 -0
  90. package/cli/watch/poller.d.ts +65 -0
  91. package/cli/watch/poller.js +203 -0
  92. package/cli/watch/types.d.ts +67 -0
  93. package/cli/watch/types.js +5 -0
  94. package/client/error.d.ts +95 -0
  95. package/client/error.js +255 -0
  96. package/client/execute.d.ts +57 -0
  97. package/client/execute.js +124 -0
  98. package/client/index.d.ts +6 -0
  99. package/client/index.js +18 -0
  100. package/client/typed-document.d.ts +31 -0
  101. package/client/typed-document.js +44 -0
  102. package/core/ast.d.ts +10 -0
  103. package/core/ast.js +593 -0
  104. package/core/custom-ast.d.ts +35 -0
  105. package/core/custom-ast.js +204 -0
  106. package/core/index.d.ts +8 -0
  107. package/core/index.js +33 -0
  108. package/core/meta-object/convert.d.ts +65 -0
  109. package/core/meta-object/convert.js +63 -0
  110. package/core/meta-object/format.json +93 -0
  111. package/core/meta-object/index.d.ts +2 -0
  112. package/core/meta-object/index.js +18 -0
  113. package/core/meta-object/validate.d.ts +9 -0
  114. package/core/meta-object/validate.js +34 -0
  115. package/core/query-builder.d.ts +46 -0
  116. package/core/query-builder.js +412 -0
  117. package/core/types.d.ts +139 -0
  118. package/core/types.js +28 -0
  119. package/esm/__tests__/codegen/input-types-generator.test.d.ts +1 -0
  120. package/esm/__tests__/codegen/input-types-generator.test.js +633 -0
  121. package/esm/cli/codegen/barrel.d.ts +27 -0
  122. package/esm/cli/codegen/barrel.js +156 -0
  123. package/esm/cli/codegen/client.d.ts +4 -0
  124. package/esm/cli/codegen/client.js +167 -0
  125. package/esm/cli/codegen/custom-mutations.d.ts +38 -0
  126. package/esm/cli/codegen/custom-mutations.js +145 -0
  127. package/esm/cli/codegen/custom-queries.d.ts +38 -0
  128. package/esm/cli/codegen/custom-queries.js +354 -0
  129. package/esm/cli/codegen/filters.d.ts +27 -0
  130. package/esm/cli/codegen/filters.js +351 -0
  131. package/esm/cli/codegen/gql-ast.d.ts +41 -0
  132. package/esm/cli/codegen/gql-ast.js +288 -0
  133. package/esm/cli/codegen/index.d.ts +71 -0
  134. package/esm/cli/codegen/index.js +124 -0
  135. package/esm/cli/codegen/mutations.d.ts +30 -0
  136. package/esm/cli/codegen/mutations.js +404 -0
  137. package/esm/cli/codegen/orm/barrel.d.ts +18 -0
  138. package/esm/cli/codegen/orm/barrel.js +44 -0
  139. package/esm/cli/codegen/orm/client-generator.d.ts +45 -0
  140. package/esm/cli/codegen/orm/client-generator.js +640 -0
  141. package/esm/cli/codegen/orm/custom-ops-generator.d.ts +30 -0
  142. package/esm/cli/codegen/orm/custom-ops-generator.js +346 -0
  143. package/esm/cli/codegen/orm/index.d.ts +38 -0
  144. package/esm/cli/codegen/orm/index.js +75 -0
  145. package/esm/cli/codegen/orm/input-types-generator.d.ts +21 -0
  146. package/esm/cli/codegen/orm/input-types-generator.js +700 -0
  147. package/esm/cli/codegen/orm/input-types-generator.test.d.ts +1 -0
  148. package/esm/cli/codegen/orm/input-types-generator.test.js +73 -0
  149. package/esm/cli/codegen/orm/model-generator.d.ts +32 -0
  150. package/esm/cli/codegen/orm/model-generator.js +260 -0
  151. package/esm/cli/codegen/orm/query-builder.d.ts +161 -0
  152. package/esm/cli/codegen/orm/query-builder.js +353 -0
  153. package/esm/cli/codegen/orm/select-types.d.ts +169 -0
  154. package/esm/cli/codegen/orm/select-types.js +15 -0
  155. package/esm/cli/codegen/orm/select-types.test.d.ts +11 -0
  156. package/esm/cli/codegen/orm/select-types.test.js +21 -0
  157. package/esm/cli/codegen/queries.d.ts +25 -0
  158. package/esm/cli/codegen/queries.js +433 -0
  159. package/esm/cli/codegen/scalars.d.ts +12 -0
  160. package/esm/cli/codegen/scalars.js +66 -0
  161. package/esm/cli/codegen/schema-gql-ast.d.ts +51 -0
  162. package/esm/cli/codegen/schema-gql-ast.js +343 -0
  163. package/esm/cli/codegen/ts-ast.d.ts +122 -0
  164. package/esm/cli/codegen/ts-ast.js +260 -0
  165. package/esm/cli/codegen/type-resolver.d.ts +96 -0
  166. package/esm/cli/codegen/type-resolver.js +224 -0
  167. package/esm/cli/codegen/types.d.ts +12 -0
  168. package/esm/cli/codegen/types.js +65 -0
  169. package/esm/cli/codegen/utils.d.ts +163 -0
  170. package/esm/cli/codegen/utils.js +288 -0
  171. package/esm/cli/commands/generate-orm.d.ts +37 -0
  172. package/esm/cli/commands/generate-orm.js +192 -0
  173. package/esm/cli/commands/generate.d.ts +39 -0
  174. package/esm/cli/commands/generate.js +262 -0
  175. package/esm/cli/commands/index.d.ts +7 -0
  176. package/esm/cli/commands/index.js +5 -0
  177. package/esm/cli/commands/init.d.ts +35 -0
  178. package/esm/cli/commands/init.js +138 -0
  179. package/esm/cli/index.d.ts +4 -0
  180. package/esm/cli/index.js +256 -0
  181. package/esm/cli/introspect/fetch-meta.d.ts +31 -0
  182. package/esm/cli/introspect/fetch-meta.js +104 -0
  183. package/esm/cli/introspect/fetch-schema.d.ts +21 -0
  184. package/esm/cli/introspect/fetch-schema.js +83 -0
  185. package/esm/cli/introspect/index.d.ts +8 -0
  186. package/esm/cli/introspect/index.js +6 -0
  187. package/esm/cli/introspect/meta-query.d.ts +111 -0
  188. package/esm/cli/introspect/meta-query.js +188 -0
  189. package/esm/cli/introspect/schema-query.d.ts +20 -0
  190. package/esm/cli/introspect/schema-query.js +120 -0
  191. package/esm/cli/introspect/transform-schema.d.ts +74 -0
  192. package/esm/cli/introspect/transform-schema.js +259 -0
  193. package/esm/cli/introspect/transform-schema.test.d.ts +1 -0
  194. package/esm/cli/introspect/transform-schema.test.js +65 -0
  195. package/esm/cli/introspect/transform.d.ts +21 -0
  196. package/esm/cli/introspect/transform.js +210 -0
  197. package/esm/cli/watch/cache.d.ts +45 -0
  198. package/esm/cli/watch/cache.js +73 -0
  199. package/esm/cli/watch/debounce.d.ts +19 -0
  200. package/esm/cli/watch/debounce.js +85 -0
  201. package/esm/cli/watch/hash.d.ts +17 -0
  202. package/esm/cli/watch/hash.js +43 -0
  203. package/esm/cli/watch/index.d.ts +10 -0
  204. package/esm/cli/watch/index.js +8 -0
  205. package/esm/cli/watch/orchestrator.d.ts +63 -0
  206. package/esm/cli/watch/orchestrator.js +223 -0
  207. package/esm/cli/watch/poller.d.ts +65 -0
  208. package/esm/cli/watch/poller.js +198 -0
  209. package/esm/cli/watch/types.d.ts +67 -0
  210. package/esm/cli/watch/types.js +4 -0
  211. package/esm/client/error.d.ts +95 -0
  212. package/esm/client/error.js +249 -0
  213. package/esm/client/execute.d.ts +57 -0
  214. package/esm/client/execute.js +120 -0
  215. package/esm/client/index.d.ts +6 -0
  216. package/esm/client/index.js +6 -0
  217. package/esm/client/typed-document.d.ts +31 -0
  218. package/esm/client/typed-document.js +40 -0
  219. package/esm/core/ast.d.ts +10 -0
  220. package/esm/core/ast.js +549 -0
  221. package/esm/core/custom-ast.d.ts +35 -0
  222. package/esm/core/custom-ast.js +161 -0
  223. package/esm/core/index.d.ts +8 -0
  224. package/esm/core/index.js +12 -0
  225. package/esm/core/meta-object/convert.d.ts +65 -0
  226. package/esm/core/meta-object/convert.js +60 -0
  227. package/esm/core/meta-object/format.json +93 -0
  228. package/esm/core/meta-object/index.d.ts +2 -0
  229. package/esm/core/meta-object/index.js +2 -0
  230. package/esm/core/meta-object/validate.d.ts +9 -0
  231. package/esm/core/meta-object/validate.js +28 -0
  232. package/esm/core/query-builder.d.ts +46 -0
  233. package/esm/core/query-builder.js +375 -0
  234. package/esm/core/types.d.ts +139 -0
  235. package/esm/core/types.js +24 -0
  236. package/esm/generators/field-selector.d.ts +30 -0
  237. package/esm/generators/field-selector.js +355 -0
  238. package/esm/generators/index.d.ts +6 -0
  239. package/esm/generators/index.js +9 -0
  240. package/esm/generators/mutations.d.ts +31 -0
  241. package/esm/generators/mutations.js +197 -0
  242. package/esm/generators/select.d.ts +50 -0
  243. package/esm/generators/select.js +636 -0
  244. package/esm/index.d.ts +12 -0
  245. package/esm/index.js +17 -3
  246. package/esm/react/index.d.ts +5 -0
  247. package/esm/react/index.js +6 -0
  248. package/esm/types/config.d.ts +199 -0
  249. package/esm/types/config.js +106 -0
  250. package/esm/types/index.d.ts +9 -0
  251. package/esm/types/index.js +4 -0
  252. package/esm/types/introspection.d.ts +121 -0
  253. package/esm/types/introspection.js +54 -0
  254. package/esm/types/mutation.d.ts +45 -0
  255. package/esm/types/mutation.js +4 -0
  256. package/esm/types/query.d.ts +82 -0
  257. package/esm/types/query.js +4 -0
  258. package/esm/types/schema.d.ts +253 -0
  259. package/esm/types/schema.js +5 -0
  260. package/esm/types/selection.d.ts +43 -0
  261. package/esm/types/selection.js +4 -0
  262. package/esm/utils/index.d.ts +4 -0
  263. package/esm/utils/index.js +4 -0
  264. package/generators/field-selector.d.ts +30 -0
  265. package/generators/field-selector.js +361 -0
  266. package/generators/index.d.ts +6 -0
  267. package/generators/index.js +27 -0
  268. package/generators/mutations.d.ts +31 -0
  269. package/generators/mutations.js +235 -0
  270. package/generators/select.d.ts +50 -0
  271. package/generators/select.js +679 -0
  272. package/index.d.ts +12 -3
  273. package/index.js +19 -3
  274. package/package.json +59 -38
  275. package/react/index.d.ts +5 -0
  276. package/react/index.js +9 -0
  277. package/types/config.d.ts +199 -0
  278. package/types/config.js +111 -0
  279. package/types/index.d.ts +9 -0
  280. package/types/index.js +10 -0
  281. package/types/introspection.d.ts +121 -0
  282. package/types/introspection.js +62 -0
  283. package/types/mutation.d.ts +45 -0
  284. package/types/mutation.js +5 -0
  285. package/types/query.d.ts +82 -0
  286. package/types/query.js +5 -0
  287. package/types/schema.d.ts +253 -0
  288. package/types/schema.js +6 -0
  289. package/types/selection.d.ts +43 -0
  290. package/types/selection.js +5 -0
  291. package/utils/index.d.ts +4 -0
  292. package/utils/index.js +7 -0
  293. package/codegen.d.ts +0 -13
  294. package/codegen.js +0 -293
  295. package/esm/codegen.js +0 -253
  296. package/esm/gql.js +0 -939
  297. package/esm/options.js +0 -27
  298. package/gql.d.ts +0 -188
  299. package/gql.js +0 -992
  300. package/options.d.ts +0 -45
  301. package/options.js +0 -31
@@ -0,0 +1,156 @@
1
+ import { createFileHeader } from './ts-ast';
2
+ import { getListQueryHookName, getSingleQueryHookName, getCreateMutationHookName, getUpdateMutationHookName, getDeleteMutationHookName, } from './utils';
3
+ import { getOperationHookName } from './type-resolver';
4
+ /**
5
+ * Generate the queries/index.ts barrel file
6
+ */
7
+ export function generateQueriesBarrel(tables) {
8
+ const lines = [
9
+ createFileHeader('Query hooks barrel export'),
10
+ '',
11
+ ];
12
+ // Export all query hooks
13
+ for (const table of tables) {
14
+ const listHookName = getListQueryHookName(table);
15
+ const singleHookName = getSingleQueryHookName(table);
16
+ lines.push(`export * from './${listHookName}';`);
17
+ lines.push(`export * from './${singleHookName}';`);
18
+ }
19
+ return lines.join('\n') + '\n';
20
+ }
21
+ /**
22
+ * Generate the mutations/index.ts barrel file
23
+ */
24
+ export function generateMutationsBarrel(tables) {
25
+ const lines = [
26
+ createFileHeader('Mutation hooks barrel export'),
27
+ '',
28
+ ];
29
+ // Export all mutation hooks
30
+ for (const table of tables) {
31
+ const createHookName = getCreateMutationHookName(table);
32
+ const updateHookName = getUpdateMutationHookName(table);
33
+ const deleteHookName = getDeleteMutationHookName(table);
34
+ lines.push(`export * from './${createHookName}';`);
35
+ // Only add update/delete if they exist
36
+ if (table.query?.update !== null) {
37
+ lines.push(`export * from './${updateHookName}';`);
38
+ }
39
+ if (table.query?.delete !== null) {
40
+ lines.push(`export * from './${deleteHookName}';`);
41
+ }
42
+ }
43
+ return lines.join('\n') + '\n';
44
+ }
45
+ /**
46
+ * Generate the main index.ts barrel file
47
+ */
48
+ export function generateMainBarrel(tables) {
49
+ const tableNames = tables.map((t) => t.name).join(', ');
50
+ return `/**
51
+ * Auto-generated GraphQL SDK
52
+ * @generated by @constructive-io/graphql-codegen
53
+ *
54
+ * Tables: ${tableNames}
55
+ *
56
+ * Usage:
57
+ *
58
+ * 1. Configure the client:
59
+ * \`\`\`ts
60
+ * import { configure } from './generated';
61
+ *
62
+ * configure({
63
+ * endpoint: 'https://api.example.com/graphql',
64
+ * headers: { Authorization: 'Bearer <token>' },
65
+ * });
66
+ * \`\`\`
67
+ *
68
+ * 2. Use the hooks:
69
+ * \`\`\`tsx
70
+ * import { useCarsQuery, useCreateCarMutation } from './generated';
71
+ *
72
+ * function MyComponent() {
73
+ * const { data, isLoading } = useCarsQuery({ first: 10 });
74
+ * const { mutate } = useCreateCarMutation();
75
+ * // ...
76
+ * }
77
+ * \`\`\`
78
+ */
79
+
80
+ // Client configuration
81
+ export * from './client';
82
+
83
+ // Entity and filter types
84
+ export * from './types';
85
+
86
+ // Query hooks
87
+ export * from './queries';
88
+
89
+ // Mutation hooks
90
+ export * from './mutations';
91
+ `;
92
+ }
93
+ // ============================================================================
94
+ // Custom operation barrels (includes both table and custom hooks)
95
+ // ============================================================================
96
+ /**
97
+ * Generate queries barrel including custom query operations
98
+ */
99
+ export function generateCustomQueriesBarrel(tables, customQueryNames) {
100
+ const lines = [
101
+ createFileHeader('Query hooks barrel export'),
102
+ '',
103
+ '// Table-based query hooks',
104
+ ];
105
+ // Export all table query hooks
106
+ for (const table of tables) {
107
+ const listHookName = getListQueryHookName(table);
108
+ const singleHookName = getSingleQueryHookName(table);
109
+ lines.push(`export * from './${listHookName}';`);
110
+ lines.push(`export * from './${singleHookName}';`);
111
+ }
112
+ // Add custom query hooks
113
+ if (customQueryNames.length > 0) {
114
+ lines.push('');
115
+ lines.push('// Custom query hooks');
116
+ for (const name of customQueryNames) {
117
+ const hookName = getOperationHookName(name, 'query');
118
+ lines.push(`export * from './${hookName}';`);
119
+ }
120
+ }
121
+ return lines.join('\n') + '\n';
122
+ }
123
+ /**
124
+ * Generate mutations barrel including custom mutation operations
125
+ */
126
+ export function generateCustomMutationsBarrel(tables, customMutationNames) {
127
+ const lines = [
128
+ createFileHeader('Mutation hooks barrel export'),
129
+ '',
130
+ '// Table-based mutation hooks',
131
+ ];
132
+ // Export all table mutation hooks
133
+ for (const table of tables) {
134
+ const createHookName = getCreateMutationHookName(table);
135
+ const updateHookName = getUpdateMutationHookName(table);
136
+ const deleteHookName = getDeleteMutationHookName(table);
137
+ lines.push(`export * from './${createHookName}';`);
138
+ // Only add update/delete if they exist
139
+ if (table.query?.update !== null) {
140
+ lines.push(`export * from './${updateHookName}';`);
141
+ }
142
+ if (table.query?.delete !== null) {
143
+ lines.push(`export * from './${deleteHookName}';`);
144
+ }
145
+ }
146
+ // Add custom mutation hooks
147
+ if (customMutationNames.length > 0) {
148
+ lines.push('');
149
+ lines.push('// Custom mutation hooks');
150
+ for (const name of customMutationNames) {
151
+ const hookName = getOperationHookName(name, 'mutation');
152
+ lines.push(`export * from './${hookName}';`);
153
+ }
154
+ }
155
+ return lines.join('\n') + '\n';
156
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Generate client.ts content
3
+ */
4
+ export declare function generateClientFile(): string;
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Client generator - generates client.ts with configure() and execute()
3
+ */
4
+ import { getGeneratedFileHeader } from './utils';
5
+ /**
6
+ * Generate client.ts content
7
+ */
8
+ export function generateClientFile() {
9
+ return `${getGeneratedFileHeader('GraphQL client configuration and execution')}
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
+ }
21
+
22
+ let globalConfig: GraphQLClientConfig | null = null;
23
+
24
+ /**
25
+ * Configure the GraphQL client
26
+ *
27
+ * @example
28
+ * \`\`\`ts
29
+ * import { configure } from './generated';
30
+ *
31
+ * configure({
32
+ * endpoint: 'https://api.example.com/graphql',
33
+ * headers: {
34
+ * Authorization: 'Bearer <token>',
35
+ * },
36
+ * });
37
+ * \`\`\`
38
+ */
39
+ export function configure(config: GraphQLClientConfig): void {
40
+ globalConfig = config;
41
+ }
42
+
43
+ /**
44
+ * Get the current configuration
45
+ * @throws Error if not configured
46
+ */
47
+ export function getConfig(): GraphQLClientConfig {
48
+ if (!globalConfig) {
49
+ throw new Error(
50
+ 'GraphQL client not configured. Call configure() before making requests.'
51
+ );
52
+ }
53
+ return globalConfig;
54
+ }
55
+
56
+ // ============================================================================
57
+ // Error handling
58
+ // ============================================================================
59
+
60
+ export interface GraphQLError {
61
+ message: string;
62
+ locations?: Array<{ line: number; column: number }>;
63
+ path?: Array<string | number>;
64
+ extensions?: Record<string, unknown>;
65
+ }
66
+
67
+ export class GraphQLClientError extends Error {
68
+ constructor(
69
+ message: string,
70
+ public errors: GraphQLError[],
71
+ public response?: Response
72
+ ) {
73
+ super(message);
74
+ this.name = 'GraphQLClientError';
75
+ }
76
+ }
77
+
78
+ // ============================================================================
79
+ // Execution
80
+ // ============================================================================
81
+
82
+ export interface ExecuteOptions {
83
+ /** Override headers for this request */
84
+ headers?: Record<string, string>;
85
+ /** AbortSignal for request cancellation */
86
+ signal?: AbortSignal;
87
+ }
88
+
89
+ /**
90
+ * Execute a GraphQL operation
91
+ *
92
+ * @example
93
+ * \`\`\`ts
94
+ * const result = await execute<CarsQueryResult, CarsQueryVariables>(
95
+ * carsQueryDocument,
96
+ * { first: 10 }
97
+ * );
98
+ * \`\`\`
99
+ */
100
+ export async function execute<TData = unknown, TVariables = Record<string, unknown>>(
101
+ document: string,
102
+ variables?: TVariables,
103
+ options?: ExecuteOptions
104
+ ): Promise<TData> {
105
+ const config = getConfig();
106
+
107
+ const response = await fetch(config.endpoint, {
108
+ method: 'POST',
109
+ headers: {
110
+ 'Content-Type': 'application/json',
111
+ ...config.headers,
112
+ ...options?.headers,
113
+ },
114
+ body: JSON.stringify({
115
+ query: document,
116
+ variables,
117
+ }),
118
+ signal: options?.signal,
119
+ });
120
+
121
+ const json = await response.json();
122
+
123
+ if (json.errors && json.errors.length > 0) {
124
+ throw new GraphQLClientError(
125
+ json.errors[0].message || 'GraphQL request failed',
126
+ json.errors,
127
+ response
128
+ );
129
+ }
130
+
131
+ return json.data as TData;
132
+ }
133
+
134
+ /**
135
+ * Execute a GraphQL operation with full response (data + errors)
136
+ * Useful when you want to handle partial data with errors
137
+ */
138
+ export async function executeWithErrors<TData = unknown, TVariables = Record<string, unknown>>(
139
+ document: string,
140
+ variables?: TVariables,
141
+ options?: ExecuteOptions
142
+ ): Promise<{ data: TData | null; errors: GraphQLError[] | null }> {
143
+ const config = getConfig();
144
+
145
+ const response = await fetch(config.endpoint, {
146
+ method: 'POST',
147
+ headers: {
148
+ 'Content-Type': 'application/json',
149
+ ...config.headers,
150
+ ...options?.headers,
151
+ },
152
+ body: JSON.stringify({
153
+ query: document,
154
+ variables,
155
+ }),
156
+ signal: options?.signal,
157
+ });
158
+
159
+ const json = await response.json();
160
+
161
+ return {
162
+ data: json.data ?? null,
163
+ errors: json.errors ?? null,
164
+ };
165
+ }
166
+ `;
167
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Custom mutation hook generators for non-table operations
3
+ *
4
+ * Generates hooks for operations discovered via schema introspection
5
+ * that are NOT table CRUD operations (e.g., login, register, etc.)
6
+ *
7
+ * Output structure:
8
+ * mutations/
9
+ * useLoginMutation.ts
10
+ * useRegisterMutation.ts
11
+ * ...
12
+ */
13
+ import type { CleanOperation, TypeRegistry } from '../../types/schema';
14
+ export interface GeneratedCustomMutationFile {
15
+ fileName: string;
16
+ content: string;
17
+ operationName: string;
18
+ }
19
+ export interface GenerateCustomMutationHookOptions {
20
+ operation: CleanOperation;
21
+ typeRegistry: TypeRegistry;
22
+ maxDepth?: number;
23
+ skipQueryField?: boolean;
24
+ }
25
+ /**
26
+ * Generate a custom mutation hook file
27
+ */
28
+ export declare function generateCustomMutationHook(options: GenerateCustomMutationHookOptions): GeneratedCustomMutationFile;
29
+ export interface GenerateAllCustomMutationHooksOptions {
30
+ operations: CleanOperation[];
31
+ typeRegistry: TypeRegistry;
32
+ maxDepth?: number;
33
+ skipQueryField?: boolean;
34
+ }
35
+ /**
36
+ * Generate all custom mutation hook files
37
+ */
38
+ export declare function generateAllCustomMutationHooks(options: GenerateAllCustomMutationHooksOptions): GeneratedCustomMutationFile[];
@@ -0,0 +1,145 @@
1
+ import { createProject, createSourceFile, getFormattedOutput, createFileHeader, createImport, createInterface, createConst, } from './ts-ast';
2
+ import { buildCustomMutationString } from './schema-gql-ast';
3
+ import { typeRefToTsType, isTypeRequired, getOperationHookName, getOperationFileName, getOperationVariablesTypeName, getOperationResultTypeName, getDocumentConstName, } from './type-resolver';
4
+ /**
5
+ * Generate a custom mutation hook file
6
+ */
7
+ export function generateCustomMutationHook(options) {
8
+ const { operation } = options;
9
+ try {
10
+ return generateCustomMutationHookInternal(options);
11
+ }
12
+ catch (err) {
13
+ console.error(`Error generating hook for mutation: ${operation.name}`);
14
+ console.error(` Args: ${operation.args.length}, Return type: ${operation.returnType.kind}/${operation.returnType.name}`);
15
+ throw err;
16
+ }
17
+ }
18
+ function generateCustomMutationHookInternal(options) {
19
+ const { operation, typeRegistry, maxDepth = 2, skipQueryField = true } = options;
20
+ const project = createProject();
21
+ const hookName = getOperationHookName(operation.name, 'mutation');
22
+ const fileName = getOperationFileName(operation.name, 'mutation');
23
+ const variablesTypeName = getOperationVariablesTypeName(operation.name, 'mutation');
24
+ const resultTypeName = getOperationResultTypeName(operation.name, 'mutation');
25
+ const documentConstName = getDocumentConstName(operation.name, 'mutation');
26
+ // Generate GraphQL document
27
+ const mutationDocument = buildCustomMutationString({
28
+ operation,
29
+ typeRegistry,
30
+ maxDepth,
31
+ skipQueryField,
32
+ });
33
+ const sourceFile = createSourceFile(project, fileName);
34
+ // Add file header
35
+ sourceFile.insertText(0, createFileHeader(`Custom mutation hook for ${operation.name}`) + '\n\n');
36
+ // Add imports
37
+ sourceFile.addImportDeclarations([
38
+ createImport({
39
+ moduleSpecifier: '@tanstack/react-query',
40
+ namedImports: ['useMutation'],
41
+ typeOnlyNamedImports: ['UseMutationOptions'],
42
+ }),
43
+ createImport({
44
+ moduleSpecifier: '../client',
45
+ namedImports: ['execute'],
46
+ }),
47
+ ]);
48
+ // Add mutation document constant
49
+ sourceFile.addVariableStatement(createConst(documentConstName, '`\n' + mutationDocument + '`', {
50
+ docs: ['GraphQL mutation document'],
51
+ }));
52
+ // Generate variables interface if there are arguments
53
+ if (operation.args.length > 0) {
54
+ const variablesProps = generateVariablesProperties(operation.args);
55
+ sourceFile.addInterface(createInterface(variablesTypeName, variablesProps));
56
+ }
57
+ // Generate result interface
58
+ const resultType = typeRefToTsType(operation.returnType);
59
+ const resultProps = [
60
+ { name: operation.name, type: resultType },
61
+ ];
62
+ sourceFile.addInterface(createInterface(resultTypeName, resultProps));
63
+ // Generate hook function
64
+ const hookParams = generateHookParameters(operation, variablesTypeName, resultTypeName);
65
+ const hookBody = generateHookBody(operation, documentConstName, variablesTypeName, resultTypeName);
66
+ // Note: docs can cause ts-morph issues with certain content, so we skip them
67
+ sourceFile.addFunction({
68
+ name: hookName,
69
+ isExported: true,
70
+ parameters: hookParams,
71
+ statements: hookBody,
72
+ });
73
+ return {
74
+ fileName,
75
+ content: getFormattedOutput(sourceFile),
76
+ operationName: operation.name,
77
+ };
78
+ }
79
+ // ============================================================================
80
+ // Helper functions
81
+ // ============================================================================
82
+ /**
83
+ * Generate interface properties from CleanArguments
84
+ */
85
+ function generateVariablesProperties(args) {
86
+ return args.map((arg) => ({
87
+ name: arg.name,
88
+ type: typeRefToTsType(arg.type),
89
+ optional: !isTypeRequired(arg.type),
90
+ docs: arg.description ? [arg.description] : undefined,
91
+ }));
92
+ }
93
+ /**
94
+ * Generate hook function parameters
95
+ */
96
+ function generateHookParameters(operation, variablesTypeName, resultTypeName) {
97
+ const hasArgs = operation.args.length > 0;
98
+ // Mutation hooks use UseMutationOptions with variables as the second type param
99
+ const optionsType = hasArgs
100
+ ? `Omit<UseMutationOptions<${resultTypeName}, Error, ${variablesTypeName}>, 'mutationFn'>`
101
+ : `Omit<UseMutationOptions<${resultTypeName}, Error, void>, 'mutationFn'>`;
102
+ return [
103
+ {
104
+ name: 'options',
105
+ type: optionsType,
106
+ hasQuestionToken: true,
107
+ },
108
+ ];
109
+ }
110
+ /**
111
+ * Generate hook function body
112
+ */
113
+ function generateHookBody(operation, documentConstName, variablesTypeName, resultTypeName) {
114
+ const hasArgs = operation.args.length > 0;
115
+ if (hasArgs) {
116
+ return `return useMutation({
117
+ mutationFn: (variables: ${variablesTypeName}) =>
118
+ execute<${resultTypeName}, ${variablesTypeName}>(
119
+ ${documentConstName},
120
+ variables
121
+ ),
122
+ ...options,
123
+ });`;
124
+ }
125
+ else {
126
+ return `return useMutation({
127
+ mutationFn: () => execute<${resultTypeName}>(${documentConstName}),
128
+ ...options,
129
+ });`;
130
+ }
131
+ }
132
+ /**
133
+ * Generate all custom mutation hook files
134
+ */
135
+ export function generateAllCustomMutationHooks(options) {
136
+ const { operations, typeRegistry, maxDepth = 2, skipQueryField = true } = options;
137
+ return operations
138
+ .filter((op) => op.kind === 'mutation')
139
+ .map((operation) => generateCustomMutationHook({
140
+ operation,
141
+ typeRegistry,
142
+ maxDepth,
143
+ skipQueryField,
144
+ }));
145
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Custom query hook generators for non-table operations
3
+ *
4
+ * Generates hooks for operations discovered via schema introspection
5
+ * that are NOT table CRUD operations (e.g., currentUser, nodeById, etc.)
6
+ *
7
+ * Output structure:
8
+ * queries/
9
+ * useCurrentUserQuery.ts
10
+ * useNodeQuery.ts
11
+ * ...
12
+ */
13
+ import type { CleanOperation, TypeRegistry } from '../../types/schema';
14
+ export interface GeneratedCustomQueryFile {
15
+ fileName: string;
16
+ content: string;
17
+ operationName: string;
18
+ }
19
+ export interface GenerateCustomQueryHookOptions {
20
+ operation: CleanOperation;
21
+ typeRegistry: TypeRegistry;
22
+ maxDepth?: number;
23
+ skipQueryField?: boolean;
24
+ }
25
+ /**
26
+ * Generate a custom query hook file
27
+ */
28
+ export declare function generateCustomQueryHook(options: GenerateCustomQueryHookOptions): GeneratedCustomQueryFile;
29
+ export interface GenerateAllCustomQueryHooksOptions {
30
+ operations: CleanOperation[];
31
+ typeRegistry: TypeRegistry;
32
+ maxDepth?: number;
33
+ skipQueryField?: boolean;
34
+ }
35
+ /**
36
+ * Generate all custom query hook files
37
+ */
38
+ export declare function generateAllCustomQueryHooks(options: GenerateAllCustomQueryHooksOptions): GeneratedCustomQueryFile[];