@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,438 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateListQueryHook = generateListQueryHook;
4
+ exports.generateSingleQueryHook = generateSingleQueryHook;
5
+ exports.generateAllQueryHooks = generateAllQueryHooks;
6
+ const ts_ast_1 = require("./ts-ast");
7
+ const gql_ast_1 = require("./gql-ast");
8
+ const utils_1 = require("./utils");
9
+ // ============================================================================
10
+ // List query hook generator
11
+ // ============================================================================
12
+ /**
13
+ * Generate list query hook file content using AST
14
+ */
15
+ function generateListQueryHook(table) {
16
+ const project = (0, ts_ast_1.createProject)();
17
+ const { typeName, pluralName } = (0, utils_1.getTableNames)(table);
18
+ const hookName = (0, utils_1.getListQueryHookName)(table);
19
+ const queryName = (0, utils_1.getAllRowsQueryName)(table);
20
+ const filterTypeName = (0, utils_1.getFilterTypeName)(table);
21
+ const orderByTypeName = (0, utils_1.getOrderByTypeName)(table);
22
+ const scalarFields = (0, utils_1.getScalarFields)(table);
23
+ // Generate GraphQL document via AST
24
+ const queryAST = (0, gql_ast_1.buildListQueryAST)({ table });
25
+ const queryDocument = (0, gql_ast_1.printGraphQL)(queryAST);
26
+ const sourceFile = (0, ts_ast_1.createSourceFile)(project, (0, utils_1.getListQueryFileName)(table));
27
+ // Add file header as leading comment
28
+ sourceFile.insertText(0, (0, ts_ast_1.createFileHeader)(`List query hook for ${typeName}`) + '\n\n');
29
+ // Collect all filter types used by this table's fields
30
+ const filterTypesUsed = new Set();
31
+ for (const field of scalarFields) {
32
+ const filterType = (0, utils_1.getScalarFilterType)(field.type.gqlType);
33
+ if (filterType) {
34
+ filterTypesUsed.add(filterType);
35
+ }
36
+ }
37
+ // Add imports
38
+ sourceFile.addImportDeclarations([
39
+ (0, ts_ast_1.createImport)({
40
+ moduleSpecifier: '@tanstack/react-query',
41
+ namedImports: ['useQuery'],
42
+ typeOnlyNamedImports: ['UseQueryOptions', 'QueryClient'],
43
+ }),
44
+ (0, ts_ast_1.createImport)({
45
+ moduleSpecifier: '../client',
46
+ namedImports: ['execute'],
47
+ typeOnlyNamedImports: ['ExecuteOptions'],
48
+ }),
49
+ (0, ts_ast_1.createImport)({
50
+ moduleSpecifier: '../types',
51
+ typeOnlyNamedImports: [typeName, ...Array.from(filterTypesUsed)],
52
+ }),
53
+ ]);
54
+ // Re-export entity type
55
+ sourceFile.addStatements(`\n// Re-export entity type for convenience\nexport type { ${typeName} };\n`);
56
+ // Add section comment
57
+ sourceFile.addStatements('\n// ============================================================================');
58
+ sourceFile.addStatements('// GraphQL Document');
59
+ sourceFile.addStatements('// ============================================================================\n');
60
+ // Add query document constant
61
+ sourceFile.addVariableStatement((0, ts_ast_1.createConst)(`${queryName}QueryDocument`, '`\n' + queryDocument + '`'));
62
+ // Add section comment
63
+ sourceFile.addStatements('\n// ============================================================================');
64
+ sourceFile.addStatements('// Types');
65
+ sourceFile.addStatements('// ============================================================================\n');
66
+ // Generate filter interface
67
+ const fieldFilters = scalarFields
68
+ .map((field) => {
69
+ const filterType = (0, utils_1.getScalarFilterType)(field.type.gqlType);
70
+ return filterType ? { fieldName: field.name, filterType } : null;
71
+ })
72
+ .filter((f) => f !== null);
73
+ sourceFile.addInterface((0, ts_ast_1.createFilterInterface)(filterTypeName, fieldFilters));
74
+ // Generate OrderBy type
75
+ const orderByValues = [
76
+ ...scalarFields.flatMap((f) => [
77
+ `${(0, utils_1.toScreamingSnake)(f.name)}_ASC`,
78
+ `${(0, utils_1.toScreamingSnake)(f.name)}_DESC`,
79
+ ]),
80
+ 'NATURAL',
81
+ 'PRIMARY_KEY_ASC',
82
+ 'PRIMARY_KEY_DESC',
83
+ ];
84
+ sourceFile.addTypeAlias((0, ts_ast_1.createTypeAlias)(orderByTypeName, (0, ts_ast_1.createUnionType)(orderByValues)));
85
+ // Variables interface
86
+ const variablesProps = [
87
+ { name: 'first', type: 'number', optional: true },
88
+ { name: 'offset', type: 'number', optional: true },
89
+ { name: 'filter', type: filterTypeName, optional: true },
90
+ { name: 'orderBy', type: `${orderByTypeName}[]`, optional: true },
91
+ ];
92
+ sourceFile.addInterface((0, ts_ast_1.createInterface)(`${(0, utils_1.ucFirst)(pluralName)}QueryVariables`, variablesProps));
93
+ // Result interface
94
+ const resultProps = [
95
+ {
96
+ name: queryName,
97
+ type: `{
98
+ totalCount: number;
99
+ nodes: ${typeName}[];
100
+ pageInfo: {
101
+ hasNextPage: boolean;
102
+ hasPreviousPage: boolean;
103
+ startCursor: string | null;
104
+ endCursor: string | null;
105
+ };
106
+ }`,
107
+ },
108
+ ];
109
+ sourceFile.addInterface((0, ts_ast_1.createInterface)(`${(0, utils_1.ucFirst)(pluralName)}QueryResult`, resultProps));
110
+ // Add section comment
111
+ sourceFile.addStatements('\n// ============================================================================');
112
+ sourceFile.addStatements('// Query Key');
113
+ sourceFile.addStatements('// ============================================================================\n');
114
+ // Query key factory
115
+ sourceFile.addVariableStatement((0, ts_ast_1.createConst)(`${queryName}QueryKey`, `(variables?: ${(0, utils_1.ucFirst)(pluralName)}QueryVariables) =>
116
+ ['${typeName.toLowerCase()}', 'list', variables] as const`));
117
+ // Add section comment
118
+ sourceFile.addStatements('\n// ============================================================================');
119
+ sourceFile.addStatements('// Hook');
120
+ sourceFile.addStatements('// ============================================================================\n');
121
+ // Hook function
122
+ sourceFile.addFunction({
123
+ name: hookName,
124
+ isExported: true,
125
+ parameters: [
126
+ {
127
+ name: 'variables',
128
+ type: `${(0, utils_1.ucFirst)(pluralName)}QueryVariables`,
129
+ hasQuestionToken: true,
130
+ },
131
+ {
132
+ name: 'options',
133
+ type: `Omit<UseQueryOptions<${(0, utils_1.ucFirst)(pluralName)}QueryResult, Error>, 'queryKey' | 'queryFn'>`,
134
+ hasQuestionToken: true,
135
+ },
136
+ ],
137
+ statements: `return useQuery({
138
+ queryKey: ${queryName}QueryKey(variables),
139
+ queryFn: () => execute<${(0, utils_1.ucFirst)(pluralName)}QueryResult, ${(0, utils_1.ucFirst)(pluralName)}QueryVariables>(
140
+ ${queryName}QueryDocument,
141
+ variables
142
+ ),
143
+ ...options,
144
+ });`,
145
+ docs: [
146
+ {
147
+ description: `Query hook for fetching ${typeName} list
148
+
149
+ @example
150
+ \`\`\`tsx
151
+ const { data, isLoading } = ${hookName}({
152
+ first: 10,
153
+ filter: { name: { equalTo: "example" } },
154
+ orderBy: ['CREATED_AT_DESC'],
155
+ });
156
+ \`\`\``,
157
+ },
158
+ ],
159
+ });
160
+ // Add section comment for standalone functions
161
+ sourceFile.addStatements('\n// ============================================================================');
162
+ sourceFile.addStatements('// Standalone Functions (non-React)');
163
+ sourceFile.addStatements('// ============================================================================\n');
164
+ // Fetch function (standalone, no React)
165
+ sourceFile.addFunction({
166
+ name: `fetch${(0, utils_1.ucFirst)(pluralName)}Query`,
167
+ isExported: true,
168
+ isAsync: true,
169
+ parameters: [
170
+ {
171
+ name: 'variables',
172
+ type: `${(0, utils_1.ucFirst)(pluralName)}QueryVariables`,
173
+ hasQuestionToken: true,
174
+ },
175
+ {
176
+ name: 'options',
177
+ type: 'ExecuteOptions',
178
+ hasQuestionToken: true,
179
+ },
180
+ ],
181
+ returnType: `Promise<${(0, utils_1.ucFirst)(pluralName)}QueryResult>`,
182
+ statements: `return execute<${(0, utils_1.ucFirst)(pluralName)}QueryResult, ${(0, utils_1.ucFirst)(pluralName)}QueryVariables>(
183
+ ${queryName}QueryDocument,
184
+ variables,
185
+ options
186
+ );`,
187
+ docs: [
188
+ {
189
+ description: `Fetch ${typeName} list without React hooks
190
+
191
+ @example
192
+ \`\`\`ts
193
+ // Direct fetch
194
+ const data = await fetch${(0, utils_1.ucFirst)(pluralName)}Query({ first: 10 });
195
+
196
+ // With QueryClient
197
+ const data = await queryClient.fetchQuery({
198
+ queryKey: ${queryName}QueryKey(variables),
199
+ queryFn: () => fetch${(0, utils_1.ucFirst)(pluralName)}Query(variables),
200
+ });
201
+ \`\`\``,
202
+ },
203
+ ],
204
+ });
205
+ // Prefetch function (for SSR/QueryClient)
206
+ sourceFile.addFunction({
207
+ name: `prefetch${(0, utils_1.ucFirst)(pluralName)}Query`,
208
+ isExported: true,
209
+ isAsync: true,
210
+ parameters: [
211
+ {
212
+ name: 'queryClient',
213
+ type: 'QueryClient',
214
+ },
215
+ {
216
+ name: 'variables',
217
+ type: `${(0, utils_1.ucFirst)(pluralName)}QueryVariables`,
218
+ hasQuestionToken: true,
219
+ },
220
+ {
221
+ name: 'options',
222
+ type: 'ExecuteOptions',
223
+ hasQuestionToken: true,
224
+ },
225
+ ],
226
+ returnType: 'Promise<void>',
227
+ statements: `await queryClient.prefetchQuery({
228
+ queryKey: ${queryName}QueryKey(variables),
229
+ queryFn: () => execute<${(0, utils_1.ucFirst)(pluralName)}QueryResult, ${(0, utils_1.ucFirst)(pluralName)}QueryVariables>(
230
+ ${queryName}QueryDocument,
231
+ variables,
232
+ options
233
+ ),
234
+ });`,
235
+ docs: [
236
+ {
237
+ description: `Prefetch ${typeName} list for SSR or cache warming
238
+
239
+ @example
240
+ \`\`\`ts
241
+ await prefetch${(0, utils_1.ucFirst)(pluralName)}Query(queryClient, { first: 10 });
242
+ \`\`\``,
243
+ },
244
+ ],
245
+ });
246
+ return {
247
+ fileName: (0, utils_1.getListQueryFileName)(table),
248
+ content: (0, ts_ast_1.getFormattedOutput)(sourceFile),
249
+ };
250
+ }
251
+ // ============================================================================
252
+ // Single item query hook generator
253
+ // ============================================================================
254
+ /**
255
+ * Generate single item query hook file content using AST
256
+ */
257
+ function generateSingleQueryHook(table) {
258
+ const project = (0, ts_ast_1.createProject)();
259
+ const { typeName, singularName } = (0, utils_1.getTableNames)(table);
260
+ const hookName = (0, utils_1.getSingleQueryHookName)(table);
261
+ const queryName = (0, utils_1.getSingleRowQueryName)(table);
262
+ // Generate GraphQL document via AST
263
+ const queryAST = (0, gql_ast_1.buildSingleQueryAST)({ table });
264
+ const queryDocument = (0, gql_ast_1.printGraphQL)(queryAST);
265
+ const sourceFile = (0, ts_ast_1.createSourceFile)(project, (0, utils_1.getSingleQueryFileName)(table));
266
+ // Add file header
267
+ sourceFile.insertText(0, (0, ts_ast_1.createFileHeader)(`Single item query hook for ${typeName}`) + '\n\n');
268
+ // Add imports
269
+ sourceFile.addImportDeclarations([
270
+ (0, ts_ast_1.createImport)({
271
+ moduleSpecifier: '@tanstack/react-query',
272
+ namedImports: ['useQuery'],
273
+ typeOnlyNamedImports: ['UseQueryOptions', 'QueryClient'],
274
+ }),
275
+ (0, ts_ast_1.createImport)({
276
+ moduleSpecifier: '../client',
277
+ namedImports: ['execute'],
278
+ typeOnlyNamedImports: ['ExecuteOptions'],
279
+ }),
280
+ (0, ts_ast_1.createImport)({
281
+ moduleSpecifier: '../types',
282
+ typeOnlyNamedImports: [typeName],
283
+ }),
284
+ ]);
285
+ // Re-export entity type
286
+ sourceFile.addStatements(`\n// Re-export entity type for convenience\nexport type { ${typeName} };\n`);
287
+ // Add section comment
288
+ sourceFile.addStatements('\n// ============================================================================');
289
+ sourceFile.addStatements('// GraphQL Document');
290
+ sourceFile.addStatements('// ============================================================================\n');
291
+ // Add query document constant
292
+ sourceFile.addVariableStatement((0, ts_ast_1.createConst)(`${queryName}QueryDocument`, '`\n' + queryDocument + '`'));
293
+ // Add section comment
294
+ sourceFile.addStatements('\n// ============================================================================');
295
+ sourceFile.addStatements('// Types');
296
+ sourceFile.addStatements('// ============================================================================\n');
297
+ // Variables interface
298
+ sourceFile.addInterface((0, ts_ast_1.createInterface)(`${(0, utils_1.ucFirst)(singularName)}QueryVariables`, [
299
+ { name: 'id', type: 'string' },
300
+ ]));
301
+ // Result interface
302
+ sourceFile.addInterface((0, ts_ast_1.createInterface)(`${(0, utils_1.ucFirst)(singularName)}QueryResult`, [
303
+ { name: queryName, type: `${typeName} | null` },
304
+ ]));
305
+ // Add section comment
306
+ sourceFile.addStatements('\n// ============================================================================');
307
+ sourceFile.addStatements('// Query Key');
308
+ sourceFile.addStatements('// ============================================================================\n');
309
+ // Query key factory
310
+ sourceFile.addVariableStatement((0, ts_ast_1.createConst)(`${queryName}QueryKey`, `(id: string) =>
311
+ ['${typeName.toLowerCase()}', 'detail', id] as const`));
312
+ // Add section comment
313
+ sourceFile.addStatements('\n// ============================================================================');
314
+ sourceFile.addStatements('// Hook');
315
+ sourceFile.addStatements('// ============================================================================\n');
316
+ // Hook function
317
+ sourceFile.addFunction({
318
+ name: hookName,
319
+ isExported: true,
320
+ parameters: [
321
+ { name: 'id', type: 'string' },
322
+ {
323
+ name: 'options',
324
+ type: `Omit<UseQueryOptions<${(0, utils_1.ucFirst)(singularName)}QueryResult, Error>, 'queryKey' | 'queryFn'>`,
325
+ hasQuestionToken: true,
326
+ },
327
+ ],
328
+ statements: `return useQuery({
329
+ queryKey: ${queryName}QueryKey(id),
330
+ queryFn: () => execute<${(0, utils_1.ucFirst)(singularName)}QueryResult, ${(0, utils_1.ucFirst)(singularName)}QueryVariables>(
331
+ ${queryName}QueryDocument,
332
+ { id }
333
+ ),
334
+ enabled: !!id && (options?.enabled !== false),
335
+ ...options,
336
+ });`,
337
+ docs: [
338
+ {
339
+ description: `Query hook for fetching a single ${typeName} by ID
340
+
341
+ @example
342
+ \`\`\`tsx
343
+ const { data, isLoading } = ${hookName}('uuid-here');
344
+
345
+ if (data?.${queryName}) {
346
+ console.log(data.${queryName}.id);
347
+ }
348
+ \`\`\``,
349
+ },
350
+ ],
351
+ });
352
+ // Add section comment for standalone functions
353
+ sourceFile.addStatements('\n// ============================================================================');
354
+ sourceFile.addStatements('// Standalone Functions (non-React)');
355
+ sourceFile.addStatements('// ============================================================================\n');
356
+ // Fetch function (standalone, no React)
357
+ sourceFile.addFunction({
358
+ name: `fetch${(0, utils_1.ucFirst)(singularName)}Query`,
359
+ isExported: true,
360
+ isAsync: true,
361
+ parameters: [
362
+ { name: 'id', type: 'string' },
363
+ {
364
+ name: 'options',
365
+ type: 'ExecuteOptions',
366
+ hasQuestionToken: true,
367
+ },
368
+ ],
369
+ returnType: `Promise<${(0, utils_1.ucFirst)(singularName)}QueryResult>`,
370
+ statements: `return execute<${(0, utils_1.ucFirst)(singularName)}QueryResult, ${(0, utils_1.ucFirst)(singularName)}QueryVariables>(
371
+ ${queryName}QueryDocument,
372
+ { id },
373
+ options
374
+ );`,
375
+ docs: [
376
+ {
377
+ description: `Fetch a single ${typeName} by ID without React hooks
378
+
379
+ @example
380
+ \`\`\`ts
381
+ const data = await fetch${(0, utils_1.ucFirst)(singularName)}Query('uuid-here');
382
+ \`\`\``,
383
+ },
384
+ ],
385
+ });
386
+ // Prefetch function (for SSR/QueryClient)
387
+ sourceFile.addFunction({
388
+ name: `prefetch${(0, utils_1.ucFirst)(singularName)}Query`,
389
+ isExported: true,
390
+ isAsync: true,
391
+ parameters: [
392
+ { name: 'queryClient', type: 'QueryClient' },
393
+ { name: 'id', type: 'string' },
394
+ {
395
+ name: 'options',
396
+ type: 'ExecuteOptions',
397
+ hasQuestionToken: true,
398
+ },
399
+ ],
400
+ returnType: 'Promise<void>',
401
+ statements: `await queryClient.prefetchQuery({
402
+ queryKey: ${queryName}QueryKey(id),
403
+ queryFn: () => execute<${(0, utils_1.ucFirst)(singularName)}QueryResult, ${(0, utils_1.ucFirst)(singularName)}QueryVariables>(
404
+ ${queryName}QueryDocument,
405
+ { id },
406
+ options
407
+ ),
408
+ });`,
409
+ docs: [
410
+ {
411
+ description: `Prefetch a single ${typeName} for SSR or cache warming
412
+
413
+ @example
414
+ \`\`\`ts
415
+ await prefetch${(0, utils_1.ucFirst)(singularName)}Query(queryClient, 'uuid-here');
416
+ \`\`\``,
417
+ },
418
+ ],
419
+ });
420
+ return {
421
+ fileName: (0, utils_1.getSingleQueryFileName)(table),
422
+ content: (0, ts_ast_1.getFormattedOutput)(sourceFile),
423
+ };
424
+ }
425
+ // ============================================================================
426
+ // Batch generator
427
+ // ============================================================================
428
+ /**
429
+ * Generate all query hook files for all tables
430
+ */
431
+ function generateAllQueryHooks(tables) {
432
+ const files = [];
433
+ for (const table of tables) {
434
+ files.push(generateListQueryHook(table));
435
+ files.push(generateSingleQueryHook(table));
436
+ }
437
+ return files;
438
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Shared scalar mappings for code generation
3
+ */
4
+ export declare const SCALAR_TS_MAP: Record<string, string>;
5
+ export declare const SCALAR_FILTER_MAP: Record<string, string>;
6
+ export declare const SCALAR_NAMES: Set<string>;
7
+ export interface ScalarToTsOptions {
8
+ unknownScalar?: 'unknown' | 'name';
9
+ overrides?: Record<string, string>;
10
+ }
11
+ export declare function scalarToTsType(scalarName: string, options?: ScalarToTsOptions): string;
12
+ export declare function scalarToFilterType(scalarName: string): string | null;
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ /**
3
+ * Shared scalar mappings for code generation
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SCALAR_NAMES = exports.SCALAR_FILTER_MAP = exports.SCALAR_TS_MAP = void 0;
7
+ exports.scalarToTsType = scalarToTsType;
8
+ exports.scalarToFilterType = scalarToFilterType;
9
+ exports.SCALAR_TS_MAP = {
10
+ // Standard GraphQL scalars
11
+ String: 'string',
12
+ Int: 'number',
13
+ Float: 'number',
14
+ Boolean: 'boolean',
15
+ ID: 'string',
16
+ // PostGraphile scalars
17
+ UUID: 'string',
18
+ Cursor: 'string',
19
+ Datetime: 'string',
20
+ Date: 'string',
21
+ Time: 'string',
22
+ JSON: 'unknown',
23
+ BigInt: 'string',
24
+ BigFloat: 'string',
25
+ // Geometry types
26
+ GeoJSON: 'unknown',
27
+ Geometry: 'unknown',
28
+ Point: 'unknown',
29
+ // Interval
30
+ Interval: 'string',
31
+ // PostgreSQL-specific types
32
+ BitString: 'string',
33
+ FullText: 'string',
34
+ InternetAddress: 'string',
35
+ Inet: 'string',
36
+ Cidr: 'string',
37
+ MacAddr: 'string',
38
+ TsVector: 'string',
39
+ TsQuery: 'string',
40
+ };
41
+ exports.SCALAR_FILTER_MAP = {
42
+ String: 'StringFilter',
43
+ Int: 'IntFilter',
44
+ Float: 'FloatFilter',
45
+ Boolean: 'BooleanFilter',
46
+ UUID: 'UUIDFilter',
47
+ ID: 'UUIDFilter',
48
+ Datetime: 'DatetimeFilter',
49
+ Date: 'DateFilter',
50
+ Time: 'StringFilter',
51
+ JSON: 'JSONFilter',
52
+ BigInt: 'BigIntFilter',
53
+ BigFloat: 'BigFloatFilter',
54
+ BitString: 'BitStringFilter',
55
+ InternetAddress: 'InternetAddressFilter',
56
+ FullText: 'FullTextFilter',
57
+ Interval: 'StringFilter',
58
+ };
59
+ exports.SCALAR_NAMES = new Set(Object.keys(exports.SCALAR_TS_MAP));
60
+ function scalarToTsType(scalarName, options = {}) {
61
+ const override = options.overrides?.[scalarName];
62
+ if (override)
63
+ return override;
64
+ const mapped = exports.SCALAR_TS_MAP[scalarName];
65
+ if (mapped)
66
+ return mapped;
67
+ return options.unknownScalar === 'unknown' ? 'unknown' : scalarName;
68
+ }
69
+ function scalarToFilterType(scalarName) {
70
+ return exports.SCALAR_FILTER_MAP[scalarName] ?? null;
71
+ }
@@ -0,0 +1,51 @@
1
+ import type { DocumentNode, FieldNode, VariableDefinitionNode } from 'graphql';
2
+ import type { CleanOperation, CleanArgument, CleanTypeRef, TypeRegistry } from '../../types/schema';
3
+ export interface FieldSelectionConfig {
4
+ /** Max depth for nested object selections */
5
+ maxDepth: number;
6
+ /** Skip the 'query' field in payloads */
7
+ skipQueryField: boolean;
8
+ /** Type registry for resolving nested types */
9
+ typeRegistry?: TypeRegistry;
10
+ }
11
+ /**
12
+ * Build variable definitions from operation arguments
13
+ */
14
+ export declare function buildVariableDefinitions(args: CleanArgument[]): VariableDefinitionNode[];
15
+ /**
16
+ * Build field selections for an object type
17
+ * Recursively handles nested objects up to maxDepth
18
+ */
19
+ export declare function buildFieldSelections(typeRef: CleanTypeRef, config: FieldSelectionConfig, currentDepth?: number): FieldNode[];
20
+ export interface CustomQueryConfig {
21
+ operation: CleanOperation;
22
+ typeRegistry?: TypeRegistry;
23
+ maxDepth?: number;
24
+ skipQueryField?: boolean;
25
+ }
26
+ /**
27
+ * Build a custom query AST from a CleanOperation
28
+ */
29
+ export declare function buildCustomQueryAST(config: CustomQueryConfig): DocumentNode;
30
+ export interface CustomMutationConfig {
31
+ operation: CleanOperation;
32
+ typeRegistry?: TypeRegistry;
33
+ maxDepth?: number;
34
+ skipQueryField?: boolean;
35
+ }
36
+ /**
37
+ * Build a custom mutation AST from a CleanOperation
38
+ */
39
+ export declare function buildCustomMutationAST(config: CustomMutationConfig): DocumentNode;
40
+ /**
41
+ * Print a document AST to GraphQL string
42
+ */
43
+ export declare function printGraphQL(ast: DocumentNode): string;
44
+ /**
45
+ * Build and print a custom query in one call
46
+ */
47
+ export declare function buildCustomQueryString(config: CustomQueryConfig): string;
48
+ /**
49
+ * Build and print a custom mutation in one call
50
+ */
51
+ export declare function buildCustomMutationString(config: CustomMutationConfig): string;