@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,5 +1,5 @@
1
- import type { CleanTable, CleanOperation } from '../../types/schema';
2
1
  import type { QueryKeyConfig } from '../../types/config';
2
+ import type { CleanOperation, CleanTable } from '../../types/schema';
3
3
  export interface QueryKeyGeneratorOptions {
4
4
  tables: CleanTable[];
5
5
  customQueries: CleanOperation[];
@@ -9,8 +9,8 @@
9
9
  * @see https://tanstack.com/query/docs/framework/react/community/lukemorales-query-key-factory
10
10
  */
11
11
  import * as t from '@babel/types';
12
- import { getTableNames, getGeneratedFileHeader, ucFirst, lcFirst } from './utils';
13
- import { generateCode, addJSDocComment, asConst, constArray, typedParam, keyofTypeof, } from './babel-ast';
12
+ import { addJSDocComment, asConst, constArray, generateCode, keyofTypeof, typedParam, } from './babel-ast';
13
+ import { getGeneratedFileHeader, getTableNames, lcFirst, ucFirst, } from './utils';
14
14
  /**
15
15
  * Get all ancestor entities for a given entity based on relationships
16
16
  */
@@ -76,11 +76,13 @@ function buildByParentProperty(entityKey, typeName, parent, fkField) {
76
76
  const arrowFn = t.arrowFunctionExpression([typedParam(fkField, t.tsStringKeyword())], constArray([
77
77
  t.stringLiteral(entityKey),
78
78
  t.objectExpression([
79
- t.objectProperty(t.identifier(fkField), t.identifier(fkField), false, true)
80
- ])
79
+ t.objectProperty(t.identifier(fkField), t.identifier(fkField), false, true),
80
+ ]),
81
81
  ]));
82
82
  const prop = t.objectProperty(t.identifier(`by${parentUpper}`), arrowFn);
83
- addJSDocComment(prop, [`${typeName} queries scoped to a specific ${parentLower}`]);
83
+ addJSDocComment(prop, [
84
+ `${typeName} queries scoped to a specific ${parentLower}`,
85
+ ]);
84
86
  return prop;
85
87
  }
86
88
  /**
@@ -92,14 +94,18 @@ function buildScopedProperty(keysName, typeName, relationship, ancestors) {
92
94
  const statements = [];
93
95
  if (relationship.parent) {
94
96
  statements.push(t.ifStatement(t.optionalMemberExpression(t.identifier('scope'), t.identifier(relationship.foreignKey), false, true), t.blockStatement([
95
- t.returnStatement(t.callExpression(t.memberExpression(t.identifier(keysName), t.identifier(`by${ucFirst(relationship.parent)}`)), [t.memberExpression(t.identifier('scope'), t.identifier(relationship.foreignKey))]))
97
+ t.returnStatement(t.callExpression(t.memberExpression(t.identifier(keysName), t.identifier(`by${ucFirst(relationship.parent)}`)), [
98
+ t.memberExpression(t.identifier('scope'), t.identifier(relationship.foreignKey)),
99
+ ])),
96
100
  ])));
97
101
  }
98
102
  for (const ancestor of ancestors) {
99
103
  const ancestorLower = lcFirst(ancestor);
100
104
  const fkField = `${ancestorLower}Id`;
101
105
  statements.push(t.ifStatement(t.optionalMemberExpression(t.identifier('scope'), t.identifier(fkField), false, true), t.blockStatement([
102
- t.returnStatement(t.callExpression(t.memberExpression(t.identifier(keysName), t.identifier(`by${ucFirst(ancestor)}`)), [t.memberExpression(t.identifier('scope'), t.identifier(fkField))]))
106
+ t.returnStatement(t.callExpression(t.memberExpression(t.identifier(keysName), t.identifier(`by${ucFirst(ancestor)}`)), [
107
+ t.memberExpression(t.identifier('scope'), t.identifier(fkField)),
108
+ ])),
103
109
  ])));
104
110
  }
105
111
  statements.push(t.returnStatement(t.memberExpression(t.identifier(keysName), t.identifier('all'))));
@@ -115,7 +121,7 @@ function buildScopedListsProperty(keysName, scopeTypeName) {
115
121
  const scopeParam = typedParam('scope', t.tsTypeReference(t.identifier(scopeTypeName)), true);
116
122
  const arrowFn = t.arrowFunctionExpression([scopeParam], constArray([
117
123
  t.spreadElement(t.callExpression(t.memberExpression(t.identifier(keysName), t.identifier('scoped')), [t.identifier('scope')])),
118
- t.stringLiteral('list')
124
+ t.stringLiteral('list'),
119
125
  ]));
120
126
  const prop = t.objectProperty(t.identifier('lists'), arrowFn);
121
127
  addJSDocComment(prop, ['List query keys (optionally scoped)']);
@@ -129,7 +135,7 @@ function buildScopedListProperty(keysName, scopeTypeName) {
129
135
  const scopeParam = typedParam('scope', t.tsTypeReference(t.identifier(scopeTypeName)), true);
130
136
  const arrowFn = t.arrowFunctionExpression([variablesParam, scopeParam], constArray([
131
137
  t.spreadElement(t.callExpression(t.memberExpression(t.identifier(keysName), t.identifier('lists')), [t.identifier('scope')])),
132
- t.identifier('variables')
138
+ t.identifier('variables'),
133
139
  ]));
134
140
  const prop = t.objectProperty(t.identifier('list'), arrowFn);
135
141
  addJSDocComment(prop, ['List query key with variables']);
@@ -142,7 +148,7 @@ function buildScopedDetailsProperty(keysName, scopeTypeName) {
142
148
  const scopeParam = typedParam('scope', t.tsTypeReference(t.identifier(scopeTypeName)), true);
143
149
  const arrowFn = t.arrowFunctionExpression([scopeParam], constArray([
144
150
  t.spreadElement(t.callExpression(t.memberExpression(t.identifier(keysName), t.identifier('scoped')), [t.identifier('scope')])),
145
- t.stringLiteral('detail')
151
+ t.stringLiteral('detail'),
146
152
  ]));
147
153
  const prop = t.objectProperty(t.identifier('details'), arrowFn);
148
154
  addJSDocComment(prop, ['Detail query keys (optionally scoped)']);
@@ -156,7 +162,7 @@ function buildScopedDetailProperty(keysName, scopeTypeName) {
156
162
  const scopeParam = typedParam('scope', t.tsTypeReference(t.identifier(scopeTypeName)), true);
157
163
  const arrowFn = t.arrowFunctionExpression([idParam, scopeParam], constArray([
158
164
  t.spreadElement(t.callExpression(t.memberExpression(t.identifier(keysName), t.identifier('details')), [t.identifier('scope')])),
159
- t.identifier('id')
165
+ t.identifier('id'),
160
166
  ]));
161
167
  const prop = t.objectProperty(t.identifier('detail'), arrowFn);
162
168
  addJSDocComment(prop, ['Detail query key for specific item']);
@@ -168,7 +174,7 @@ function buildScopedDetailProperty(keysName, scopeTypeName) {
168
174
  function buildSimpleListsProperty(keysName) {
169
175
  const arrowFn = t.arrowFunctionExpression([], constArray([
170
176
  t.spreadElement(t.memberExpression(t.identifier(keysName), t.identifier('all'))),
171
- t.stringLiteral('list')
177
+ t.stringLiteral('list'),
172
178
  ]));
173
179
  const prop = t.objectProperty(t.identifier('lists'), arrowFn);
174
180
  addJSDocComment(prop, ['List query keys']);
@@ -181,7 +187,7 @@ function buildSimpleListProperty(keysName) {
181
187
  const variablesParam = typedParam('variables', t.tsTypeReference(t.identifier('object')), true);
182
188
  const arrowFn = t.arrowFunctionExpression([variablesParam], constArray([
183
189
  t.spreadElement(t.callExpression(t.memberExpression(t.identifier(keysName), t.identifier('lists')), [])),
184
- t.identifier('variables')
190
+ t.identifier('variables'),
185
191
  ]));
186
192
  const prop = t.objectProperty(t.identifier('list'), arrowFn);
187
193
  addJSDocComment(prop, ['List query key with variables']);
@@ -193,7 +199,7 @@ function buildSimpleListProperty(keysName) {
193
199
  function buildSimpleDetailsProperty(keysName) {
194
200
  const arrowFn = t.arrowFunctionExpression([], constArray([
195
201
  t.spreadElement(t.memberExpression(t.identifier(keysName), t.identifier('all'))),
196
- t.stringLiteral('detail')
202
+ t.stringLiteral('detail'),
197
203
  ]));
198
204
  const prop = t.objectProperty(t.identifier('details'), arrowFn);
199
205
  addJSDocComment(prop, ['Detail query keys']);
@@ -206,7 +212,7 @@ function buildSimpleDetailProperty(keysName) {
206
212
  const idParam = typedParam('id', t.tsUnionType([t.tsStringKeyword(), t.tsNumberKeyword()]));
207
213
  const arrowFn = t.arrowFunctionExpression([idParam], constArray([
208
214
  t.spreadElement(t.callExpression(t.memberExpression(t.identifier(keysName), t.identifier('details')), [])),
209
- t.identifier('id')
215
+ t.identifier('id'),
210
216
  ]));
211
217
  const prop = t.objectProperty(t.identifier('detail'), arrowFn);
212
218
  addJSDocComment(prop, ['Detail query key for specific item']);
@@ -247,7 +253,7 @@ function generateEntityKeysDeclaration(table, relationships, generateScopedKeys)
247
253
  properties.push(buildSimpleDetailProperty(keysName));
248
254
  }
249
255
  return t.exportNamedDeclaration(t.variableDeclaration('const', [
250
- t.variableDeclarator(t.identifier(keysName), asConst(t.objectExpression(properties)))
256
+ t.variableDeclarator(t.identifier(keysName), asConst(t.objectExpression(properties))),
251
257
  ]));
252
258
  }
253
259
  /**
@@ -274,7 +280,7 @@ function generateCustomQueryKeysDeclaration(operations) {
274
280
  properties.push(prop);
275
281
  }
276
282
  return t.exportNamedDeclaration(t.variableDeclaration('const', [
277
- t.variableDeclarator(t.identifier('customQueryKeys'), asConst(t.objectExpression(properties)))
283
+ t.variableDeclarator(t.identifier('customQueryKeys'), asConst(t.objectExpression(properties))),
278
284
  ]));
279
285
  }
280
286
  /**
@@ -291,7 +297,7 @@ function generateUnifiedStoreDeclaration(tables, hasCustomQueries) {
291
297
  properties.push(t.objectProperty(t.identifier('custom'), t.identifier('customQueryKeys')));
292
298
  }
293
299
  const decl = t.exportNamedDeclaration(t.variableDeclaration('const', [
294
- t.variableDeclarator(t.identifier('queryKeys'), asConst(t.objectExpression(properties)))
300
+ t.variableDeclarator(t.identifier('queryKeys'), asConst(t.objectExpression(properties))),
295
301
  ]));
296
302
  addJSDocComment(decl, [
297
303
  'Unified query key store',
@@ -348,7 +354,9 @@ export function generateQueryKeysFile(options) {
348
354
  statements.push(generateUnifiedStoreDeclaration(tables, queryOperations.length > 0));
349
355
  // Generate QueryKeyScope type
350
356
  const scopeTypeDecl = t.exportNamedDeclaration(t.tsTypeAliasDeclaration(t.identifier('QueryKeyScope'), null, keyofTypeof('queryKeys')));
351
- addJSDocComment(scopeTypeDecl, ['Type representing all available query key scopes']);
357
+ addJSDocComment(scopeTypeDecl, [
358
+ 'Type representing all available query key scopes',
359
+ ]);
352
360
  statements.push(scopeTypeDecl);
353
361
  // Generate code from AST
354
362
  const code = generateCode(statements);
@@ -371,7 +379,7 @@ ${description}
371
379
  `;
372
380
  // Add scope types section if present
373
381
  if (generateScopedKeys && Object.keys(relationships).length > 0) {
374
- const hasScopes = tables.some(table => {
382
+ const hasScopes = tables.some((table) => {
375
383
  const { typeName } = getTableNames(table);
376
384
  return !!relationships[typeName.toLowerCase()];
377
385
  });
@@ -392,7 +400,9 @@ ${description}
392
400
  for (let i = 0; i < codeLines.length; i++) {
393
401
  const line = codeLines[i];
394
402
  // Detect transition from scope types to entity keys
395
- if (inScopeTypes && line.startsWith('export const') && line.includes('Keys =')) {
403
+ if (inScopeTypes &&
404
+ line.startsWith('export const') &&
405
+ line.includes('Keys =')) {
396
406
  content += `// ============================================================================
397
407
  // Entity Query Keys
398
408
  // ============================================================================
@@ -402,7 +412,8 @@ ${description}
402
412
  addedEntitySection = true;
403
413
  }
404
414
  // Detect custom query keys section
405
- if (!addedCustomSection && line.startsWith('export const customQueryKeys')) {
415
+ if (!addedCustomSection &&
416
+ line.startsWith('export const customQueryKeys')) {
406
417
  content += `
407
418
  // ============================================================================
408
419
  // Custom Query Keys
@@ -427,11 +438,14 @@ ${description}
427
438
  if (!addedEntitySection && !inScopeTypes) {
428
439
  const firstExportIndex = content.indexOf('\nexport const');
429
440
  if (firstExportIndex !== -1) {
430
- content = content.slice(0, firstExportIndex) + `
441
+ content =
442
+ content.slice(0, firstExportIndex) +
443
+ `
431
444
  // ============================================================================
432
445
  // Entity Query Keys
433
446
  // ============================================================================
434
- ` + content.slice(firstExportIndex);
447
+ ` +
448
+ content.slice(firstExportIndex);
435
449
  }
436
450
  }
437
451
  return {
@@ -63,7 +63,9 @@ export const BASE_FILTER_TYPE_NAMES = new Set([
63
63
  ...Array.from(LIST_FILTER_SCALARS).map((s) => `${s}ListFilter`),
64
64
  ]);
65
65
  export function scalarToTsType(scalarName, options = {}) {
66
- return options.overrides?.[scalarName] ?? SCALAR_TS_MAP[scalarName] ?? (options.unknownScalar === 'unknown' ? 'unknown' : scalarName);
66
+ return (options.overrides?.[scalarName] ??
67
+ SCALAR_TS_MAP[scalarName] ??
68
+ (options.unknownScalar === 'unknown' ? 'unknown' : scalarName));
67
69
  }
68
70
  /** Get the filter type for a scalar (handles both scalar and array types) */
69
71
  export function scalarToFilterType(scalarName, isArray = false) {
@@ -11,8 +11,8 @@
11
11
  *
12
12
  * Uses Babel AST for robust code generation.
13
13
  */
14
- import type { TypeRegistry } from '../../types/schema';
15
14
  import * as t from '@babel/types';
15
+ import type { TypeRegistry } from '../../types/schema';
16
16
  export interface GeneratedSchemaTypesFile {
17
17
  fileName: string;
18
18
  content: string;
@@ -1,7 +1,20 @@
1
+ /**
2
+ * Schema types generator for React Query hooks (non-ORM mode)
3
+ *
4
+ * Generates TypeScript interfaces for:
5
+ * 1. INPUT_OBJECT types (e.g., BootstrapUserInput, LoginInput)
6
+ * 2. Payload OBJECT types (e.g., BootstrapUserPayload, LoginPayload)
7
+ * 3. ENUM types (e.g., FieldCategory, TableCategory)
8
+ *
9
+ * These types are referenced by custom mutation/query hooks but not generated
10
+ * elsewhere in non-ORM mode.
11
+ *
12
+ * Uses Babel AST for robust code generation.
13
+ */
1
14
  import * as t from '@babel/types';
2
15
  import { generateCode } from './babel-ast';
16
+ import { BASE_FILTER_TYPE_NAMES, SCALAR_NAMES, scalarToTsType, } from './scalars';
3
17
  import { getTypeBaseName } from './type-resolver';
4
- import { scalarToTsType, SCALAR_NAMES, BASE_FILTER_TYPE_NAMES, } from './scalars';
5
18
  import { getGeneratedFileHeader } from './utils';
6
19
  const SKIP_TYPES = new Set([
7
20
  ...SCALAR_NAMES,
@@ -231,7 +244,9 @@ export function generateSchemaTypesFile(options) {
231
244
  allStatements.push(...inputResult.statements);
232
245
  allStatements.push(...payloadResult.statements);
233
246
  const code = generateCode(allStatements);
234
- const content = getGeneratedFileHeader('GraphQL schema types for custom operations') + '\n\n' + code;
247
+ const content = getGeneratedFileHeader('GraphQL schema types for custom operations') +
248
+ '\n\n' +
249
+ code;
235
250
  return {
236
251
  fileName: 'schema-types.ts',
237
252
  content,
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Shared helpers for select type resolution in custom operations
3
+ *
4
+ * Used by custom-queries.ts, custom-mutations.ts, and orm/custom-ops-generator.ts
5
+ */
6
+ import type { CleanArgument } from '../../types/schema';
7
+ /**
8
+ * Types that don't need Select types (scalars + root query/mutation types)
9
+ */
10
+ export declare const NON_SELECT_TYPES: Set<string>;
11
+ /**
12
+ * Get the Select type name for a return type.
13
+ * Returns null for scalar types, Connection types, and root types.
14
+ */
15
+ export declare function getSelectTypeName(returnType: CleanArgument['type']): string | null;
16
+ /**
17
+ * Wrap a type reference in InferSelectResult, handling NON_NULL and LIST wrappers.
18
+ */
19
+ export declare function wrapInferSelectResult(typeRef: CleanArgument['type'], payloadTypeName: string, selectType?: string): string;
@@ -0,0 +1,35 @@
1
+ import { SCALAR_NAMES } from './scalars';
2
+ import { getTypeBaseName } from './type-resolver';
3
+ /**
4
+ * Types that don't need Select types (scalars + root query/mutation types)
5
+ */
6
+ export const NON_SELECT_TYPES = new Set([
7
+ ...SCALAR_NAMES,
8
+ 'Query',
9
+ 'Mutation',
10
+ ]);
11
+ /**
12
+ * Get the Select type name for a return type.
13
+ * Returns null for scalar types, Connection types, and root types.
14
+ */
15
+ export function getSelectTypeName(returnType) {
16
+ const baseName = getTypeBaseName(returnType);
17
+ if (baseName &&
18
+ !NON_SELECT_TYPES.has(baseName) &&
19
+ !baseName.endsWith('Connection')) {
20
+ return `${baseName}Select`;
21
+ }
22
+ return null;
23
+ }
24
+ /**
25
+ * Wrap a type reference in InferSelectResult, handling NON_NULL and LIST wrappers.
26
+ */
27
+ export function wrapInferSelectResult(typeRef, payloadTypeName, selectType = 'S') {
28
+ if (typeRef.kind === 'NON_NULL' && typeRef.ofType) {
29
+ return wrapInferSelectResult(typeRef.ofType, payloadTypeName, selectType);
30
+ }
31
+ if (typeRef.kind === 'LIST' && typeRef.ofType) {
32
+ return `${wrapInferSelectResult(typeRef.ofType, payloadTypeName, selectType)}[]`;
33
+ }
34
+ return `InferSelectResult<${payloadTypeName}, ${selectType}>`;
35
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Generate selection.ts content - shared selection types + runtime mappers
3
+ */
4
+ export declare function generateSelectionFile(): string;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Selection helper generator for React Query hooks
3
+ *
4
+ * Uses template-copy pattern: reads hooks-selection.ts from templates/
5
+ * and writes it to the output directory with a generated file header.
6
+ */
7
+ import * as fs from 'fs';
8
+ import * as path from 'path';
9
+ import { getGeneratedFileHeader } from './utils';
10
+ function findTemplateFile(templateName) {
11
+ const templatePath = path.join(__dirname, 'templates', templateName);
12
+ if (fs.existsSync(templatePath)) {
13
+ return templatePath;
14
+ }
15
+ throw new Error(`Could not find template file: ${templateName}. Searched in: ${templatePath}`);
16
+ }
17
+ function readTemplateFile(templateName, description) {
18
+ const templatePath = findTemplateFile(templateName);
19
+ let content = fs.readFileSync(templatePath, 'utf-8');
20
+ const headerPattern = /\/\*\*[\s\S]*?\* NOTE: This file is read at codegen time and written to output\.[\s\S]*?\*\/\n*/;
21
+ content = content.replace(headerPattern, getGeneratedFileHeader(description) + '\n');
22
+ return content;
23
+ }
24
+ /**
25
+ * Generate selection.ts content - shared selection types + runtime mappers
26
+ */
27
+ export function generateSelectionFile() {
28
+ return readTemplateFile('hooks-selection.ts', 'Selection helpers for React Query hooks');
29
+ }
@@ -1,18 +1,5 @@
1
- /**
2
- * Shared types generator
3
- *
4
- * Generates shared TypeScript types that can be imported by both
5
- * React Query SDK and ORM client outputs.
6
- *
7
- * Output structure:
8
- * shared/
9
- * index.ts - Barrel export
10
- * types.ts - Entity interfaces
11
- * schema-types.ts - Enums, input types, payload types
12
- * filters.ts - Filter types (StringFilter, IntFilter, etc.)
13
- */
14
- import type { CleanTable, CleanOperation, TypeRegistry } from '../../../types/schema';
15
1
  import type { GraphQLSDKConfigTarget } from '../../../types/config';
2
+ import type { CleanOperation, CleanTable, TypeRegistry } from '../../../types/schema';
16
3
  export interface GeneratedFile {
17
4
  path: string;
18
5
  content: string;
@@ -35,5 +22,5 @@ export interface GenerateSharedResult {
35
22
  * Generate shared types that can be imported by both React Query SDK and ORM client
36
23
  */
37
24
  export declare function generateSharedTypes(options: GenerateSharedOptions): GenerateSharedResult;
38
- export { generateTypesFile } from '../types';
39
25
  export { generateSchemaTypesFile } from '../schema-types-generator';
26
+ export { generateTypesFile } from '../types';
@@ -1,7 +1,20 @@
1
+ /**
2
+ * Shared types generator
3
+ *
4
+ * Generates shared TypeScript types that can be imported by both
5
+ * React Query SDK and ORM client outputs.
6
+ *
7
+ * Output structure:
8
+ * shared/
9
+ * index.ts - Barrel export
10
+ * types.ts - Entity interfaces
11
+ * schema-types.ts - Enums, input types, payload types
12
+ * filters.ts - Filter types (StringFilter, IntFilter, etc.)
13
+ */
1
14
  import * as t from '@babel/types';
2
- import { generateCode, addJSDocComment } from '../babel-ast';
3
- import { generateTypesFile } from '../types';
15
+ import { addJSDocComment, generateCode } from '../babel-ast';
4
16
  import { generateSchemaTypesFile } from '../schema-types-generator';
17
+ import { generateTypesFile } from '../types';
5
18
  import { getTableNames } from '../utils';
6
19
  /**
7
20
  * Helper to create export * from './module' statement
@@ -75,5 +88,5 @@ function generateSharedBarrel(hasSchemaTypes) {
75
88
  }
76
89
  return generateCode(statements);
77
90
  }
78
- export { generateTypesFile } from '../types';
79
91
  export { generateSchemaTypesFile } from '../schema-types-generator';
92
+ export { generateTypesFile } from '../types';
@@ -4,7 +4,7 @@
4
4
  * Utilities for converting CleanTypeRef and other GraphQL types
5
5
  * into TypeScript type strings and interface definitions.
6
6
  */
7
- import type { CleanTypeRef, CleanObjectField } from '../../types/schema';
7
+ import type { CleanTypeRef } from '../../types/schema';
8
8
  /**
9
9
  * Interface for tracking referenced types during code generation
10
10
  */
@@ -73,10 +73,6 @@ export declare function getBaseTypeKind(typeRef: CleanTypeRef): CleanTypeRef['ki
73
73
  * Check if a field should be skipped in selections
74
74
  */
75
75
  export declare function shouldSkipField(fieldName: string, skipQueryField: boolean): boolean;
76
- /**
77
- * Filter fields to only include selectable scalar and object fields
78
- */
79
- export declare function getSelectableFields(fields: CleanObjectField[] | undefined, skipQueryField: boolean, maxDepth?: number, currentDepth?: number): CleanObjectField[];
80
76
  /**
81
77
  * Convert operation name to PascalCase for type names
82
78
  */
@@ -1,4 +1,4 @@
1
- import { scalarToTsType as resolveScalarToTs, SCALAR_NAMES } from './scalars';
1
+ import { SCALAR_NAMES, scalarToTsType as resolveScalarToTs } from './scalars';
2
2
  // ============================================================================
3
3
  // Type Tracker for Collecting Referenced Types
4
4
  // ============================================================================
@@ -175,27 +175,6 @@ export function shouldSkipField(fieldName, skipQueryField) {
175
175
  return true;
176
176
  return false;
177
177
  }
178
- /**
179
- * Filter fields to only include selectable scalar and object fields
180
- */
181
- export function getSelectableFields(fields, skipQueryField, maxDepth = 2, currentDepth = 0) {
182
- if (!fields || currentDepth >= maxDepth)
183
- return [];
184
- return fields.filter((field) => {
185
- // Skip internal fields
186
- if (shouldSkipField(field.name, skipQueryField))
187
- return false;
188
- // Get base type kind
189
- const baseKind = getBaseTypeKind(field.type);
190
- // Include scalars and enums
191
- if (baseKind === 'SCALAR' || baseKind === 'ENUM')
192
- return true;
193
- // Include objects up to max depth
194
- if (baseKind === 'OBJECT' && currentDepth < maxDepth - 1)
195
- return true;
196
- return false;
197
- });
198
- }
199
178
  // ============================================================================
200
179
  // Type Name Utilities
201
180
  // ============================================================================
@@ -1,6 +1,3 @@
1
- /**
2
- * Types generator - generates types.ts with entity interfaces using Babel AST
3
- */
4
1
  import type { CleanTable } from '../../types/schema';
5
2
  /**
6
3
  * Options for generating types.ts
@@ -1,26 +1,81 @@
1
+ /**
2
+ * Types generator - generates types.ts with entity interfaces using Babel AST
3
+ */
1
4
  import * as t from '@babel/types';
2
5
  import { generateCode } from './babel-ast';
3
- import { getScalarFields, fieldTypeToTs, getGeneratedFileHeader } from './utils';
6
+ import { fieldTypeToTs, getGeneratedFileHeader, getScalarFields, } from './utils';
4
7
  /** All filter type configurations - scalar and list filters */
5
8
  const FILTER_CONFIGS = [
6
9
  // Scalar filters
7
- { name: 'StringFilter', tsType: 'string', operators: ['equality', 'distinct', 'inArray', 'comparison', 'string'] },
8
- { name: 'IntFilter', tsType: 'number', operators: ['equality', 'distinct', 'inArray', 'comparison'] },
9
- { name: 'FloatFilter', tsType: 'number', operators: ['equality', 'distinct', 'inArray', 'comparison'] },
10
+ {
11
+ name: 'StringFilter',
12
+ tsType: 'string',
13
+ operators: ['equality', 'distinct', 'inArray', 'comparison', 'string'],
14
+ },
15
+ {
16
+ name: 'IntFilter',
17
+ tsType: 'number',
18
+ operators: ['equality', 'distinct', 'inArray', 'comparison'],
19
+ },
20
+ {
21
+ name: 'FloatFilter',
22
+ tsType: 'number',
23
+ operators: ['equality', 'distinct', 'inArray', 'comparison'],
24
+ },
10
25
  { name: 'BooleanFilter', tsType: 'boolean', operators: ['equality'] },
11
- { name: 'UUIDFilter', tsType: 'string', operators: ['equality', 'distinct', 'inArray'] },
12
- { name: 'DatetimeFilter', tsType: 'string', operators: ['equality', 'distinct', 'inArray', 'comparison'] },
13
- { name: 'DateFilter', tsType: 'string', operators: ['equality', 'distinct', 'inArray', 'comparison'] },
14
- { name: 'JSONFilter', tsType: 'Record<string, unknown>', operators: ['equality', 'distinct', 'json'] },
15
- { name: 'BigIntFilter', tsType: 'string', operators: ['equality', 'distinct', 'inArray', 'comparison'] },
16
- { name: 'BigFloatFilter', tsType: 'string', operators: ['equality', 'distinct', 'inArray', 'comparison'] },
26
+ {
27
+ name: 'UUIDFilter',
28
+ tsType: 'string',
29
+ operators: ['equality', 'distinct', 'inArray'],
30
+ },
31
+ {
32
+ name: 'DatetimeFilter',
33
+ tsType: 'string',
34
+ operators: ['equality', 'distinct', 'inArray', 'comparison'],
35
+ },
36
+ {
37
+ name: 'DateFilter',
38
+ tsType: 'string',
39
+ operators: ['equality', 'distinct', 'inArray', 'comparison'],
40
+ },
41
+ {
42
+ name: 'JSONFilter',
43
+ tsType: 'Record<string, unknown>',
44
+ operators: ['equality', 'distinct', 'json'],
45
+ },
46
+ {
47
+ name: 'BigIntFilter',
48
+ tsType: 'string',
49
+ operators: ['equality', 'distinct', 'inArray', 'comparison'],
50
+ },
51
+ {
52
+ name: 'BigFloatFilter',
53
+ tsType: 'string',
54
+ operators: ['equality', 'distinct', 'inArray', 'comparison'],
55
+ },
17
56
  { name: 'BitStringFilter', tsType: 'string', operators: ['equality'] },
18
- { name: 'InternetAddressFilter', tsType: 'string', operators: ['equality', 'distinct', 'inArray', 'comparison', 'inet'] },
57
+ {
58
+ name: 'InternetAddressFilter',
59
+ tsType: 'string',
60
+ operators: ['equality', 'distinct', 'inArray', 'comparison', 'inet'],
61
+ },
19
62
  { name: 'FullTextFilter', tsType: 'string', operators: ['fulltext'] },
20
63
  // List filters
21
- { name: 'StringListFilter', tsType: 'string[]', operators: ['equality', 'distinct', 'comparison', 'listArray'] },
22
- { name: 'IntListFilter', tsType: 'number[]', operators: ['equality', 'distinct', 'comparison', 'listArray'] },
23
- { name: 'UUIDListFilter', tsType: 'string[]', operators: ['equality', 'distinct', 'comparison', 'listArray'] },
64
+ {
65
+ name: 'StringListFilter',
66
+ tsType: 'string[]',
67
+ operators: ['equality', 'distinct', 'comparison', 'listArray'],
68
+ },
69
+ {
70
+ name: 'IntListFilter',
71
+ tsType: 'number[]',
72
+ operators: ['equality', 'distinct', 'comparison', 'listArray'],
73
+ },
74
+ {
75
+ name: 'UUIDListFilter',
76
+ tsType: 'string[]',
77
+ operators: ['equality', 'distinct', 'comparison', 'listArray'],
78
+ },
24
79
  ];
25
80
  /** Build filter properties based on operator sets */
26
81
  function buildFilterProperties(tsType, operators) {
@@ -75,7 +130,9 @@ function parseTypeAnnotation(typeStr) {
75
130
  if (typeStr === 'unknown')
76
131
  return t.tsUnknownKeyword();
77
132
  if (typeStr.includes(' | ')) {
78
- const parts = typeStr.split(' | ').map((p) => parseTypeAnnotation(p.trim()));
133
+ const parts = typeStr
134
+ .split(' | ')
135
+ .map((p) => parseTypeAnnotation(p.trim()));
79
136
  return t.tsUnionType(parts);
80
137
  }
81
138
  if (typeStr.endsWith('[]')) {
@@ -1,7 +1,4 @@
1
- /**
2
- * Codegen utilities - naming conventions, type mapping, and helpers
3
- */
4
- import type { CleanTable, CleanField, CleanFieldType } from '../../types/schema';
1
+ import type { CleanField, CleanFieldType, CleanTable } from '../../types/schema';
5
2
  /** Lowercase first character */
6
3
  export declare function lcFirst(str: string): string;
7
4
  /** Uppercase first character */
@@ -1,5 +1,8 @@
1
- import { scalarToTsType, scalarToFilterType } from './scalars';
1
+ /**
2
+ * Codegen utilities - naming conventions, type mapping, and helpers
3
+ */
2
4
  import { pluralize } from 'inflekt';
5
+ import { scalarToFilterType, scalarToTsType } from './scalars';
3
6
  // ============================================================================
4
7
  // String manipulation
5
8
  // ============================================================================
@@ -2,4 +2,4 @@
2
2
  * Configuration module exports
3
3
  */
4
4
  export { CONFIG_FILENAME, findConfigFile, loadConfigFile, type LoadConfigFileResult, } from './loader';
5
- export { loadAndResolveConfig, loadWatchConfig, type ConfigOverrideOptions, type LoadConfigResult, } from './resolver';
5
+ export { type ConfigOverrideOptions, loadAndResolveConfig, type LoadConfigResult, loadWatchConfig, } from './resolver';
@@ -1,4 +1,4 @@
1
- import { mergeConfig, getConfigOptions } from '../../types/config';
1
+ import { getConfigOptions, mergeConfig } from '../../types/config';
2
2
  import { findConfigFile, loadConfigFile } from './loader';
3
3
  /**
4
4
  * Load and resolve configuration from file and/or options
@@ -38,9 +38,7 @@ export async function loadAndResolveConfig(options) {
38
38
  }
39
39
  const mergedConfig = mergeConfig(baseConfig, overrides);
40
40
  // Check if we have a source (endpoint, schemaFile, or db)
41
- const hasSource = mergedConfig.endpoint ||
42
- mergedConfig.schemaFile ||
43
- mergedConfig.db;
41
+ const hasSource = mergedConfig.endpoint || mergedConfig.schemaFile || mergedConfig.db;
44
42
  if (!hasSource) {
45
43
  return {
46
44
  success: false,