@constructive-io/graphql-codegen 3.2.1 → 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 (215) hide show
  1. package/cli/index.js +36 -43
  2. package/cli/shared.d.ts +15 -19
  3. package/cli/shared.js +104 -25
  4. package/client/error.js +31 -9
  5. package/client/execute.js +2 -2
  6. package/client/index.d.ts +3 -3
  7. package/client/index.js +6 -6
  8. package/core/ast.d.ts +1 -1
  9. package/core/ast.js +1 -1
  10. package/core/codegen/babel-ast.d.ts +1 -1
  11. package/core/codegen/babel-ast.js +2 -2
  12. package/core/codegen/barrel.d.ts +0 -6
  13. package/core/codegen/barrel.js +22 -19
  14. package/core/codegen/client.d.ts +2 -12
  15. package/core/codegen/client.js +7 -21
  16. package/core/codegen/custom-mutations.d.ts +0 -14
  17. package/core/codegen/custom-mutations.js +139 -88
  18. package/core/codegen/custom-queries.d.ts +0 -14
  19. package/core/codegen/custom-queries.js +483 -193
  20. package/core/codegen/hooks-ast.d.ts +75 -0
  21. package/core/codegen/hooks-ast.js +522 -0
  22. package/core/codegen/index.d.ts +16 -18
  23. package/core/codegen/index.js +42 -88
  24. package/core/codegen/invalidation.d.ts +1 -7
  25. package/core/codegen/invalidation.js +50 -16
  26. package/core/codegen/mutation-keys.d.ts +1 -10
  27. package/core/codegen/mutation-keys.js +22 -8
  28. package/core/codegen/mutations.d.ts +0 -13
  29. package/core/codegen/mutations.js +301 -366
  30. package/core/codegen/orm/barrel.d.ts +0 -5
  31. package/core/codegen/orm/barrel.js +5 -0
  32. package/core/codegen/orm/client-generator.d.ts +0 -5
  33. package/core/codegen/orm/client-generator.js +7 -2
  34. package/core/codegen/orm/client.js +3 -1
  35. package/core/codegen/orm/custom-ops-generator.d.ts +0 -6
  36. package/core/codegen/orm/custom-ops-generator.js +104 -51
  37. package/core/codegen/orm/index.d.ts +4 -4
  38. package/core/codegen/orm/index.js +28 -15
  39. package/core/codegen/orm/input-types-generator.d.ts +1 -13
  40. package/core/codegen/orm/input-types-generator.js +85 -23
  41. package/core/codegen/orm/model-generator.d.ts +0 -5
  42. package/core/codegen/orm/model-generator.js +309 -131
  43. package/core/codegen/orm/select-types.d.ts +19 -14
  44. package/core/codegen/queries.d.ts +0 -8
  45. package/core/codegen/queries.js +360 -559
  46. package/core/codegen/query-keys.d.ts +1 -1
  47. package/core/codegen/query-keys.js +37 -23
  48. package/core/codegen/scalars.js +3 -1
  49. package/core/codegen/schema-types-generator.d.ts +1 -1
  50. package/core/codegen/schema-types-generator.js +17 -2
  51. package/core/codegen/select-helpers.d.ts +19 -0
  52. package/core/codegen/select-helpers.js +40 -0
  53. package/core/codegen/selection.d.ts +4 -0
  54. package/core/codegen/selection.js +65 -0
  55. package/core/codegen/shared/index.d.ts +2 -15
  56. package/core/codegen/shared/index.js +17 -4
  57. package/core/codegen/templates/hooks-client.ts +49 -0
  58. package/core/codegen/templates/hooks-selection.ts +58 -0
  59. package/core/codegen/templates/orm-client.ts +8 -6
  60. package/core/codegen/templates/query-builder.ts +250 -46
  61. package/core/codegen/templates/select-types.ts +31 -14
  62. package/core/codegen/type-resolver.d.ts +1 -5
  63. package/core/codegen/type-resolver.js +0 -22
  64. package/core/codegen/types.d.ts +0 -3
  65. package/core/codegen/types.js +71 -14
  66. package/core/codegen/utils.d.ts +1 -4
  67. package/core/codegen/utils.js +4 -1
  68. package/core/config/index.d.ts +1 -1
  69. package/core/config/resolver.js +1 -3
  70. package/core/generate.js +38 -50
  71. package/core/index.d.ts +3 -3
  72. package/core/index.js +3 -4
  73. package/core/introspect/index.d.ts +6 -6
  74. package/core/introspect/index.js +5 -8
  75. package/core/introspect/infer-tables.d.ts +0 -14
  76. package/core/introspect/infer-tables.js +15 -1
  77. package/core/introspect/source/database.js +1 -1
  78. package/core/introspect/source/endpoint.d.ts +0 -6
  79. package/core/introspect/source/endpoint.js +7 -1
  80. package/core/introspect/source/index.d.ts +4 -4
  81. package/core/introspect/source/index.js +5 -9
  82. package/core/introspect/source/pgpm-module.js +3 -3
  83. package/core/introspect/transform-schema.d.ts +2 -2
  84. package/core/introspect/transform-schema.js +2 -2
  85. package/core/output/index.d.ts +1 -1
  86. package/core/output/index.js +2 -2
  87. package/core/output/writer.d.ts +3 -0
  88. package/core/output/writer.js +20 -1
  89. package/core/pipeline/index.d.ts +2 -2
  90. package/core/query-builder.d.ts +2 -2
  91. package/core/query-builder.js +1 -1
  92. package/core/watch/index.d.ts +4 -4
  93. package/core/watch/index.js +9 -9
  94. package/core/watch/orchestrator.js +5 -3
  95. package/esm/cli/index.js +37 -44
  96. package/esm/cli/shared.d.ts +15 -19
  97. package/esm/cli/shared.js +94 -23
  98. package/esm/client/error.js +31 -9
  99. package/esm/client/execute.js +2 -2
  100. package/esm/client/index.d.ts +3 -3
  101. package/esm/client/index.js +3 -3
  102. package/esm/core/ast.d.ts +1 -1
  103. package/esm/core/ast.js +1 -1
  104. package/esm/core/codegen/babel-ast.d.ts +1 -1
  105. package/esm/core/codegen/babel-ast.js +2 -2
  106. package/esm/core/codegen/barrel.d.ts +0 -6
  107. package/esm/core/codegen/barrel.js +23 -20
  108. package/esm/core/codegen/client.d.ts +2 -12
  109. package/esm/core/codegen/client.js +7 -21
  110. package/esm/core/codegen/custom-mutations.d.ts +0 -14
  111. package/esm/core/codegen/custom-mutations.js +141 -90
  112. package/esm/core/codegen/custom-queries.d.ts +0 -14
  113. package/esm/core/codegen/custom-queries.js +486 -196
  114. package/esm/core/codegen/hooks-ast.d.ts +75 -0
  115. package/esm/core/codegen/hooks-ast.js +424 -0
  116. package/esm/core/codegen/index.d.ts +16 -18
  117. package/esm/core/codegen/index.js +26 -71
  118. package/esm/core/codegen/invalidation.d.ts +1 -7
  119. package/esm/core/codegen/invalidation.js +51 -17
  120. package/esm/core/codegen/mutation-keys.d.ts +1 -10
  121. package/esm/core/codegen/mutation-keys.js +23 -9
  122. package/esm/core/codegen/mutations.d.ts +0 -13
  123. package/esm/core/codegen/mutations.js +302 -367
  124. package/esm/core/codegen/orm/barrel.d.ts +0 -5
  125. package/esm/core/codegen/orm/barrel.js +6 -1
  126. package/esm/core/codegen/orm/client-generator.d.ts +0 -5
  127. package/esm/core/codegen/orm/client-generator.js +7 -2
  128. package/esm/core/codegen/orm/client.js +3 -1
  129. package/esm/core/codegen/orm/custom-ops-generator.d.ts +0 -6
  130. package/esm/core/codegen/orm/custom-ops-generator.js +103 -50
  131. package/esm/core/codegen/orm/index.d.ts +4 -4
  132. package/esm/core/codegen/orm/index.js +25 -12
  133. package/esm/core/codegen/orm/input-types-generator.d.ts +1 -13
  134. package/esm/core/codegen/orm/input-types-generator.js +85 -23
  135. package/esm/core/codegen/orm/model-generator.d.ts +0 -5
  136. package/esm/core/codegen/orm/model-generator.js +310 -132
  137. package/esm/core/codegen/orm/select-types.d.ts +19 -14
  138. package/esm/core/codegen/queries.d.ts +0 -8
  139. package/esm/core/codegen/queries.js +362 -561
  140. package/esm/core/codegen/query-keys.d.ts +1 -1
  141. package/esm/core/codegen/query-keys.js +38 -24
  142. package/esm/core/codegen/scalars.js +3 -1
  143. package/esm/core/codegen/schema-types-generator.d.ts +1 -1
  144. package/esm/core/codegen/schema-types-generator.js +17 -2
  145. package/esm/core/codegen/select-helpers.d.ts +19 -0
  146. package/esm/core/codegen/select-helpers.js +35 -0
  147. package/esm/core/codegen/selection.d.ts +4 -0
  148. package/esm/core/codegen/selection.js +29 -0
  149. package/esm/core/codegen/shared/index.d.ts +2 -15
  150. package/esm/core/codegen/shared/index.js +16 -3
  151. package/esm/core/codegen/type-resolver.d.ts +1 -5
  152. package/esm/core/codegen/type-resolver.js +1 -22
  153. package/esm/core/codegen/types.d.ts +0 -3
  154. package/esm/core/codegen/types.js +72 -15
  155. package/esm/core/codegen/utils.d.ts +1 -4
  156. package/esm/core/codegen/utils.js +4 -1
  157. package/esm/core/config/index.d.ts +1 -1
  158. package/esm/core/config/resolver.js +2 -4
  159. package/esm/core/generate.js +38 -50
  160. package/esm/core/index.d.ts +3 -3
  161. package/esm/core/index.js +2 -3
  162. package/esm/core/introspect/index.d.ts +6 -6
  163. package/esm/core/introspect/index.js +3 -6
  164. package/esm/core/introspect/infer-tables.d.ts +0 -14
  165. package/esm/core/introspect/infer-tables.js +16 -2
  166. package/esm/core/introspect/source/database.js +2 -2
  167. package/esm/core/introspect/source/endpoint.d.ts +0 -6
  168. package/esm/core/introspect/source/endpoint.js +7 -1
  169. package/esm/core/introspect/source/index.d.ts +4 -4
  170. package/esm/core/introspect/source/index.js +6 -10
  171. package/esm/core/introspect/source/pgpm-module.js +3 -3
  172. package/esm/core/introspect/transform-schema.d.ts +2 -2
  173. package/esm/core/introspect/transform-schema.js +2 -2
  174. package/esm/core/output/index.d.ts +1 -1
  175. package/esm/core/output/index.js +1 -1
  176. package/esm/core/output/writer.d.ts +3 -0
  177. package/esm/core/output/writer.js +20 -1
  178. package/esm/core/pipeline/index.d.ts +2 -2
  179. package/esm/core/pipeline/index.js +2 -2
  180. package/esm/core/query-builder.d.ts +2 -2
  181. package/esm/core/query-builder.js +2 -2
  182. package/esm/core/watch/index.d.ts +4 -4
  183. package/esm/core/watch/index.js +3 -3
  184. package/esm/core/watch/orchestrator.js +5 -3
  185. package/esm/generators/index.d.ts +3 -3
  186. package/esm/generators/index.js +3 -3
  187. package/esm/generators/mutations.d.ts +1 -1
  188. package/esm/generators/select.d.ts +1 -1
  189. package/esm/index.d.ts +3 -3
  190. package/esm/index.js +1 -4
  191. package/esm/types/config.d.ts +0 -10
  192. package/esm/types/config.js +0 -2
  193. package/esm/types/index.d.ts +6 -6
  194. package/esm/types/index.js +1 -1
  195. package/generators/index.d.ts +3 -3
  196. package/generators/index.js +8 -8
  197. package/generators/mutations.d.ts +1 -1
  198. package/generators/select.d.ts +1 -1
  199. package/index.d.ts +3 -3
  200. package/index.js +11 -6
  201. package/package.json +10 -10
  202. package/types/config.d.ts +0 -10
  203. package/types/config.js +0 -2
  204. package/types/index.d.ts +6 -6
  205. package/types/index.js +2 -2
  206. package/core/codegen/gql-ast.d.ts +0 -41
  207. package/core/codegen/gql-ast.js +0 -353
  208. package/core/codegen/schema-gql-ast.d.ts +0 -51
  209. package/core/codegen/schema-gql-ast.js +0 -385
  210. package/core/codegen/templates/client.browser.ts +0 -271
  211. package/core/codegen/templates/client.node.ts +0 -337
  212. package/esm/core/codegen/gql-ast.d.ts +0 -41
  213. package/esm/core/codegen/gql-ast.js +0 -312
  214. package/esm/core/codegen/schema-gql-ast.d.ts +0 -51
  215. package/esm/core/codegen/schema-gql-ast.js +0 -343
@@ -35,45 +35,31 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.generateClientFile = generateClientFile;
37
37
  /**
38
- * Client generator - generates client.ts with configure() and execute()
38
+ * Client generator - generates client.ts as ORM client wrapper
39
39
  *
40
- * Reads from template files in the templates/ directory for proper type checking.
40
+ * Uses template-copy pattern: reads hooks-client.ts from templates/
41
+ * and writes it to the output directory with a generated file header.
41
42
  */
42
43
  const fs = __importStar(require("fs"));
43
44
  const path = __importStar(require("path"));
44
45
  const utils_1 = require("./utils");
45
- /**
46
- * Find a template file path.
47
- * Templates are at ./templates/ relative to this file in both src/ and dist/.
48
- */
49
46
  function findTemplateFile(templateName) {
50
47
  const templatePath = path.join(__dirname, 'templates', templateName);
51
48
  if (fs.existsSync(templatePath)) {
52
49
  return templatePath;
53
50
  }
54
- throw new Error(`Could not find template file: ${templateName}. ` +
55
- `Searched in: ${templatePath}`);
51
+ throw new Error(`Could not find template file: ${templateName}. Searched in: ${templatePath}`);
56
52
  }
57
- /**
58
- * Read a template file and replace the header with generated file header
59
- */
60
53
  function readTemplateFile(templateName, description) {
61
54
  const templatePath = findTemplateFile(templateName);
62
55
  let content = fs.readFileSync(templatePath, 'utf-8');
63
- // Replace the source file header comment with the generated file header
64
- // Match the header pattern used in template files
65
56
  const headerPattern = /\/\*\*[\s\S]*?\* NOTE: This file is read at codegen time and written to output\.[\s\S]*?\*\/\n*/;
66
57
  content = content.replace(headerPattern, (0, utils_1.getGeneratedFileHeader)(description) + '\n');
67
58
  return content;
68
59
  }
69
60
  /**
70
- * Generate client.ts content
71
- * @param options - Generation options
61
+ * Generate client.ts content - ORM client wrapper with configure/getClient
72
62
  */
73
- function generateClientFile(options = {}) {
74
- const { browserCompatible = true } = options;
75
- const templateName = browserCompatible
76
- ? 'client.browser.ts'
77
- : 'client.node.ts';
78
- return readTemplateFile(templateName, 'GraphQL client configuration and execution');
63
+ function generateClientFile() {
64
+ return readTemplateFile('hooks-client.ts', 'ORM client wrapper for React Query hooks');
79
65
  }
@@ -1,15 +1,3 @@
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
1
  import type { CleanOperation, TypeRegistry } from '../../types/schema';
14
2
  export interface GeneratedCustomMutationFile {
15
3
  fileName: string;
@@ -19,7 +7,6 @@ export interface GeneratedCustomMutationFile {
19
7
  export interface GenerateCustomMutationHookOptions {
20
8
  operation: CleanOperation;
21
9
  typeRegistry: TypeRegistry;
22
- maxDepth?: number;
23
10
  skipQueryField?: boolean;
24
11
  reactQueryEnabled?: boolean;
25
12
  tableTypeNames?: Set<string>;
@@ -29,7 +16,6 @@ export declare function generateCustomMutationHook(options: GenerateCustomMutati
29
16
  export interface GenerateAllCustomMutationHooksOptions {
30
17
  operations: CleanOperation[];
31
18
  typeRegistry: TypeRegistry;
32
- maxDepth?: number;
33
19
  skipQueryField?: boolean;
34
20
  reactQueryEnabled?: boolean;
35
21
  tableTypeNames?: Set<string>;
@@ -35,19 +35,26 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.generateCustomMutationHook = generateCustomMutationHook;
37
37
  exports.generateAllCustomMutationHooks = generateAllCustomMutationHooks;
38
+ /**
39
+ * Custom mutation hook generators for non-table operations (Babel AST-based)
40
+ *
41
+ * Generates hooks for operations discovered via schema introspection
42
+ * that are NOT table CRUD operations (e.g., login, register, etc.)
43
+ *
44
+ * Delegates to ORM custom mutation operations:
45
+ * getClient().mutation.operationName(args, { select }).unwrap()
46
+ *
47
+ * Output structure:
48
+ * mutations/
49
+ * useLoginMutation.ts
50
+ * useRegisterMutation.ts
51
+ * ...
52
+ */
38
53
  const t = __importStar(require("@babel/types"));
39
- const babel_ast_1 = require("./babel-ast");
40
- const schema_gql_ast_1 = require("./schema-gql-ast");
54
+ const hooks_ast_1 = require("./hooks-ast");
55
+ const select_helpers_1 = require("./select-helpers");
41
56
  const type_resolver_1 = require("./type-resolver");
42
57
  const utils_1 = require("./utils");
43
- function generateVariablesProperties(args, tracker) {
44
- return args.map((arg) => ({
45
- name: arg.name,
46
- type: (0, type_resolver_1.typeRefToTsType)(arg.type, tracker),
47
- optional: !(0, type_resolver_1.isTypeRequired)(arg.type),
48
- docs: arg.description ? [arg.description] : undefined,
49
- }));
50
- }
51
58
  function generateCustomMutationHook(options) {
52
59
  const { operation, reactQueryEnabled = true } = options;
53
60
  if (!reactQueryEnabled) {
@@ -63,95 +70,140 @@ function generateCustomMutationHook(options) {
63
70
  }
64
71
  }
65
72
  function generateCustomMutationHookInternal(options) {
66
- const { operation, typeRegistry, maxDepth = 2, skipQueryField = true, tableTypeNames, useCentralizedKeys = true, } = options;
73
+ const { operation, typeRegistry, tableTypeNames, useCentralizedKeys = true, } = options;
67
74
  const hookName = (0, type_resolver_1.getOperationHookName)(operation.name, 'mutation');
68
75
  const fileName = (0, type_resolver_1.getOperationFileName)(operation.name, 'mutation');
69
- const variablesTypeName = (0, type_resolver_1.getOperationVariablesTypeName)(operation.name, 'mutation');
70
- const resultTypeName = (0, type_resolver_1.getOperationResultTypeName)(operation.name, 'mutation');
71
- const documentConstName = (0, type_resolver_1.getDocumentConstName)(operation.name, 'mutation');
76
+ const varTypeName = `${(0, utils_1.ucFirst)(operation.name)}Variables`;
72
77
  const tracker = (0, type_resolver_1.createTypeTracker)({ tableTypeNames });
73
- const mutationDocument = (0, schema_gql_ast_1.buildCustomMutationString)({
74
- operation,
75
- typeRegistry,
76
- maxDepth,
77
- skipQueryField,
78
- });
78
+ const hasArgs = operation.args.length > 0;
79
+ (0, type_resolver_1.typeRefToTsType)(operation.returnType, tracker);
80
+ for (const arg of operation.args) {
81
+ (0, type_resolver_1.typeRefToTsType)(arg.type, tracker);
82
+ }
83
+ const selectTypeName = (0, select_helpers_1.getSelectTypeName)(operation.returnType);
84
+ const payloadTypeName = (0, type_resolver_1.getTypeBaseName)(operation.returnType);
85
+ const hasSelect = !!selectTypeName && !!payloadTypeName;
79
86
  const statements = [];
80
- const variablesProps = operation.args.length > 0
81
- ? generateVariablesProperties(operation.args, tracker)
82
- : [];
83
- const resultType = (0, type_resolver_1.typeRefToTsType)(operation.returnType, tracker);
84
- const schemaTypes = tracker.getImportableTypes();
85
- const tableTypes = tracker.getTableTypes();
86
- const reactQueryImport = t.importDeclaration([t.importSpecifier(t.identifier('useMutation'), t.identifier('useMutation'))], t.stringLiteral('@tanstack/react-query'));
87
- statements.push(reactQueryImport);
88
- const reactQueryTypeImport = t.importDeclaration([t.importSpecifier(t.identifier('UseMutationOptions'), t.identifier('UseMutationOptions'))], t.stringLiteral('@tanstack/react-query'));
89
- reactQueryTypeImport.importKind = 'type';
90
- statements.push(reactQueryTypeImport);
91
- const clientImport = t.importDeclaration([t.importSpecifier(t.identifier('execute'), t.identifier('execute'))], t.stringLiteral('../client'));
92
- statements.push(clientImport);
93
- if (tableTypes.length > 0) {
94
- const typesImport = t.importDeclaration(tableTypes.map((tt) => t.importSpecifier(t.identifier(tt), t.identifier(tt))), t.stringLiteral('../types'));
95
- typesImport.importKind = 'type';
96
- statements.push(typesImport);
87
+ // Imports
88
+ statements.push((0, hooks_ast_1.createImportDeclaration)('@tanstack/react-query', ['useMutation']));
89
+ statements.push((0, hooks_ast_1.createImportDeclaration)('@tanstack/react-query', ['UseMutationOptions', 'UseMutationResult'], true));
90
+ statements.push((0, hooks_ast_1.createImportDeclaration)('../client', ['getClient']));
91
+ statements.push((0, hooks_ast_1.createImportDeclaration)('../selection', ['buildSelectionArgs']));
92
+ statements.push((0, hooks_ast_1.createImportDeclaration)('../selection', ['SelectionConfig'], true));
93
+ if (useCentralizedKeys) {
94
+ statements.push((0, hooks_ast_1.createImportDeclaration)('../mutation-keys', ['customMutationKeys']));
97
95
  }
98
- if (schemaTypes.length > 0) {
99
- const schemaTypesImport = t.importDeclaration(schemaTypes.map((st) => t.importSpecifier(t.identifier(st), t.identifier(st))), t.stringLiteral('../schema-types'));
100
- schemaTypesImport.importKind = 'type';
101
- statements.push(schemaTypesImport);
96
+ if (hasArgs) {
97
+ statements.push((0, hooks_ast_1.createImportDeclaration)('../../orm/mutation', [varTypeName], true));
102
98
  }
103
- if (useCentralizedKeys) {
104
- const mutationKeyImport = t.importDeclaration([t.importSpecifier(t.identifier('customMutationKeys'), t.identifier('customMutationKeys'))], t.stringLiteral('../mutation-keys'));
105
- statements.push(mutationKeyImport);
99
+ const inputTypeImports = [];
100
+ if (hasSelect) {
101
+ inputTypeImports.push(selectTypeName);
102
+ inputTypeImports.push(payloadTypeName);
106
103
  }
107
- const mutationDocConst = t.variableDeclaration('const', [
108
- t.variableDeclarator(t.identifier(documentConstName), t.templateLiteral([t.templateElement({ raw: '\n' + mutationDocument, cooked: '\n' + mutationDocument }, true)], [])),
109
- ]);
110
- const mutationDocExport = t.exportNamedDeclaration(mutationDocConst);
111
- (0, babel_ast_1.addJSDocComment)(mutationDocExport, ['GraphQL mutation document']);
112
- statements.push(mutationDocExport);
113
- if (operation.args.length > 0) {
114
- const variablesInterfaceProps = variablesProps.map((vp) => {
115
- const prop = t.tsPropertySignature(t.identifier(vp.name), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(vp.type))));
116
- prop.optional = vp.optional;
117
- return prop;
118
- });
119
- const variablesInterface = t.tsInterfaceDeclaration(t.identifier(variablesTypeName), null, null, t.tsInterfaceBody(variablesInterfaceProps));
120
- statements.push(t.exportNamedDeclaration(variablesInterface));
104
+ else {
105
+ for (const refType of tracker.referencedTypes) {
106
+ if (!inputTypeImports.includes(refType)) {
107
+ inputTypeImports.push(refType);
108
+ }
109
+ }
121
110
  }
122
- const resultInterfaceBody = t.tsInterfaceBody([
123
- t.tsPropertySignature(t.identifier(operation.name), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(resultType)))),
124
- ]);
125
- const resultInterface = t.tsInterfaceDeclaration(t.identifier(resultTypeName), null, null, resultInterfaceBody);
126
- statements.push(t.exportNamedDeclaration(resultInterface));
127
- const hasArgs = operation.args.length > 0;
128
- const hookBodyStatements = [];
129
- const mutationOptions = [];
130
- if (useCentralizedKeys) {
131
- mutationOptions.push(t.objectProperty(t.identifier('mutationKey'), t.callExpression(t.memberExpression(t.identifier('customMutationKeys'), t.identifier(operation.name)), [])));
111
+ if (inputTypeImports.length > 0) {
112
+ statements.push((0, hooks_ast_1.createImportDeclaration)('../../orm/input-types', inputTypeImports, true));
132
113
  }
114
+ if (hasSelect) {
115
+ statements.push((0, hooks_ast_1.createImportDeclaration)('../../orm/select-types', ['InferSelectResult', 'StrictSelect'], true));
116
+ }
117
+ // Re-exports
133
118
  if (hasArgs) {
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
- ]))));
119
+ statements.push((0, hooks_ast_1.createTypeReExport)([varTypeName], '../../orm/mutation'));
120
+ }
121
+ if (hasSelect) {
122
+ statements.push((0, hooks_ast_1.createTypeReExport)([selectTypeName], '../../orm/input-types'));
123
+ }
124
+ // Hook
125
+ if (hasSelect) {
126
+ const mutationVarType = hasArgs
127
+ ? (0, hooks_ast_1.typeRef)(varTypeName)
128
+ : t.tsVoidKeyword();
129
+ const selectedResultType = (sel) => (0, hooks_ast_1.customSelectResultTypeLiteral)(operation.name, operation.returnType, payloadTypeName, sel);
130
+ // Overload 1: with selection.fields
131
+ const o1ParamType = t.tsIntersectionType([
132
+ t.tsTypeLiteral([
133
+ t.tsPropertySignature(t.identifier('selection'), t.tsTypeAnnotation(t.tsParenthesizedType(t.tsIntersectionType([
134
+ t.tsTypeLiteral([
135
+ t.tsPropertySignature(t.identifier('fields'), t.tsTypeAnnotation((0, hooks_ast_1.sRef)())),
136
+ ]),
137
+ (0, hooks_ast_1.typeRef)('StrictSelect', [(0, hooks_ast_1.sRef)(), (0, hooks_ast_1.typeRef)(selectTypeName)]),
138
+ ])))),
139
+ ]),
140
+ (0, hooks_ast_1.useMutationOptionsType)(selectedResultType((0, hooks_ast_1.sRef)()), mutationVarType),
141
+ ]);
142
+ statements.push((0, hooks_ast_1.exportDeclareFunction)(hookName, (0, hooks_ast_1.createSTypeParam)(selectTypeName), [(0, hooks_ast_1.createFunctionParam)('params', o1ParamType)], (0, hooks_ast_1.useMutationResultType)(selectedResultType((0, hooks_ast_1.sRef)()), mutationVarType)));
143
+ // Implementation
144
+ const implSelProp = t.tsPropertySignature(t.identifier('selection'), t.tsTypeAnnotation((0, hooks_ast_1.selectionConfigType)((0, hooks_ast_1.typeRef)(selectTypeName))));
145
+ const implParamType = t.tsIntersectionType([
146
+ t.tsTypeLiteral([implSelProp]),
147
+ (0, hooks_ast_1.omitType)((0, hooks_ast_1.typeRef)('UseMutationOptions', [
148
+ t.tsAnyKeyword(),
149
+ (0, hooks_ast_1.typeRef)('Error'),
150
+ mutationVarType,
151
+ ]), ['mutationFn']),
152
+ ]);
153
+ const body = [];
154
+ body.push((0, hooks_ast_1.buildSelectionArgsCall)(selectTypeName));
155
+ body.push((0, hooks_ast_1.destructureParamsWithSelection)('mutationOptions'));
156
+ body.push((0, hooks_ast_1.voidStatement)('_selection'));
157
+ const mutationKeyExpr = useCentralizedKeys
158
+ ? (0, hooks_ast_1.callExpr)(t.memberExpression(t.identifier('customMutationKeys'), t.identifier(operation.name)), [])
159
+ : undefined;
160
+ const selectArgExpr = t.objectExpression([
161
+ (0, hooks_ast_1.objectProp)('select', t.memberExpression(t.identifier('args'), t.identifier('select'))),
162
+ ]);
163
+ let mutationFnExpr;
164
+ if (hasArgs) {
165
+ const variablesParam = (0, hooks_ast_1.createFunctionParam)('variables', (0, hooks_ast_1.typeRef)(varTypeName));
166
+ mutationFnExpr = t.arrowFunctionExpression([variablesParam], (0, hooks_ast_1.getClientCustomCallUnwrap)('mutation', operation.name, [t.identifier('variables')], selectArgExpr));
167
+ }
168
+ else {
169
+ mutationFnExpr = t.arrowFunctionExpression([], (0, hooks_ast_1.getClientCustomCallUnwrap)('mutation', operation.name, [], selectArgExpr));
170
+ }
171
+ body.push((0, hooks_ast_1.returnUseMutation)(mutationFnExpr, [(0, hooks_ast_1.spreadObj)(t.identifier('mutationOptions'))], mutationKeyExpr));
172
+ statements.push((0, hooks_ast_1.exportFunction)(hookName, null, [(0, hooks_ast_1.createFunctionParam)('params', implParamType)], body));
138
173
  }
139
174
  else {
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))]))));
175
+ // Without select: simple hook (scalar return type)
176
+ const resultTypeStr = (0, type_resolver_1.typeRefToTsType)(operation.returnType, tracker);
177
+ const resultTypeLiteral = t.tsTypeLiteral([
178
+ t.tsPropertySignature(t.identifier(operation.name), t.tsTypeAnnotation((0, hooks_ast_1.typeRef)(resultTypeStr))),
179
+ ]);
180
+ const mutationVarType = hasArgs
181
+ ? (0, hooks_ast_1.typeRef)(varTypeName)
182
+ : t.tsVoidKeyword();
183
+ const optionsType = (0, hooks_ast_1.omitType)((0, hooks_ast_1.typeRef)('UseMutationOptions', [
184
+ resultTypeLiteral,
185
+ (0, hooks_ast_1.typeRef)('Error'),
186
+ mutationVarType,
187
+ ]), ['mutationFn']);
188
+ const body = [];
189
+ body.push((0, hooks_ast_1.constDecl)('mutationOptions', t.logicalExpression('??', t.identifier('params'), t.objectExpression([]))));
190
+ const mutationKeyExpr = useCentralizedKeys
191
+ ? (0, hooks_ast_1.callExpr)(t.memberExpression(t.identifier('customMutationKeys'), t.identifier(operation.name)), [])
192
+ : undefined;
193
+ let mutationFnExpr;
194
+ if (hasArgs) {
195
+ const variablesParam = (0, hooks_ast_1.createFunctionParam)('variables', (0, hooks_ast_1.typeRef)(varTypeName));
196
+ mutationFnExpr = t.arrowFunctionExpression([variablesParam], (0, hooks_ast_1.getClientCustomCallUnwrap)('mutation', operation.name, [
197
+ t.identifier('variables'),
198
+ ]));
199
+ }
200
+ else {
201
+ mutationFnExpr = t.arrowFunctionExpression([], (0, hooks_ast_1.getClientCustomCallUnwrap)('mutation', operation.name, []));
202
+ }
203
+ body.push((0, hooks_ast_1.returnUseMutation)(mutationFnExpr, [(0, hooks_ast_1.spreadObj)(t.identifier('mutationOptions'))], mutationKeyExpr));
204
+ statements.push((0, hooks_ast_1.exportFunction)(hookName, null, [(0, hooks_ast_1.createFunctionParam)('params', optionsType, true)], body));
141
205
  }
142
- mutationOptions.push(t.spreadElement(t.identifier('options')));
143
- hookBodyStatements.push(t.returnStatement(t.callExpression(t.identifier('useMutation'), [t.objectExpression(mutationOptions)])));
144
- const optionsType = hasArgs
145
- ? `Omit<UseMutationOptions<${resultTypeName}, Error, ${variablesTypeName}>, 'mutationFn'>`
146
- : `Omit<UseMutationOptions<${resultTypeName}, Error, void>, 'mutationFn'>`;
147
- const optionsParam = t.identifier('options');
148
- optionsParam.optional = true;
149
- optionsParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier(optionsType)));
150
- const hookFunc = t.functionDeclaration(t.identifier(hookName), [optionsParam], t.blockStatement(hookBodyStatements));
151
- const hookExport = t.exportNamedDeclaration(hookFunc);
152
- statements.push(hookExport);
153
- const code = (0, babel_ast_1.generateCode)(statements);
154
- const content = (0, utils_1.getGeneratedFileHeader)(`Custom mutation hook for ${operation.name}`) + '\n\n' + code;
206
+ const content = (0, hooks_ast_1.generateHookFileCode)(`Custom mutation hook for ${operation.name}`, statements);
155
207
  return {
156
208
  fileName,
157
209
  content,
@@ -159,13 +211,12 @@ function generateCustomMutationHookInternal(options) {
159
211
  };
160
212
  }
161
213
  function generateAllCustomMutationHooks(options) {
162
- const { operations, typeRegistry, maxDepth = 2, skipQueryField = true, reactQueryEnabled = true, tableTypeNames, useCentralizedKeys = true, } = options;
214
+ const { operations, typeRegistry, skipQueryField = true, reactQueryEnabled = true, tableTypeNames, useCentralizedKeys = true, } = options;
163
215
  return operations
164
216
  .filter((op) => op.kind === 'mutation')
165
217
  .map((operation) => generateCustomMutationHook({
166
218
  operation,
167
219
  typeRegistry,
168
- maxDepth,
169
220
  skipQueryField,
170
221
  reactQueryEnabled,
171
222
  tableTypeNames,
@@ -1,15 +1,3 @@
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
1
  import type { CleanOperation, TypeRegistry } from '../../types/schema';
14
2
  export interface GeneratedCustomQueryFile {
15
3
  fileName: string;
@@ -19,7 +7,6 @@ export interface GeneratedCustomQueryFile {
19
7
  export interface GenerateCustomQueryHookOptions {
20
8
  operation: CleanOperation;
21
9
  typeRegistry: TypeRegistry;
22
- maxDepth?: number;
23
10
  skipQueryField?: boolean;
24
11
  reactQueryEnabled?: boolean;
25
12
  tableTypeNames?: Set<string>;
@@ -29,7 +16,6 @@ export declare function generateCustomQueryHook(options: GenerateCustomQueryHook
29
16
  export interface GenerateAllCustomQueryHooksOptions {
30
17
  operations: CleanOperation[];
31
18
  typeRegistry: TypeRegistry;
32
- maxDepth?: number;
33
19
  skipQueryField?: boolean;
34
20
  reactQueryEnabled?: boolean;
35
21
  tableTypeNames?: Set<string>;