@constructive-io/graphql-codegen 2.24.0 → 2.26.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 (66) hide show
  1. package/README.md +403 -279
  2. package/cli/codegen/babel-ast.d.ts +7 -0
  3. package/cli/codegen/babel-ast.js +15 -0
  4. package/cli/codegen/barrel.js +43 -14
  5. package/cli/codegen/custom-mutations.js +4 -4
  6. package/cli/codegen/custom-queries.js +12 -22
  7. package/cli/codegen/gql-ast.js +22 -1
  8. package/cli/codegen/index.js +1 -0
  9. package/cli/codegen/mutations.d.ts +2 -0
  10. package/cli/codegen/mutations.js +26 -13
  11. package/cli/codegen/orm/client-generator.js +475 -136
  12. package/cli/codegen/orm/custom-ops-generator.js +8 -3
  13. package/cli/codegen/orm/input-types-generator.js +22 -0
  14. package/cli/codegen/orm/model-generator.js +18 -5
  15. package/cli/codegen/orm/select-types.d.ts +33 -0
  16. package/cli/codegen/queries.d.ts +1 -1
  17. package/cli/codegen/queries.js +112 -35
  18. package/cli/codegen/utils.d.ts +6 -0
  19. package/cli/codegen/utils.js +19 -0
  20. package/cli/commands/generate-orm.d.ts +14 -0
  21. package/cli/commands/generate-orm.js +160 -44
  22. package/cli/commands/generate.d.ts +22 -0
  23. package/cli/commands/generate.js +195 -55
  24. package/cli/commands/init.js +29 -9
  25. package/cli/index.js +133 -28
  26. package/cli/watch/orchestrator.d.ts +4 -0
  27. package/cli/watch/orchestrator.js +4 -0
  28. package/esm/cli/codegen/babel-ast.d.ts +7 -0
  29. package/esm/cli/codegen/babel-ast.js +14 -0
  30. package/esm/cli/codegen/barrel.js +44 -15
  31. package/esm/cli/codegen/custom-mutations.js +5 -5
  32. package/esm/cli/codegen/custom-queries.js +13 -23
  33. package/esm/cli/codegen/gql-ast.js +23 -2
  34. package/esm/cli/codegen/index.js +1 -0
  35. package/esm/cli/codegen/mutations.d.ts +2 -0
  36. package/esm/cli/codegen/mutations.js +27 -14
  37. package/esm/cli/codegen/orm/client-generator.js +475 -136
  38. package/esm/cli/codegen/orm/custom-ops-generator.js +8 -3
  39. package/esm/cli/codegen/orm/input-types-generator.js +22 -0
  40. package/esm/cli/codegen/orm/model-generator.js +18 -5
  41. package/esm/cli/codegen/orm/select-types.d.ts +33 -0
  42. package/esm/cli/codegen/queries.d.ts +1 -1
  43. package/esm/cli/codegen/queries.js +114 -37
  44. package/esm/cli/codegen/utils.d.ts +6 -0
  45. package/esm/cli/codegen/utils.js +18 -0
  46. package/esm/cli/commands/generate-orm.d.ts +14 -0
  47. package/esm/cli/commands/generate-orm.js +161 -45
  48. package/esm/cli/commands/generate.d.ts +22 -0
  49. package/esm/cli/commands/generate.js +195 -56
  50. package/esm/cli/commands/init.js +29 -9
  51. package/esm/cli/index.js +134 -29
  52. package/esm/cli/watch/orchestrator.d.ts +4 -0
  53. package/esm/cli/watch/orchestrator.js +5 -1
  54. package/esm/types/config.d.ts +39 -2
  55. package/esm/types/config.js +88 -4
  56. package/esm/types/index.d.ts +2 -2
  57. package/esm/types/index.js +1 -1
  58. package/package.json +10 -7
  59. package/types/config.d.ts +39 -2
  60. package/types/config.js +91 -4
  61. package/types/index.d.ts +2 -2
  62. package/types/index.js +2 -1
  63. package/cli/codegen/orm/query-builder.d.ts +0 -161
  64. package/cli/codegen/orm/query-builder.js +0 -366
  65. package/esm/cli/codegen/orm/query-builder.d.ts +0 -161
  66. package/esm/cli/codegen/orm/query-builder.js +0 -353
@@ -44,3 +44,10 @@ export declare function typedParam(name: string, typeAnnotation: t.TSType, optio
44
44
  * Create keyof typeof expression - complex nested type operators
45
45
  */
46
46
  export declare function keyofTypeof(name: string): t.TSTypeOperator;
47
+ /**
48
+ * Create a call expression with TypeScript type parameters
49
+ *
50
+ * This is used to generate typed function calls like:
51
+ * execute<ResultType, VariablesType>(document, variables)
52
+ */
53
+ export declare function createTypedCallExpression(callee: t.Expression, args: (t.Expression | t.SpreadElement)[], typeParams: t.TSType[]): t.CallExpression;
@@ -44,6 +44,7 @@ exports.asConst = asConst;
44
44
  exports.constArray = constArray;
45
45
  exports.typedParam = typedParam;
46
46
  exports.keyofTypeof = keyofTypeof;
47
+ exports.createTypedCallExpression = createTypedCallExpression;
47
48
  /**
48
49
  * Babel AST utilities for code generation
49
50
  *
@@ -143,3 +144,17 @@ function keyofTypeof(name) {
143
144
  keyofOp.operator = 'keyof';
144
145
  return keyofOp;
145
146
  }
147
+ /**
148
+ * Create a call expression with TypeScript type parameters
149
+ *
150
+ * This is used to generate typed function calls like:
151
+ * execute<ResultType, VariablesType>(document, variables)
152
+ */
153
+ function createTypedCallExpression(callee, args, typeParams) {
154
+ const call = t.callExpression(callee, args);
155
+ if (typeParams.length > 0) {
156
+ // @ts-ignore - Babel types support typeParameters on CallExpression for TS
157
+ call.typeParameters = t.tsTypeParameterInstantiation(typeParams);
158
+ }
159
+ return call;
160
+ }
@@ -56,9 +56,12 @@ function generateQueriesBarrel(tables) {
56
56
  // Export all query hooks
57
57
  for (const table of tables) {
58
58
  const listHookName = (0, utils_1.getListQueryHookName)(table);
59
- const singleHookName = (0, utils_1.getSingleQueryHookName)(table);
60
59
  statements.push(exportAllFrom(`./${listHookName}`));
61
- statements.push(exportAllFrom(`./${singleHookName}`));
60
+ // Only export single query hook if table has valid primary key
61
+ if ((0, utils_1.hasValidPrimaryKey)(table)) {
62
+ const singleHookName = (0, utils_1.getSingleQueryHookName)(table);
63
+ statements.push(exportAllFrom(`./${singleHookName}`));
64
+ }
62
65
  }
63
66
  // Add file header as leading comment on first statement
64
67
  if (statements.length > 0) {
@@ -175,17 +178,30 @@ function generateMainBarrel(tables, options = {}) {
175
178
  */
176
179
  function generateCustomQueriesBarrel(tables, customQueryNames) {
177
180
  const statements = [];
181
+ const exportedHooks = new Set();
178
182
  // Export all table query hooks
179
183
  for (const table of tables) {
180
184
  const listHookName = (0, utils_1.getListQueryHookName)(table);
181
- const singleHookName = (0, utils_1.getSingleQueryHookName)(table);
182
- statements.push(exportAllFrom(`./${listHookName}`));
183
- statements.push(exportAllFrom(`./${singleHookName}`));
185
+ if (!exportedHooks.has(listHookName)) {
186
+ statements.push(exportAllFrom(`./${listHookName}`));
187
+ exportedHooks.add(listHookName);
188
+ }
189
+ // Only export single query hook if table has valid primary key
190
+ if ((0, utils_1.hasValidPrimaryKey)(table)) {
191
+ const singleHookName = (0, utils_1.getSingleQueryHookName)(table);
192
+ if (!exportedHooks.has(singleHookName)) {
193
+ statements.push(exportAllFrom(`./${singleHookName}`));
194
+ exportedHooks.add(singleHookName);
195
+ }
196
+ }
184
197
  }
185
- // Add custom query hooks
198
+ // Add custom query hooks (skip if already exported from table hooks)
186
199
  for (const name of customQueryNames) {
187
200
  const hookName = (0, type_resolver_1.getOperationHookName)(name, 'query');
188
- statements.push(exportAllFrom(`./${hookName}`));
201
+ if (!exportedHooks.has(hookName)) {
202
+ statements.push(exportAllFrom(`./${hookName}`));
203
+ exportedHooks.add(hookName);
204
+ }
189
205
  }
190
206
  // Add file header as leading comment on first statement
191
207
  if (statements.length > 0) {
@@ -202,24 +218,37 @@ function generateCustomQueriesBarrel(tables, customQueryNames) {
202
218
  */
203
219
  function generateCustomMutationsBarrel(tables, customMutationNames) {
204
220
  const statements = [];
221
+ const exportedHooks = new Set();
205
222
  // Export all table mutation hooks
206
223
  for (const table of tables) {
207
224
  const createHookName = (0, utils_1.getCreateMutationHookName)(table);
208
- const updateHookName = (0, utils_1.getUpdateMutationHookName)(table);
209
- const deleteHookName = (0, utils_1.getDeleteMutationHookName)(table);
210
- statements.push(exportAllFrom(`./${createHookName}`));
225
+ if (!exportedHooks.has(createHookName)) {
226
+ statements.push(exportAllFrom(`./${createHookName}`));
227
+ exportedHooks.add(createHookName);
228
+ }
211
229
  // Only add update/delete if they exist
212
230
  if (table.query?.update !== null) {
213
- statements.push(exportAllFrom(`./${updateHookName}`));
231
+ const updateHookName = (0, utils_1.getUpdateMutationHookName)(table);
232
+ if (!exportedHooks.has(updateHookName)) {
233
+ statements.push(exportAllFrom(`./${updateHookName}`));
234
+ exportedHooks.add(updateHookName);
235
+ }
214
236
  }
215
237
  if (table.query?.delete !== null) {
216
- statements.push(exportAllFrom(`./${deleteHookName}`));
238
+ const deleteHookName = (0, utils_1.getDeleteMutationHookName)(table);
239
+ if (!exportedHooks.has(deleteHookName)) {
240
+ statements.push(exportAllFrom(`./${deleteHookName}`));
241
+ exportedHooks.add(deleteHookName);
242
+ }
217
243
  }
218
244
  }
219
- // Add custom mutation hooks
245
+ // Add custom mutation hooks (skip if already exported from table hooks)
220
246
  for (const name of customMutationNames) {
221
247
  const hookName = (0, type_resolver_1.getOperationHookName)(name, 'mutation');
222
- statements.push(exportAllFrom(`./${hookName}`));
248
+ if (!exportedHooks.has(hookName)) {
249
+ statements.push(exportAllFrom(`./${hookName}`));
250
+ exportedHooks.add(hookName);
251
+ }
223
252
  }
224
253
  // Add file header as leading comment on first statement
225
254
  if (statements.length > 0) {
@@ -131,13 +131,13 @@ function generateCustomMutationHookInternal(options) {
131
131
  mutationOptions.push(t.objectProperty(t.identifier('mutationKey'), t.callExpression(t.memberExpression(t.identifier('customMutationKeys'), t.identifier(operation.name)), [])));
132
132
  }
133
133
  if (hasArgs) {
134
- mutationOptions.push(t.objectProperty(t.identifier('mutationFn'), t.arrowFunctionExpression([(0, babel_ast_1.typedParam)('variables', t.tsTypeReference(t.identifier(variablesTypeName)))], t.callExpression(t.identifier('execute'), [
135
- t.identifier(documentConstName),
136
- t.identifier('variables'),
134
+ mutationOptions.push(t.objectProperty(t.identifier('mutationFn'), t.arrowFunctionExpression([(0, babel_ast_1.typedParam)('variables', t.tsTypeReference(t.identifier(variablesTypeName)))], (0, babel_ast_1.createTypedCallExpression)(t.identifier('execute'), [t.identifier(documentConstName), t.identifier('variables')], [
135
+ t.tsTypeReference(t.identifier(resultTypeName)),
136
+ t.tsTypeReference(t.identifier(variablesTypeName)),
137
137
  ]))));
138
138
  }
139
139
  else {
140
- mutationOptions.push(t.objectProperty(t.identifier('mutationFn'), t.arrowFunctionExpression([], t.callExpression(t.identifier('execute'), [t.identifier(documentConstName)]))));
140
+ mutationOptions.push(t.objectProperty(t.identifier('mutationFn'), t.arrowFunctionExpression([], (0, babel_ast_1.createTypedCallExpression)(t.identifier('execute'), [t.identifier(documentConstName)], [t.tsTypeReference(t.identifier(resultTypeName))]))));
141
141
  }
142
142
  mutationOptions.push(t.spreadElement(t.identifier('options')));
143
143
  hookBodyStatements.push(t.returnStatement(t.callExpression(t.identifier('useMutation'), [t.objectExpression(mutationOptions)])));
@@ -152,9 +152,9 @@ function generateCustomQueryHook(options) {
152
152
  const useQueryOptions = [];
153
153
  if (hasArgs) {
154
154
  useQueryOptions.push(t.objectProperty(t.identifier('queryKey'), t.callExpression(t.identifier(queryKeyName), [t.identifier('variables')])));
155
- useQueryOptions.push(t.objectProperty(t.identifier('queryFn'), t.arrowFunctionExpression([], t.callExpression(t.identifier('execute'), [
156
- t.identifier(documentConstName),
157
- t.identifier('variables'),
155
+ useQueryOptions.push(t.objectProperty(t.identifier('queryFn'), t.arrowFunctionExpression([], (0, babel_ast_1.createTypedCallExpression)(t.identifier('execute'), [t.identifier(documentConstName), t.identifier('variables')], [
156
+ t.tsTypeReference(t.identifier(resultTypeName)),
157
+ t.tsTypeReference(t.identifier(variablesTypeName)),
158
158
  ]))));
159
159
  if (hasRequiredArgs) {
160
160
  useQueryOptions.push(t.objectProperty(t.identifier('enabled'), t.logicalExpression('&&', t.unaryExpression('!', t.unaryExpression('!', t.identifier('variables'))), t.binaryExpression('!==', t.optionalMemberExpression(t.identifier('options'), t.identifier('enabled'), false, true), t.booleanLiteral(false)))));
@@ -162,7 +162,7 @@ function generateCustomQueryHook(options) {
162
162
  }
163
163
  else {
164
164
  useQueryOptions.push(t.objectProperty(t.identifier('queryKey'), t.callExpression(t.identifier(queryKeyName), [])));
165
- useQueryOptions.push(t.objectProperty(t.identifier('queryFn'), t.arrowFunctionExpression([], t.callExpression(t.identifier('execute'), [t.identifier(documentConstName)]))));
165
+ useQueryOptions.push(t.objectProperty(t.identifier('queryFn'), t.arrowFunctionExpression([], (0, babel_ast_1.createTypedCallExpression)(t.identifier('execute'), [t.identifier(documentConstName)], [t.tsTypeReference(t.identifier(resultTypeName))]))));
166
166
  }
167
167
  useQueryOptions.push(t.spreadElement(t.identifier('options')));
168
168
  hookBodyStatements.push(t.returnStatement(t.callExpression(t.identifier('useQuery'), [t.objectExpression(useQueryOptions)])));
@@ -199,18 +199,13 @@ function generateCustomQueryHook(options) {
199
199
  const hasRequiredArgs = operation.args.some((arg) => (0, type_resolver_1.isTypeRequired)(arg.type));
200
200
  const fetchBodyStatements = [];
201
201
  if (hasArgs) {
202
- fetchBodyStatements.push(t.returnStatement(t.callExpression(t.identifier('execute'), [
203
- t.identifier(documentConstName),
204
- t.identifier('variables'),
205
- t.identifier('options'),
202
+ fetchBodyStatements.push(t.returnStatement((0, babel_ast_1.createTypedCallExpression)(t.identifier('execute'), [t.identifier(documentConstName), t.identifier('variables'), t.identifier('options')], [
203
+ t.tsTypeReference(t.identifier(resultTypeName)),
204
+ t.tsTypeReference(t.identifier(variablesTypeName)),
206
205
  ])));
207
206
  }
208
207
  else {
209
- fetchBodyStatements.push(t.returnStatement(t.callExpression(t.identifier('execute'), [
210
- t.identifier(documentConstName),
211
- t.identifier('undefined'),
212
- t.identifier('options'),
213
- ])));
208
+ fetchBodyStatements.push(t.returnStatement((0, babel_ast_1.createTypedCallExpression)(t.identifier('execute'), [t.identifier(documentConstName), t.identifier('undefined'), t.identifier('options')], [t.tsTypeReference(t.identifier(resultTypeName))])));
214
209
  }
215
210
  const fetchParams = [];
216
211
  if (hasArgs) {
@@ -238,19 +233,14 @@ function generateCustomQueryHook(options) {
238
233
  const prefetchQueryOptions = [];
239
234
  if (hasArgs) {
240
235
  prefetchQueryOptions.push(t.objectProperty(t.identifier('queryKey'), t.callExpression(t.identifier(queryKeyName), [t.identifier('variables')])));
241
- prefetchQueryOptions.push(t.objectProperty(t.identifier('queryFn'), t.arrowFunctionExpression([], t.callExpression(t.identifier('execute'), [
242
- t.identifier(documentConstName),
243
- t.identifier('variables'),
244
- t.identifier('options'),
236
+ prefetchQueryOptions.push(t.objectProperty(t.identifier('queryFn'), t.arrowFunctionExpression([], (0, babel_ast_1.createTypedCallExpression)(t.identifier('execute'), [t.identifier(documentConstName), t.identifier('variables'), t.identifier('options')], [
237
+ t.tsTypeReference(t.identifier(resultTypeName)),
238
+ t.tsTypeReference(t.identifier(variablesTypeName)),
245
239
  ]))));
246
240
  }
247
241
  else {
248
242
  prefetchQueryOptions.push(t.objectProperty(t.identifier('queryKey'), t.callExpression(t.identifier(queryKeyName), [])));
249
- prefetchQueryOptions.push(t.objectProperty(t.identifier('queryFn'), t.arrowFunctionExpression([], t.callExpression(t.identifier('execute'), [
250
- t.identifier(documentConstName),
251
- t.identifier('undefined'),
252
- t.identifier('options'),
253
- ]))));
243
+ prefetchQueryOptions.push(t.objectProperty(t.identifier('queryFn'), t.arrowFunctionExpression([], (0, babel_ast_1.createTypedCallExpression)(t.identifier('execute'), [t.identifier(documentConstName), t.identifier('undefined'), t.identifier('options')], [t.tsTypeReference(t.identifier(resultTypeName))]))));
254
244
  }
255
245
  prefetchBodyStatements.push(t.expressionStatement(t.awaitExpression(t.callExpression(t.memberExpression(t.identifier('queryClient'), t.identifier('prefetchQuery')), [t.objectExpression(prefetchQueryOptions)]))));
256
246
  const prefetchParams = [
@@ -80,22 +80,39 @@ function buildListQueryAST(config) {
80
80
  const { table } = config;
81
81
  const queryName = (0, utils_1.getAllRowsQueryName)(table);
82
82
  const filterType = (0, utils_1.getFilterTypeName)(table);
83
+ const conditionType = (0, utils_1.getConditionTypeName)(table);
83
84
  const orderByType = (0, utils_1.getOrderByTypeName)(table);
84
85
  const scalarFields = (0, utils_1.getScalarFields)(table);
85
- // Variable definitions
86
+ // Variable definitions - all pagination arguments from PostGraphile
86
87
  const variableDefinitions = [
87
88
  t.variableDefinition({
88
89
  variable: t.variable({ name: 'first' }),
89
90
  type: t.namedType({ type: 'Int' }),
90
91
  }),
92
+ t.variableDefinition({
93
+ variable: t.variable({ name: 'last' }),
94
+ type: t.namedType({ type: 'Int' }),
95
+ }),
91
96
  t.variableDefinition({
92
97
  variable: t.variable({ name: 'offset' }),
93
98
  type: t.namedType({ type: 'Int' }),
94
99
  }),
100
+ t.variableDefinition({
101
+ variable: t.variable({ name: 'before' }),
102
+ type: t.namedType({ type: 'Cursor' }),
103
+ }),
104
+ t.variableDefinition({
105
+ variable: t.variable({ name: 'after' }),
106
+ type: t.namedType({ type: 'Cursor' }),
107
+ }),
95
108
  t.variableDefinition({
96
109
  variable: t.variable({ name: 'filter' }),
97
110
  type: t.namedType({ type: filterType }),
98
111
  }),
112
+ t.variableDefinition({
113
+ variable: t.variable({ name: 'condition' }),
114
+ type: t.namedType({ type: conditionType }),
115
+ }),
99
116
  t.variableDefinition({
100
117
  variable: t.variable({ name: 'orderBy' }),
101
118
  type: t.listType({
@@ -106,8 +123,12 @@ function buildListQueryAST(config) {
106
123
  // Query arguments
107
124
  const args = [
108
125
  t.argument({ name: 'first', value: t.variable({ name: 'first' }) }),
126
+ t.argument({ name: 'last', value: t.variable({ name: 'last' }) }),
109
127
  t.argument({ name: 'offset', value: t.variable({ name: 'offset' }) }),
128
+ t.argument({ name: 'before', value: t.variable({ name: 'before' }) }),
129
+ t.argument({ name: 'after', value: t.variable({ name: 'after' }) }),
110
130
  t.argument({ name: 'filter', value: t.variable({ name: 'filter' }) }),
131
+ t.argument({ name: 'condition', value: t.variable({ name: 'condition' }) }),
111
132
  t.argument({ name: 'orderBy', value: t.variable({ name: 'orderBy' }) }),
112
133
  ];
113
134
  // Field selections
@@ -157,6 +157,7 @@ function generate(options) {
157
157
  enumsFromSchemaTypes: generatedEnumNames,
158
158
  useCentralizedKeys,
159
159
  hasRelationships,
160
+ tableTypeNames,
160
161
  });
161
162
  for (const hook of mutationHooks) {
162
163
  files.push({
@@ -17,6 +17,8 @@ export interface MutationGeneratorOptions {
17
17
  enumsFromSchemaTypes?: string[];
18
18
  useCentralizedKeys?: boolean;
19
19
  hasRelationships?: boolean;
20
+ /** All table type names for determining which types to import from types.ts vs schema-types.ts */
21
+ tableTypeNames?: Set<string>;
20
22
  }
21
23
  export declare function generateCreateMutationHook(table: CleanTable, options?: MutationGeneratorOptions): GeneratedMutationFile | null;
22
24
  export declare function generateUpdateMutationHook(table: CleanTable, options?: MutationGeneratorOptions): GeneratedMutationFile | null;
@@ -53,7 +53,7 @@ function isAutoGeneratedField(fieldName, pkFieldNames) {
53
53
  return timestampPatterns.includes(name);
54
54
  }
55
55
  function generateCreateMutationHook(table, options = {}) {
56
- const { reactQueryEnabled = true, enumsFromSchemaTypes = [], useCentralizedKeys = true, hasRelationships = false, } = options;
56
+ const { reactQueryEnabled = true, enumsFromSchemaTypes = [], useCentralizedKeys = true, hasRelationships = false, tableTypeNames = new Set(), } = options;
57
57
  if (!reactQueryEnabled) {
58
58
  return null;
59
59
  }
@@ -67,11 +67,16 @@ function generateCreateMutationHook(table, options = {}) {
67
67
  const scalarFields = (0, utils_1.getScalarFields)(table);
68
68
  const pkFieldNames = new Set((0, utils_1.getPrimaryKeyInfo)(table).map((pk) => pk.name));
69
69
  const usedEnums = new Set();
70
+ const usedTableTypes = new Set();
70
71
  for (const field of scalarFields) {
71
72
  const cleanType = field.type.gqlType.replace(/!/g, '');
72
73
  if (enumSet.has(cleanType)) {
73
74
  usedEnums.add(cleanType);
74
75
  }
76
+ else if (tableTypeNames.has(cleanType) && cleanType !== typeName) {
77
+ // Track table types used in scalar fields (excluding the main type which is already imported)
78
+ usedTableTypes.add(cleanType);
79
+ }
75
80
  }
76
81
  const mutationAST = (0, gql_ast_1.buildCreateMutationAST)({ table });
77
82
  const mutationDocument = (0, gql_ast_1.printGraphQL)(mutationAST);
@@ -86,7 +91,9 @@ function generateCreateMutationHook(table, options = {}) {
86
91
  statements.push(reactQueryTypeImport);
87
92
  const clientImport = t.importDeclaration([t.importSpecifier(t.identifier('execute'), t.identifier('execute'))], t.stringLiteral('../client'));
88
93
  statements.push(clientImport);
89
- const typesImport = t.importDeclaration([t.importSpecifier(t.identifier(typeName), t.identifier(typeName))], t.stringLiteral('../types'));
94
+ // Import the main type and any other table types used in scalar fields
95
+ const allTypesToImport = [typeName, ...Array.from(usedTableTypes)].sort();
96
+ const typesImport = t.importDeclaration(allTypesToImport.map((t_) => t.importSpecifier(t.identifier(t_), t.identifier(t_))), t.stringLiteral('../types'));
90
97
  typesImport.importKind = 'type';
91
98
  statements.push(typesImport);
92
99
  if (usedEnums.size > 0) {
@@ -147,9 +154,9 @@ function generateCreateMutationHook(table, options = {}) {
147
154
  if (useCentralizedKeys) {
148
155
  mutationOptions.push(t.objectProperty(t.identifier('mutationKey'), t.callExpression(t.memberExpression(t.identifier(mutationKeysName), t.identifier('create')), [])));
149
156
  }
150
- mutationOptions.push(t.objectProperty(t.identifier('mutationFn'), t.arrowFunctionExpression([(0, babel_ast_1.typedParam)('variables', t.tsTypeReference(t.identifier(`${(0, utils_1.ucFirst)(mutationName)}MutationVariables`)))], t.callExpression(t.identifier('execute'), [
151
- t.identifier(`${mutationName}MutationDocument`),
152
- t.identifier('variables'),
157
+ mutationOptions.push(t.objectProperty(t.identifier('mutationFn'), t.arrowFunctionExpression([(0, babel_ast_1.typedParam)('variables', t.tsTypeReference(t.identifier(`${(0, utils_1.ucFirst)(mutationName)}MutationVariables`)))], (0, babel_ast_1.createTypedCallExpression)(t.identifier('execute'), [t.identifier(`${mutationName}MutationDocument`), t.identifier('variables')], [
158
+ t.tsTypeReference(t.identifier(`${(0, utils_1.ucFirst)(mutationName)}MutationResult`)),
159
+ t.tsTypeReference(t.identifier(`${(0, utils_1.ucFirst)(mutationName)}MutationVariables`)),
153
160
  ]))));
154
161
  const invalidateQueryKey = useCentralizedKeys
155
162
  ? t.callExpression(t.memberExpression(t.identifier(keysName), t.identifier('lists')), [])
@@ -190,7 +197,7 @@ function generateCreateMutationHook(table, options = {}) {
190
197
  };
191
198
  }
192
199
  function generateUpdateMutationHook(table, options = {}) {
193
- const { reactQueryEnabled = true, enumsFromSchemaTypes = [], useCentralizedKeys = true, hasRelationships = false, } = options;
200
+ const { reactQueryEnabled = true, enumsFromSchemaTypes = [], useCentralizedKeys = true, hasRelationships = false, tableTypeNames = new Set(), } = options;
194
201
  if (!reactQueryEnabled) {
195
202
  return null;
196
203
  }
@@ -209,11 +216,15 @@ function generateUpdateMutationHook(table, options = {}) {
209
216
  const pkField = pkFields[0];
210
217
  const pkFieldNames = new Set(pkFields.map((pk) => pk.name));
211
218
  const usedEnums = new Set();
219
+ const usedTableTypes = new Set();
212
220
  for (const field of scalarFields) {
213
221
  const cleanType = field.type.gqlType.replace(/!/g, '');
214
222
  if (enumSet.has(cleanType)) {
215
223
  usedEnums.add(cleanType);
216
224
  }
225
+ else if (tableTypeNames.has(cleanType) && cleanType !== typeName) {
226
+ usedTableTypes.add(cleanType);
227
+ }
217
228
  }
218
229
  const mutationAST = (0, gql_ast_1.buildUpdateMutationAST)({ table });
219
230
  const mutationDocument = (0, gql_ast_1.printGraphQL)(mutationAST);
@@ -228,7 +239,9 @@ function generateUpdateMutationHook(table, options = {}) {
228
239
  statements.push(reactQueryTypeImport);
229
240
  const clientImport = t.importDeclaration([t.importSpecifier(t.identifier('execute'), t.identifier('execute'))], t.stringLiteral('../client'));
230
241
  statements.push(clientImport);
231
- const typesImport = t.importDeclaration([t.importSpecifier(t.identifier(typeName), t.identifier(typeName))], t.stringLiteral('../types'));
242
+ // Import the main type and any other table types used in scalar fields
243
+ const allTypesToImportUpdate = [typeName, ...Array.from(usedTableTypes)].sort();
244
+ const typesImport = t.importDeclaration(allTypesToImportUpdate.map((t_) => t.importSpecifier(t.identifier(t_), t.identifier(t_))), t.stringLiteral('../types'));
232
245
  typesImport.importKind = 'type';
233
246
  statements.push(typesImport);
234
247
  if (usedEnums.size > 0) {
@@ -295,9 +308,9 @@ function generateUpdateMutationHook(table, options = {}) {
295
308
  if (useCentralizedKeys) {
296
309
  mutationOptions.push(t.objectProperty(t.identifier('mutationKey'), t.memberExpression(t.identifier(mutationKeysName), t.identifier('all'))));
297
310
  }
298
- mutationOptions.push(t.objectProperty(t.identifier('mutationFn'), t.arrowFunctionExpression([(0, babel_ast_1.typedParam)('variables', t.tsTypeReference(t.identifier(`${(0, utils_1.ucFirst)(mutationName)}MutationVariables`)))], t.callExpression(t.identifier('execute'), [
299
- t.identifier(`${mutationName}MutationDocument`),
300
- t.identifier('variables'),
311
+ mutationOptions.push(t.objectProperty(t.identifier('mutationFn'), t.arrowFunctionExpression([(0, babel_ast_1.typedParam)('variables', t.tsTypeReference(t.identifier(`${(0, utils_1.ucFirst)(mutationName)}MutationVariables`)))], (0, babel_ast_1.createTypedCallExpression)(t.identifier('execute'), [t.identifier(`${mutationName}MutationDocument`), t.identifier('variables')], [
312
+ t.tsTypeReference(t.identifier(`${(0, utils_1.ucFirst)(mutationName)}MutationResult`)),
313
+ t.tsTypeReference(t.identifier(`${(0, utils_1.ucFirst)(mutationName)}MutationVariables`)),
301
314
  ]))));
302
315
  const detailQueryKey = useCentralizedKeys
303
316
  ? t.callExpression(t.memberExpression(t.identifier(keysName), t.identifier('detail')), [t.memberExpression(t.memberExpression(t.identifier('variables'), t.identifier('input')), t.identifier(pkField.name))])
@@ -417,9 +430,9 @@ function generateDeleteMutationHook(table, options = {}) {
417
430
  if (useCentralizedKeys) {
418
431
  mutationOptions.push(t.objectProperty(t.identifier('mutationKey'), t.memberExpression(t.identifier(mutationKeysName), t.identifier('all'))));
419
432
  }
420
- mutationOptions.push(t.objectProperty(t.identifier('mutationFn'), t.arrowFunctionExpression([(0, babel_ast_1.typedParam)('variables', t.tsTypeReference(t.identifier(`${(0, utils_1.ucFirst)(mutationName)}MutationVariables`)))], t.callExpression(t.identifier('execute'), [
421
- t.identifier(`${mutationName}MutationDocument`),
422
- t.identifier('variables'),
433
+ mutationOptions.push(t.objectProperty(t.identifier('mutationFn'), t.arrowFunctionExpression([(0, babel_ast_1.typedParam)('variables', t.tsTypeReference(t.identifier(`${(0, utils_1.ucFirst)(mutationName)}MutationVariables`)))], (0, babel_ast_1.createTypedCallExpression)(t.identifier('execute'), [t.identifier(`${mutationName}MutationDocument`), t.identifier('variables')], [
434
+ t.tsTypeReference(t.identifier(`${(0, utils_1.ucFirst)(mutationName)}MutationResult`)),
435
+ t.tsTypeReference(t.identifier(`${(0, utils_1.ucFirst)(mutationName)}MutationVariables`)),
423
436
  ]))));
424
437
  const detailQueryKey = useCentralizedKeys
425
438
  ? t.callExpression(t.memberExpression(t.identifier(keysName), t.identifier('detail')), [t.memberExpression(t.memberExpression(t.identifier('variables'), t.identifier('input')), t.identifier(pkField.name))])