@constructive-io/graphql-codegen 2.19.0 → 2.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. package/README.md +1818 -113
  2. package/__tests__/codegen/input-types-generator.test.d.ts +1 -0
  3. package/__tests__/codegen/input-types-generator.test.js +635 -0
  4. package/cli/codegen/barrel.d.ts +27 -0
  5. package/cli/codegen/barrel.js +163 -0
  6. package/cli/codegen/client.d.ts +4 -0
  7. package/cli/codegen/client.js +170 -0
  8. package/cli/codegen/custom-mutations.d.ts +38 -0
  9. package/cli/codegen/custom-mutations.js +149 -0
  10. package/cli/codegen/custom-queries.d.ts +38 -0
  11. package/cli/codegen/custom-queries.js +358 -0
  12. package/cli/codegen/filters.d.ts +27 -0
  13. package/cli/codegen/filters.js +357 -0
  14. package/cli/codegen/gql-ast.d.ts +41 -0
  15. package/cli/codegen/gql-ast.js +329 -0
  16. package/cli/codegen/index.d.ts +71 -0
  17. package/cli/codegen/index.js +147 -0
  18. package/cli/codegen/mutations.d.ts +30 -0
  19. package/cli/codegen/mutations.js +410 -0
  20. package/cli/codegen/orm/barrel.d.ts +18 -0
  21. package/cli/codegen/orm/barrel.js +48 -0
  22. package/cli/codegen/orm/client-generator.d.ts +45 -0
  23. package/cli/codegen/orm/client-generator.js +646 -0
  24. package/cli/codegen/orm/custom-ops-generator.d.ts +30 -0
  25. package/cli/codegen/orm/custom-ops-generator.js +350 -0
  26. package/cli/codegen/orm/index.d.ts +38 -0
  27. package/cli/codegen/orm/index.js +88 -0
  28. package/cli/codegen/orm/input-types-generator.d.ts +21 -0
  29. package/cli/codegen/orm/input-types-generator.js +705 -0
  30. package/cli/codegen/orm/input-types-generator.test.d.ts +1 -0
  31. package/cli/codegen/orm/input-types-generator.test.js +75 -0
  32. package/cli/codegen/orm/model-generator.d.ts +32 -0
  33. package/cli/codegen/orm/model-generator.js +264 -0
  34. package/cli/codegen/orm/query-builder.d.ts +161 -0
  35. package/cli/codegen/orm/query-builder.js +366 -0
  36. package/cli/codegen/orm/select-types.d.ts +169 -0
  37. package/cli/codegen/orm/select-types.js +16 -0
  38. package/cli/codegen/orm/select-types.test.d.ts +11 -0
  39. package/cli/codegen/orm/select-types.test.js +22 -0
  40. package/cli/codegen/queries.d.ts +25 -0
  41. package/cli/codegen/queries.js +438 -0
  42. package/cli/codegen/scalars.d.ts +12 -0
  43. package/cli/codegen/scalars.js +71 -0
  44. package/cli/codegen/schema-gql-ast.d.ts +51 -0
  45. package/cli/codegen/schema-gql-ast.js +385 -0
  46. package/cli/codegen/ts-ast.d.ts +122 -0
  47. package/cli/codegen/ts-ast.js +280 -0
  48. package/cli/codegen/type-resolver.d.ts +96 -0
  49. package/cli/codegen/type-resolver.js +246 -0
  50. package/cli/codegen/types.d.ts +12 -0
  51. package/cli/codegen/types.js +69 -0
  52. package/cli/codegen/utils.d.ts +163 -0
  53. package/cli/codegen/utils.js +326 -0
  54. package/cli/commands/generate-orm.d.ts +37 -0
  55. package/cli/commands/generate-orm.js +195 -0
  56. package/cli/commands/generate.d.ts +39 -0
  57. package/cli/commands/generate.js +299 -0
  58. package/cli/commands/index.d.ts +7 -0
  59. package/cli/commands/index.js +12 -0
  60. package/cli/commands/init.d.ts +35 -0
  61. package/cli/commands/init.js +176 -0
  62. package/cli/index.d.ts +4 -0
  63. package/cli/index.js +291 -0
  64. package/cli/introspect/fetch-meta.d.ts +31 -0
  65. package/cli/introspect/fetch-meta.js +108 -0
  66. package/cli/introspect/fetch-schema.d.ts +21 -0
  67. package/cli/introspect/fetch-schema.js +86 -0
  68. package/cli/introspect/index.d.ts +8 -0
  69. package/cli/introspect/index.js +16 -0
  70. package/cli/introspect/meta-query.d.ts +111 -0
  71. package/cli/introspect/meta-query.js +191 -0
  72. package/cli/introspect/schema-query.d.ts +20 -0
  73. package/cli/introspect/schema-query.js +123 -0
  74. package/cli/introspect/transform-schema.d.ts +74 -0
  75. package/cli/introspect/transform-schema.js +269 -0
  76. package/cli/introspect/transform-schema.test.d.ts +1 -0
  77. package/cli/introspect/transform-schema.test.js +67 -0
  78. package/cli/introspect/transform.d.ts +21 -0
  79. package/cli/introspect/transform.js +216 -0
  80. package/cli/watch/cache.d.ts +45 -0
  81. package/cli/watch/cache.js +111 -0
  82. package/cli/watch/debounce.d.ts +19 -0
  83. package/cli/watch/debounce.js +89 -0
  84. package/cli/watch/hash.d.ts +17 -0
  85. package/cli/watch/hash.js +48 -0
  86. package/cli/watch/index.d.ts +10 -0
  87. package/cli/watch/index.js +22 -0
  88. package/cli/watch/orchestrator.d.ts +63 -0
  89. package/cli/watch/orchestrator.js +228 -0
  90. package/cli/watch/poller.d.ts +65 -0
  91. package/cli/watch/poller.js +203 -0
  92. package/cli/watch/types.d.ts +67 -0
  93. package/cli/watch/types.js +5 -0
  94. package/client/error.d.ts +95 -0
  95. package/client/error.js +255 -0
  96. package/client/execute.d.ts +57 -0
  97. package/client/execute.js +124 -0
  98. package/client/index.d.ts +6 -0
  99. package/client/index.js +18 -0
  100. package/client/typed-document.d.ts +31 -0
  101. package/client/typed-document.js +44 -0
  102. package/core/ast.d.ts +10 -0
  103. package/core/ast.js +593 -0
  104. package/core/custom-ast.d.ts +35 -0
  105. package/core/custom-ast.js +204 -0
  106. package/core/index.d.ts +8 -0
  107. package/core/index.js +33 -0
  108. package/core/meta-object/convert.d.ts +65 -0
  109. package/core/meta-object/convert.js +63 -0
  110. package/core/meta-object/format.json +93 -0
  111. package/core/meta-object/index.d.ts +2 -0
  112. package/core/meta-object/index.js +18 -0
  113. package/core/meta-object/validate.d.ts +9 -0
  114. package/core/meta-object/validate.js +34 -0
  115. package/core/query-builder.d.ts +46 -0
  116. package/core/query-builder.js +412 -0
  117. package/core/types.d.ts +139 -0
  118. package/core/types.js +28 -0
  119. package/esm/__tests__/codegen/input-types-generator.test.d.ts +1 -0
  120. package/esm/__tests__/codegen/input-types-generator.test.js +633 -0
  121. package/esm/cli/codegen/barrel.d.ts +27 -0
  122. package/esm/cli/codegen/barrel.js +156 -0
  123. package/esm/cli/codegen/client.d.ts +4 -0
  124. package/esm/cli/codegen/client.js +167 -0
  125. package/esm/cli/codegen/custom-mutations.d.ts +38 -0
  126. package/esm/cli/codegen/custom-mutations.js +145 -0
  127. package/esm/cli/codegen/custom-queries.d.ts +38 -0
  128. package/esm/cli/codegen/custom-queries.js +354 -0
  129. package/esm/cli/codegen/filters.d.ts +27 -0
  130. package/esm/cli/codegen/filters.js +351 -0
  131. package/esm/cli/codegen/gql-ast.d.ts +41 -0
  132. package/esm/cli/codegen/gql-ast.js +288 -0
  133. package/esm/cli/codegen/index.d.ts +71 -0
  134. package/esm/cli/codegen/index.js +124 -0
  135. package/esm/cli/codegen/mutations.d.ts +30 -0
  136. package/esm/cli/codegen/mutations.js +404 -0
  137. package/esm/cli/codegen/orm/barrel.d.ts +18 -0
  138. package/esm/cli/codegen/orm/barrel.js +44 -0
  139. package/esm/cli/codegen/orm/client-generator.d.ts +45 -0
  140. package/esm/cli/codegen/orm/client-generator.js +640 -0
  141. package/esm/cli/codegen/orm/custom-ops-generator.d.ts +30 -0
  142. package/esm/cli/codegen/orm/custom-ops-generator.js +346 -0
  143. package/esm/cli/codegen/orm/index.d.ts +38 -0
  144. package/esm/cli/codegen/orm/index.js +75 -0
  145. package/esm/cli/codegen/orm/input-types-generator.d.ts +21 -0
  146. package/esm/cli/codegen/orm/input-types-generator.js +700 -0
  147. package/esm/cli/codegen/orm/input-types-generator.test.d.ts +1 -0
  148. package/esm/cli/codegen/orm/input-types-generator.test.js +73 -0
  149. package/esm/cli/codegen/orm/model-generator.d.ts +32 -0
  150. package/esm/cli/codegen/orm/model-generator.js +260 -0
  151. package/esm/cli/codegen/orm/query-builder.d.ts +161 -0
  152. package/esm/cli/codegen/orm/query-builder.js +353 -0
  153. package/esm/cli/codegen/orm/select-types.d.ts +169 -0
  154. package/esm/cli/codegen/orm/select-types.js +15 -0
  155. package/esm/cli/codegen/orm/select-types.test.d.ts +11 -0
  156. package/esm/cli/codegen/orm/select-types.test.js +21 -0
  157. package/esm/cli/codegen/queries.d.ts +25 -0
  158. package/esm/cli/codegen/queries.js +433 -0
  159. package/esm/cli/codegen/scalars.d.ts +12 -0
  160. package/esm/cli/codegen/scalars.js +66 -0
  161. package/esm/cli/codegen/schema-gql-ast.d.ts +51 -0
  162. package/esm/cli/codegen/schema-gql-ast.js +343 -0
  163. package/esm/cli/codegen/ts-ast.d.ts +122 -0
  164. package/esm/cli/codegen/ts-ast.js +260 -0
  165. package/esm/cli/codegen/type-resolver.d.ts +96 -0
  166. package/esm/cli/codegen/type-resolver.js +224 -0
  167. package/esm/cli/codegen/types.d.ts +12 -0
  168. package/esm/cli/codegen/types.js +65 -0
  169. package/esm/cli/codegen/utils.d.ts +163 -0
  170. package/esm/cli/codegen/utils.js +288 -0
  171. package/esm/cli/commands/generate-orm.d.ts +37 -0
  172. package/esm/cli/commands/generate-orm.js +192 -0
  173. package/esm/cli/commands/generate.d.ts +39 -0
  174. package/esm/cli/commands/generate.js +262 -0
  175. package/esm/cli/commands/index.d.ts +7 -0
  176. package/esm/cli/commands/index.js +5 -0
  177. package/esm/cli/commands/init.d.ts +35 -0
  178. package/esm/cli/commands/init.js +138 -0
  179. package/esm/cli/index.d.ts +4 -0
  180. package/esm/cli/index.js +256 -0
  181. package/esm/cli/introspect/fetch-meta.d.ts +31 -0
  182. package/esm/cli/introspect/fetch-meta.js +104 -0
  183. package/esm/cli/introspect/fetch-schema.d.ts +21 -0
  184. package/esm/cli/introspect/fetch-schema.js +83 -0
  185. package/esm/cli/introspect/index.d.ts +8 -0
  186. package/esm/cli/introspect/index.js +6 -0
  187. package/esm/cli/introspect/meta-query.d.ts +111 -0
  188. package/esm/cli/introspect/meta-query.js +188 -0
  189. package/esm/cli/introspect/schema-query.d.ts +20 -0
  190. package/esm/cli/introspect/schema-query.js +120 -0
  191. package/esm/cli/introspect/transform-schema.d.ts +74 -0
  192. package/esm/cli/introspect/transform-schema.js +259 -0
  193. package/esm/cli/introspect/transform-schema.test.d.ts +1 -0
  194. package/esm/cli/introspect/transform-schema.test.js +65 -0
  195. package/esm/cli/introspect/transform.d.ts +21 -0
  196. package/esm/cli/introspect/transform.js +210 -0
  197. package/esm/cli/watch/cache.d.ts +45 -0
  198. package/esm/cli/watch/cache.js +73 -0
  199. package/esm/cli/watch/debounce.d.ts +19 -0
  200. package/esm/cli/watch/debounce.js +85 -0
  201. package/esm/cli/watch/hash.d.ts +17 -0
  202. package/esm/cli/watch/hash.js +43 -0
  203. package/esm/cli/watch/index.d.ts +10 -0
  204. package/esm/cli/watch/index.js +8 -0
  205. package/esm/cli/watch/orchestrator.d.ts +63 -0
  206. package/esm/cli/watch/orchestrator.js +223 -0
  207. package/esm/cli/watch/poller.d.ts +65 -0
  208. package/esm/cli/watch/poller.js +198 -0
  209. package/esm/cli/watch/types.d.ts +67 -0
  210. package/esm/cli/watch/types.js +4 -0
  211. package/esm/client/error.d.ts +95 -0
  212. package/esm/client/error.js +249 -0
  213. package/esm/client/execute.d.ts +57 -0
  214. package/esm/client/execute.js +120 -0
  215. package/esm/client/index.d.ts +6 -0
  216. package/esm/client/index.js +6 -0
  217. package/esm/client/typed-document.d.ts +31 -0
  218. package/esm/client/typed-document.js +40 -0
  219. package/esm/core/ast.d.ts +10 -0
  220. package/esm/core/ast.js +549 -0
  221. package/esm/core/custom-ast.d.ts +35 -0
  222. package/esm/core/custom-ast.js +161 -0
  223. package/esm/core/index.d.ts +8 -0
  224. package/esm/core/index.js +12 -0
  225. package/esm/core/meta-object/convert.d.ts +65 -0
  226. package/esm/core/meta-object/convert.js +60 -0
  227. package/esm/core/meta-object/format.json +93 -0
  228. package/esm/core/meta-object/index.d.ts +2 -0
  229. package/esm/core/meta-object/index.js +2 -0
  230. package/esm/core/meta-object/validate.d.ts +9 -0
  231. package/esm/core/meta-object/validate.js +28 -0
  232. package/esm/core/query-builder.d.ts +46 -0
  233. package/esm/core/query-builder.js +375 -0
  234. package/esm/core/types.d.ts +139 -0
  235. package/esm/core/types.js +24 -0
  236. package/esm/generators/field-selector.d.ts +30 -0
  237. package/esm/generators/field-selector.js +355 -0
  238. package/esm/generators/index.d.ts +6 -0
  239. package/esm/generators/index.js +9 -0
  240. package/esm/generators/mutations.d.ts +31 -0
  241. package/esm/generators/mutations.js +197 -0
  242. package/esm/generators/select.d.ts +50 -0
  243. package/esm/generators/select.js +636 -0
  244. package/esm/index.d.ts +12 -0
  245. package/esm/index.js +17 -3
  246. package/esm/react/index.d.ts +5 -0
  247. package/esm/react/index.js +6 -0
  248. package/esm/types/config.d.ts +199 -0
  249. package/esm/types/config.js +106 -0
  250. package/esm/types/index.d.ts +9 -0
  251. package/esm/types/index.js +4 -0
  252. package/esm/types/introspection.d.ts +121 -0
  253. package/esm/types/introspection.js +54 -0
  254. package/esm/types/mutation.d.ts +45 -0
  255. package/esm/types/mutation.js +4 -0
  256. package/esm/types/query.d.ts +82 -0
  257. package/esm/types/query.js +4 -0
  258. package/esm/types/schema.d.ts +253 -0
  259. package/esm/types/schema.js +5 -0
  260. package/esm/types/selection.d.ts +43 -0
  261. package/esm/types/selection.js +4 -0
  262. package/esm/utils/index.d.ts +4 -0
  263. package/esm/utils/index.js +4 -0
  264. package/generators/field-selector.d.ts +30 -0
  265. package/generators/field-selector.js +361 -0
  266. package/generators/index.d.ts +6 -0
  267. package/generators/index.js +27 -0
  268. package/generators/mutations.d.ts +31 -0
  269. package/generators/mutations.js +235 -0
  270. package/generators/select.d.ts +50 -0
  271. package/generators/select.js +679 -0
  272. package/index.d.ts +12 -3
  273. package/index.js +19 -3
  274. package/package.json +59 -38
  275. package/react/index.d.ts +5 -0
  276. package/react/index.js +9 -0
  277. package/types/config.d.ts +199 -0
  278. package/types/config.js +111 -0
  279. package/types/index.d.ts +9 -0
  280. package/types/index.js +10 -0
  281. package/types/introspection.d.ts +121 -0
  282. package/types/introspection.js +62 -0
  283. package/types/mutation.d.ts +45 -0
  284. package/types/mutation.js +5 -0
  285. package/types/query.d.ts +82 -0
  286. package/types/query.js +5 -0
  287. package/types/schema.d.ts +253 -0
  288. package/types/schema.js +6 -0
  289. package/types/selection.d.ts +43 -0
  290. package/types/selection.js +5 -0
  291. package/utils/index.d.ts +4 -0
  292. package/utils/index.js +7 -0
  293. package/codegen.d.ts +0 -13
  294. package/codegen.js +0 -293
  295. package/esm/codegen.js +0 -253
  296. package/esm/gql.js +0 -939
  297. package/esm/options.js +0 -27
  298. package/gql.d.ts +0 -188
  299. package/gql.js +0 -992
  300. package/options.d.ts +0 -45
  301. package/options.js +0 -31
@@ -0,0 +1,410 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateCreateMutationHook = generateCreateMutationHook;
4
+ exports.generateUpdateMutationHook = generateUpdateMutationHook;
5
+ exports.generateDeleteMutationHook = generateDeleteMutationHook;
6
+ exports.generateAllMutationHooks = generateAllMutationHooks;
7
+ const ts_ast_1 = require("./ts-ast");
8
+ const gql_ast_1 = require("./gql-ast");
9
+ const utils_1 = require("./utils");
10
+ // ============================================================================
11
+ // Create mutation hook generator
12
+ // ============================================================================
13
+ /**
14
+ * Generate create mutation hook file content using AST
15
+ */
16
+ function generateCreateMutationHook(table) {
17
+ const project = (0, ts_ast_1.createProject)();
18
+ const { typeName, singularName } = (0, utils_1.getTableNames)(table);
19
+ const hookName = (0, utils_1.getCreateMutationHookName)(table);
20
+ const mutationName = (0, utils_1.getCreateMutationName)(table);
21
+ const scalarFields = (0, utils_1.getScalarFields)(table);
22
+ // Generate GraphQL document via AST
23
+ const mutationAST = (0, gql_ast_1.buildCreateMutationAST)({ table });
24
+ const mutationDocument = (0, gql_ast_1.printGraphQL)(mutationAST);
25
+ const sourceFile = (0, ts_ast_1.createSourceFile)(project, (0, utils_1.getCreateMutationFileName)(table));
26
+ // Add file header
27
+ sourceFile.insertText(0, (0, ts_ast_1.createFileHeader)(`Create mutation hook for ${typeName}`) + '\n\n');
28
+ // Add imports
29
+ sourceFile.addImportDeclarations([
30
+ (0, ts_ast_1.createImport)({
31
+ moduleSpecifier: '@tanstack/react-query',
32
+ namedImports: ['useMutation', 'useQueryClient'],
33
+ typeOnlyNamedImports: ['UseMutationOptions'],
34
+ }),
35
+ (0, ts_ast_1.createImport)({
36
+ moduleSpecifier: '../client',
37
+ namedImports: ['execute'],
38
+ }),
39
+ (0, ts_ast_1.createImport)({
40
+ moduleSpecifier: '../types',
41
+ typeOnlyNamedImports: [typeName],
42
+ }),
43
+ ]);
44
+ // Re-export entity type
45
+ sourceFile.addStatements(`\n// Re-export entity type for convenience\nexport type { ${typeName} };\n`);
46
+ // Add section comment
47
+ sourceFile.addStatements('\n// ============================================================================');
48
+ sourceFile.addStatements('// GraphQL Document');
49
+ sourceFile.addStatements('// ============================================================================\n');
50
+ // Add mutation document constant
51
+ sourceFile.addVariableStatement((0, ts_ast_1.createConst)(`${mutationName}MutationDocument`, '`\n' + mutationDocument + '`'));
52
+ // Add section comment
53
+ sourceFile.addStatements('\n// ============================================================================');
54
+ sourceFile.addStatements('// Types');
55
+ sourceFile.addStatements('// ============================================================================\n');
56
+ // Generate CreateInput type - exclude auto-generated fields
57
+ const inputFields = scalarFields
58
+ .filter((f) => {
59
+ const name = f.name.toLowerCase();
60
+ return !['id', 'createdat', 'updatedat', 'created_at', 'updated_at'].includes(name);
61
+ })
62
+ .map((f) => ({
63
+ name: f.name,
64
+ type: `${(0, utils_1.fieldTypeToTs)(f.type)} | null`,
65
+ optional: true,
66
+ }));
67
+ sourceFile.addInterface((0, ts_ast_1.createInterface)(`${typeName}CreateInput`, inputFields, {
68
+ docs: [`Input type for creating a ${typeName}`],
69
+ }));
70
+ // Variables interface
71
+ sourceFile.addInterface((0, ts_ast_1.createInterface)(`${(0, utils_1.ucFirst)(mutationName)}MutationVariables`, [
72
+ {
73
+ name: 'input',
74
+ type: `{
75
+ ${(0, utils_1.lcFirst)(typeName)}: ${typeName}CreateInput;
76
+ }`,
77
+ },
78
+ ]));
79
+ // Result interface
80
+ sourceFile.addInterface((0, ts_ast_1.createInterface)(`${(0, utils_1.ucFirst)(mutationName)}MutationResult`, [
81
+ {
82
+ name: mutationName,
83
+ type: `{
84
+ ${singularName}: ${typeName};
85
+ }`,
86
+ },
87
+ ]));
88
+ // Add section comment
89
+ sourceFile.addStatements('\n// ============================================================================');
90
+ sourceFile.addStatements('// Hook');
91
+ sourceFile.addStatements('// ============================================================================\n');
92
+ // Hook function
93
+ sourceFile.addFunction({
94
+ name: hookName,
95
+ isExported: true,
96
+ parameters: [
97
+ {
98
+ name: 'options',
99
+ type: `Omit<UseMutationOptions<${(0, utils_1.ucFirst)(mutationName)}MutationResult, Error, ${(0, utils_1.ucFirst)(mutationName)}MutationVariables>, 'mutationFn'>`,
100
+ hasQuestionToken: true,
101
+ },
102
+ ],
103
+ statements: `const queryClient = useQueryClient();
104
+
105
+ return useMutation({
106
+ mutationFn: (variables: ${(0, utils_1.ucFirst)(mutationName)}MutationVariables) =>
107
+ execute<${(0, utils_1.ucFirst)(mutationName)}MutationResult, ${(0, utils_1.ucFirst)(mutationName)}MutationVariables>(
108
+ ${mutationName}MutationDocument,
109
+ variables
110
+ ),
111
+ onSuccess: () => {
112
+ // Invalidate list queries to refetch
113
+ queryClient.invalidateQueries({ queryKey: ['${typeName.toLowerCase()}', 'list'] });
114
+ },
115
+ ...options,
116
+ });`,
117
+ docs: [
118
+ {
119
+ description: `Mutation hook for creating a ${typeName}
120
+
121
+ @example
122
+ \`\`\`tsx
123
+ const { mutate, isPending } = ${hookName}();
124
+
125
+ mutate({
126
+ input: {
127
+ ${(0, utils_1.lcFirst)(typeName)}: {
128
+ // ... fields
129
+ },
130
+ },
131
+ });
132
+ \`\`\``,
133
+ },
134
+ ],
135
+ });
136
+ return {
137
+ fileName: (0, utils_1.getCreateMutationFileName)(table),
138
+ content: (0, ts_ast_1.getFormattedOutput)(sourceFile),
139
+ };
140
+ }
141
+ // ============================================================================
142
+ // Update mutation hook generator
143
+ // ============================================================================
144
+ /**
145
+ * Generate update mutation hook file content using AST
146
+ */
147
+ function generateUpdateMutationHook(table) {
148
+ // Check if update mutation exists
149
+ if (table.query?.update === null) {
150
+ return null;
151
+ }
152
+ const project = (0, ts_ast_1.createProject)();
153
+ const { typeName, singularName } = (0, utils_1.getTableNames)(table);
154
+ const hookName = (0, utils_1.getUpdateMutationHookName)(table);
155
+ const mutationName = (0, utils_1.getUpdateMutationName)(table);
156
+ const scalarFields = (0, utils_1.getScalarFields)(table);
157
+ // Generate GraphQL document via AST
158
+ const mutationAST = (0, gql_ast_1.buildUpdateMutationAST)({ table });
159
+ const mutationDocument = (0, gql_ast_1.printGraphQL)(mutationAST);
160
+ const sourceFile = (0, ts_ast_1.createSourceFile)(project, (0, utils_1.getUpdateMutationFileName)(table));
161
+ // Add file header
162
+ sourceFile.insertText(0, (0, ts_ast_1.createFileHeader)(`Update mutation hook for ${typeName}`) + '\n\n');
163
+ // Add imports
164
+ sourceFile.addImportDeclarations([
165
+ (0, ts_ast_1.createImport)({
166
+ moduleSpecifier: '@tanstack/react-query',
167
+ namedImports: ['useMutation', 'useQueryClient'],
168
+ typeOnlyNamedImports: ['UseMutationOptions'],
169
+ }),
170
+ (0, ts_ast_1.createImport)({
171
+ moduleSpecifier: '../client',
172
+ namedImports: ['execute'],
173
+ }),
174
+ (0, ts_ast_1.createImport)({
175
+ moduleSpecifier: '../types',
176
+ typeOnlyNamedImports: [typeName],
177
+ }),
178
+ ]);
179
+ // Re-export entity type
180
+ sourceFile.addStatements(`\n// Re-export entity type for convenience\nexport type { ${typeName} };\n`);
181
+ // Add section comment
182
+ sourceFile.addStatements('\n// ============================================================================');
183
+ sourceFile.addStatements('// GraphQL Document');
184
+ sourceFile.addStatements('// ============================================================================\n');
185
+ // Add mutation document constant
186
+ sourceFile.addVariableStatement((0, ts_ast_1.createConst)(`${mutationName}MutationDocument`, '`\n' + mutationDocument + '`'));
187
+ // Add section comment
188
+ sourceFile.addStatements('\n// ============================================================================');
189
+ sourceFile.addStatements('// Types');
190
+ sourceFile.addStatements('// ============================================================================\n');
191
+ // Generate Patch type - all fields optional
192
+ const patchFields = scalarFields
193
+ .filter((f) => f.name.toLowerCase() !== 'id')
194
+ .map((f) => ({
195
+ name: f.name,
196
+ type: `${(0, utils_1.fieldTypeToTs)(f.type)} | null`,
197
+ optional: true,
198
+ }));
199
+ sourceFile.addInterface((0, ts_ast_1.createInterface)(`${typeName}Patch`, patchFields, {
200
+ docs: [`Patch type for updating a ${typeName} - all fields optional`],
201
+ }));
202
+ // Variables interface
203
+ sourceFile.addInterface((0, ts_ast_1.createInterface)(`${(0, utils_1.ucFirst)(mutationName)}MutationVariables`, [
204
+ {
205
+ name: 'input',
206
+ type: `{
207
+ id: string;
208
+ patch: ${typeName}Patch;
209
+ }`,
210
+ },
211
+ ]));
212
+ // Result interface
213
+ sourceFile.addInterface((0, ts_ast_1.createInterface)(`${(0, utils_1.ucFirst)(mutationName)}MutationResult`, [
214
+ {
215
+ name: mutationName,
216
+ type: `{
217
+ ${singularName}: ${typeName};
218
+ }`,
219
+ },
220
+ ]));
221
+ // Add section comment
222
+ sourceFile.addStatements('\n// ============================================================================');
223
+ sourceFile.addStatements('// Hook');
224
+ sourceFile.addStatements('// ============================================================================\n');
225
+ // Hook function
226
+ sourceFile.addFunction({
227
+ name: hookName,
228
+ isExported: true,
229
+ parameters: [
230
+ {
231
+ name: 'options',
232
+ type: `Omit<UseMutationOptions<${(0, utils_1.ucFirst)(mutationName)}MutationResult, Error, ${(0, utils_1.ucFirst)(mutationName)}MutationVariables>, 'mutationFn'>`,
233
+ hasQuestionToken: true,
234
+ },
235
+ ],
236
+ statements: `const queryClient = useQueryClient();
237
+
238
+ return useMutation({
239
+ mutationFn: (variables: ${(0, utils_1.ucFirst)(mutationName)}MutationVariables) =>
240
+ execute<${(0, utils_1.ucFirst)(mutationName)}MutationResult, ${(0, utils_1.ucFirst)(mutationName)}MutationVariables>(
241
+ ${mutationName}MutationDocument,
242
+ variables
243
+ ),
244
+ onSuccess: (_, variables) => {
245
+ // Invalidate specific item and list queries
246
+ queryClient.invalidateQueries({ queryKey: ['${typeName.toLowerCase()}', 'detail', variables.input.id] });
247
+ queryClient.invalidateQueries({ queryKey: ['${typeName.toLowerCase()}', 'list'] });
248
+ },
249
+ ...options,
250
+ });`,
251
+ docs: [
252
+ {
253
+ description: `Mutation hook for updating a ${typeName}
254
+
255
+ @example
256
+ \`\`\`tsx
257
+ const { mutate, isPending } = ${hookName}();
258
+
259
+ mutate({
260
+ input: {
261
+ id: 'uuid-here',
262
+ patch: {
263
+ // ... fields to update
264
+ },
265
+ },
266
+ });
267
+ \`\`\``,
268
+ },
269
+ ],
270
+ });
271
+ return {
272
+ fileName: (0, utils_1.getUpdateMutationFileName)(table),
273
+ content: (0, ts_ast_1.getFormattedOutput)(sourceFile),
274
+ };
275
+ }
276
+ // ============================================================================
277
+ // Delete mutation hook generator
278
+ // ============================================================================
279
+ /**
280
+ * Generate delete mutation hook file content using AST
281
+ */
282
+ function generateDeleteMutationHook(table) {
283
+ // Check if delete mutation exists
284
+ if (table.query?.delete === null) {
285
+ return null;
286
+ }
287
+ const project = (0, ts_ast_1.createProject)();
288
+ const { typeName } = (0, utils_1.getTableNames)(table);
289
+ const hookName = (0, utils_1.getDeleteMutationHookName)(table);
290
+ const mutationName = (0, utils_1.getDeleteMutationName)(table);
291
+ // Generate GraphQL document via AST
292
+ const mutationAST = (0, gql_ast_1.buildDeleteMutationAST)({ table });
293
+ const mutationDocument = (0, gql_ast_1.printGraphQL)(mutationAST);
294
+ const sourceFile = (0, ts_ast_1.createSourceFile)(project, (0, utils_1.getDeleteMutationFileName)(table));
295
+ // Add file header
296
+ sourceFile.insertText(0, (0, ts_ast_1.createFileHeader)(`Delete mutation hook for ${typeName}`) + '\n\n');
297
+ // Add imports
298
+ sourceFile.addImportDeclarations([
299
+ (0, ts_ast_1.createImport)({
300
+ moduleSpecifier: '@tanstack/react-query',
301
+ namedImports: ['useMutation', 'useQueryClient'],
302
+ typeOnlyNamedImports: ['UseMutationOptions'],
303
+ }),
304
+ (0, ts_ast_1.createImport)({
305
+ moduleSpecifier: '../client',
306
+ namedImports: ['execute'],
307
+ }),
308
+ ]);
309
+ // Add section comment
310
+ sourceFile.addStatements('\n// ============================================================================');
311
+ sourceFile.addStatements('// GraphQL Document');
312
+ sourceFile.addStatements('// ============================================================================\n');
313
+ // Add mutation document constant
314
+ sourceFile.addVariableStatement((0, ts_ast_1.createConst)(`${mutationName}MutationDocument`, '`\n' + mutationDocument + '`'));
315
+ // Add section comment
316
+ sourceFile.addStatements('\n// ============================================================================');
317
+ sourceFile.addStatements('// Types');
318
+ sourceFile.addStatements('// ============================================================================\n');
319
+ // Variables interface
320
+ sourceFile.addInterface((0, ts_ast_1.createInterface)(`${(0, utils_1.ucFirst)(mutationName)}MutationVariables`, [
321
+ {
322
+ name: 'input',
323
+ type: `{
324
+ id: string;
325
+ }`,
326
+ },
327
+ ]));
328
+ // Result interface
329
+ sourceFile.addInterface((0, ts_ast_1.createInterface)(`${(0, utils_1.ucFirst)(mutationName)}MutationResult`, [
330
+ {
331
+ name: mutationName,
332
+ type: `{
333
+ clientMutationId: string | null;
334
+ deletedId: string | null;
335
+ }`,
336
+ },
337
+ ]));
338
+ // Add section comment
339
+ sourceFile.addStatements('\n// ============================================================================');
340
+ sourceFile.addStatements('// Hook');
341
+ sourceFile.addStatements('// ============================================================================\n');
342
+ // Hook function
343
+ sourceFile.addFunction({
344
+ name: hookName,
345
+ isExported: true,
346
+ parameters: [
347
+ {
348
+ name: 'options',
349
+ type: `Omit<UseMutationOptions<${(0, utils_1.ucFirst)(mutationName)}MutationResult, Error, ${(0, utils_1.ucFirst)(mutationName)}MutationVariables>, 'mutationFn'>`,
350
+ hasQuestionToken: true,
351
+ },
352
+ ],
353
+ statements: `const queryClient = useQueryClient();
354
+
355
+ return useMutation({
356
+ mutationFn: (variables: ${(0, utils_1.ucFirst)(mutationName)}MutationVariables) =>
357
+ execute<${(0, utils_1.ucFirst)(mutationName)}MutationResult, ${(0, utils_1.ucFirst)(mutationName)}MutationVariables>(
358
+ ${mutationName}MutationDocument,
359
+ variables
360
+ ),
361
+ onSuccess: (_, variables) => {
362
+ // Remove from cache and invalidate list
363
+ queryClient.removeQueries({ queryKey: ['${typeName.toLowerCase()}', 'detail', variables.input.id] });
364
+ queryClient.invalidateQueries({ queryKey: ['${typeName.toLowerCase()}', 'list'] });
365
+ },
366
+ ...options,
367
+ });`,
368
+ docs: [
369
+ {
370
+ description: `Mutation hook for deleting a ${typeName}
371
+
372
+ @example
373
+ \`\`\`tsx
374
+ const { mutate, isPending } = ${hookName}();
375
+
376
+ mutate({
377
+ input: {
378
+ id: 'uuid-to-delete',
379
+ },
380
+ });
381
+ \`\`\``,
382
+ },
383
+ ],
384
+ });
385
+ return {
386
+ fileName: (0, utils_1.getDeleteMutationFileName)(table),
387
+ content: (0, ts_ast_1.getFormattedOutput)(sourceFile),
388
+ };
389
+ }
390
+ // ============================================================================
391
+ // Batch generator
392
+ // ============================================================================
393
+ /**
394
+ * Generate all mutation hook files for all tables
395
+ */
396
+ function generateAllMutationHooks(tables) {
397
+ const files = [];
398
+ for (const table of tables) {
399
+ files.push(generateCreateMutationHook(table));
400
+ const updateHook = generateUpdateMutationHook(table);
401
+ if (updateHook) {
402
+ files.push(updateHook);
403
+ }
404
+ const deleteHook = generateDeleteMutationHook(table);
405
+ if (deleteHook) {
406
+ files.push(deleteHook);
407
+ }
408
+ }
409
+ return files;
410
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Barrel file generators for ORM client
3
+ *
4
+ * Generates index.ts files that re-export all models and operations.
5
+ */
6
+ import type { CleanTable } from '../../../types/schema';
7
+ export interface GeneratedBarrelFile {
8
+ fileName: string;
9
+ content: string;
10
+ }
11
+ /**
12
+ * Generate the models/index.ts barrel file
13
+ */
14
+ export declare function generateModelsBarrel(tables: CleanTable[]): GeneratedBarrelFile;
15
+ /**
16
+ * Generate the types.ts file that re-exports all types
17
+ */
18
+ export declare function generateTypesBarrel(_useSharedTypes: boolean): GeneratedBarrelFile;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateModelsBarrel = generateModelsBarrel;
4
+ exports.generateTypesBarrel = generateTypesBarrel;
5
+ const ts_ast_1 = require("../ts-ast");
6
+ const utils_1 = require("../utils");
7
+ /**
8
+ * Generate the models/index.ts barrel file
9
+ */
10
+ function generateModelsBarrel(tables) {
11
+ const project = (0, ts_ast_1.createProject)();
12
+ const sourceFile = (0, ts_ast_1.createSourceFile)(project, 'index.ts');
13
+ // Add file header
14
+ sourceFile.insertText(0, (0, ts_ast_1.createFileHeader)('Models barrel export') + '\n\n');
15
+ // Export all model classes (Select types are now in input-types.ts)
16
+ for (const table of tables) {
17
+ const { typeName } = (0, utils_1.getTableNames)(table);
18
+ const modelName = `${typeName}Model`;
19
+ const fileName = (0, utils_1.lcFirst)(typeName);
20
+ sourceFile.addExportDeclaration({
21
+ moduleSpecifier: `./${fileName}`,
22
+ namedExports: [modelName],
23
+ });
24
+ }
25
+ return {
26
+ fileName: 'models/index.ts',
27
+ content: (0, ts_ast_1.getFormattedOutput)(sourceFile),
28
+ };
29
+ }
30
+ /**
31
+ * Generate the types.ts file that re-exports all types
32
+ */
33
+ function generateTypesBarrel(_useSharedTypes) {
34
+ // Always re-export from input-types since that's where all types are generated
35
+ const content = `/**
36
+ * Types re-export
37
+ * @generated by @constructive-io/graphql-codegen
38
+ * DO NOT EDIT - changes will be overwritten
39
+ */
40
+
41
+ // Re-export all types from input-types
42
+ export * from './input-types';
43
+ `;
44
+ return {
45
+ fileName: 'types.ts',
46
+ content,
47
+ };
48
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * ORM Client generator
3
+ *
4
+ * Generates the createClient() factory function and main client file.
5
+ *
6
+ * Example output:
7
+ * ```typescript
8
+ * import { OrmClient, OrmClientConfig } from './client';
9
+ * import { UserModel } from './models/user';
10
+ * import { queryOperations } from './query';
11
+ * import { mutationOperations } from './mutation';
12
+ *
13
+ * export function createClient(config: OrmClientConfig) {
14
+ * const client = new OrmClient(config);
15
+ * return {
16
+ * user: new UserModel(client),
17
+ * post: new PostModel(client),
18
+ * query: queryOperations(client),
19
+ * mutation: mutationOperations(client),
20
+ * };
21
+ * }
22
+ * ```
23
+ */
24
+ import type { CleanTable } from '../../../types/schema';
25
+ export interface GeneratedClientFile {
26
+ fileName: string;
27
+ content: string;
28
+ }
29
+ /**
30
+ * Generate the main client.ts file (OrmClient class)
31
+ * This is the runtime client that handles GraphQL execution
32
+ */
33
+ export declare function generateOrmClientFile(): GeneratedClientFile;
34
+ /**
35
+ * Generate the query-builder.ts file (runtime query builder)
36
+ */
37
+ export declare function generateQueryBuilderFile(): GeneratedClientFile;
38
+ /**
39
+ * Generate the select-types.ts file
40
+ */
41
+ export declare function generateSelectTypesFile(): GeneratedClientFile;
42
+ /**
43
+ * Generate the main index.ts with createClient factory
44
+ */
45
+ export declare function generateCreateClientFile(tables: CleanTable[], hasCustomQueries: boolean, hasCustomMutations: boolean): GeneratedClientFile;