@constructive-io/graphql-codegen 2.18.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,679 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.toCamelCasePlural = toCamelCasePlural;
37
+ exports.toOrderByTypeName = toOrderByTypeName;
38
+ exports.cleanTableToMetaObject = cleanTableToMetaObject;
39
+ exports.generateIntrospectionSchema = generateIntrospectionSchema;
40
+ exports.createASTQueryBuilder = createASTQueryBuilder;
41
+ exports.buildSelect = buildSelect;
42
+ exports.buildFindOne = buildFindOne;
43
+ exports.buildCount = buildCount;
44
+ /**
45
+ * Query generators for SELECT, FindOne, and Count operations
46
+ * Uses AST-based approach for all query generation
47
+ */
48
+ const t = __importStar(require("gql-ast"));
49
+ const graphql_1 = require("graphql");
50
+ const inflection = __importStar(require("inflection"));
51
+ const typed_document_1 = require("../client/typed-document");
52
+ const custom_ast_1 = require("../core/custom-ast");
53
+ const query_builder_1 = require("../core/query-builder");
54
+ const field_selector_1 = require("./field-selector");
55
+ /**
56
+ * Convert PascalCase table name to camelCase plural for GraphQL queries
57
+ * Uses the inflection library for proper pluralization
58
+ * Example: "ActionGoal" -> "actionGoals", "User" -> "users", "Person" -> "people"
59
+ */
60
+ function toCamelCasePlural(tableName) {
61
+ // First convert to camelCase (lowercase first letter)
62
+ const camelCase = inflection.camelize(tableName, true);
63
+ // Then pluralize properly
64
+ return inflection.pluralize(camelCase);
65
+ }
66
+ /**
67
+ * Generate the PostGraphile OrderBy enum type name for a table
68
+ * PostGraphile uses pluralized PascalCase: "Product" -> "ProductsOrderBy"
69
+ * Example: "Product" -> "ProductsOrderBy", "Person" -> "PeopleOrderBy"
70
+ */
71
+ function toOrderByTypeName(tableName) {
72
+ const plural = toCamelCasePlural(tableName); // "products", "people"
73
+ // Capitalize first letter for PascalCase
74
+ return `${plural.charAt(0).toUpperCase() + plural.slice(1)}OrderBy`;
75
+ }
76
+ /**
77
+ * Convert CleanTable to MetaObject format for QueryBuilder
78
+ */
79
+ function cleanTableToMetaObject(tables) {
80
+ return {
81
+ tables: tables.map((table) => ({
82
+ name: table.name,
83
+ fields: table.fields.map((field) => ({
84
+ name: field.name,
85
+ type: {
86
+ gqlType: field.type.gqlType,
87
+ isArray: field.type.isArray,
88
+ modifier: field.type.modifier,
89
+ pgAlias: field.type.pgAlias,
90
+ pgType: field.type.pgType,
91
+ subtype: field.type.subtype,
92
+ typmod: field.type.typmod,
93
+ },
94
+ })),
95
+ primaryConstraints: [], // Would need to be derived from schema
96
+ uniqueConstraints: [], // Would need to be derived from schema
97
+ foreignConstraints: table.relations.belongsTo.map((rel) => ({
98
+ refTable: rel.referencesTable,
99
+ fromKey: {
100
+ name: rel.fieldName || '',
101
+ type: {
102
+ gqlType: 'UUID', // Default, should be derived from actual field
103
+ isArray: false,
104
+ modifier: null,
105
+ pgAlias: null,
106
+ pgType: null,
107
+ subtype: null,
108
+ typmod: null,
109
+ },
110
+ alias: rel.fieldName || '',
111
+ },
112
+ toKey: {
113
+ name: 'id',
114
+ type: {
115
+ gqlType: 'UUID',
116
+ isArray: false,
117
+ modifier: null,
118
+ pgAlias: null,
119
+ pgType: null,
120
+ subtype: null,
121
+ typmod: null,
122
+ },
123
+ },
124
+ })),
125
+ })),
126
+ };
127
+ }
128
+ /**
129
+ * Generate basic IntrospectionSchema from CleanTable array
130
+ * This creates a minimal schema for AST generation
131
+ */
132
+ function generateIntrospectionSchema(tables) {
133
+ const schema = {};
134
+ for (const table of tables) {
135
+ const modelName = table.name;
136
+ const pluralName = toCamelCasePlural(modelName);
137
+ // Basic field selection for the model
138
+ const selection = table.fields.map((field) => field.name);
139
+ // Add getMany query
140
+ schema[pluralName] = {
141
+ qtype: 'getMany',
142
+ model: modelName,
143
+ selection,
144
+ properties: convertFieldsToProperties(table.fields),
145
+ };
146
+ // Add getOne query (by ID)
147
+ const singularName = inflection.camelize(modelName, true);
148
+ schema[singularName] = {
149
+ qtype: 'getOne',
150
+ model: modelName,
151
+ selection,
152
+ properties: convertFieldsToProperties(table.fields),
153
+ };
154
+ // Add create mutation
155
+ schema[`create${modelName}`] = {
156
+ qtype: 'mutation',
157
+ mutationType: 'create',
158
+ model: modelName,
159
+ selection,
160
+ properties: {
161
+ input: {
162
+ name: 'input',
163
+ type: `Create${modelName}Input`,
164
+ isNotNull: true,
165
+ isArray: false,
166
+ isArrayNotNull: false,
167
+ properties: {
168
+ [inflection.camelize(modelName, true)]: {
169
+ name: inflection.camelize(modelName, true),
170
+ type: `${modelName}Input`,
171
+ isNotNull: true,
172
+ isArray: false,
173
+ isArrayNotNull: false,
174
+ properties: convertFieldsToNestedProperties(table.fields),
175
+ },
176
+ },
177
+ },
178
+ },
179
+ };
180
+ // Add update mutation
181
+ schema[`update${modelName}`] = {
182
+ qtype: 'mutation',
183
+ mutationType: 'patch',
184
+ model: modelName,
185
+ selection,
186
+ properties: {
187
+ input: {
188
+ name: 'input',
189
+ type: `Update${modelName}Input`,
190
+ isNotNull: true,
191
+ isArray: false,
192
+ isArrayNotNull: false,
193
+ properties: {
194
+ patch: {
195
+ name: 'patch',
196
+ type: `${modelName}Patch`,
197
+ isNotNull: true,
198
+ isArray: false,
199
+ isArrayNotNull: false,
200
+ properties: convertFieldsToNestedProperties(table.fields),
201
+ },
202
+ },
203
+ },
204
+ },
205
+ };
206
+ // Add delete mutation
207
+ schema[`delete${modelName}`] = {
208
+ qtype: 'mutation',
209
+ mutationType: 'delete',
210
+ model: modelName,
211
+ selection,
212
+ properties: {
213
+ input: {
214
+ name: 'input',
215
+ type: `Delete${modelName}Input`,
216
+ isNotNull: true,
217
+ isArray: false,
218
+ isArrayNotNull: false,
219
+ properties: {
220
+ id: {
221
+ name: 'id',
222
+ type: 'UUID',
223
+ isNotNull: true,
224
+ isArray: false,
225
+ isArrayNotNull: false,
226
+ },
227
+ },
228
+ },
229
+ },
230
+ };
231
+ }
232
+ return schema;
233
+ }
234
+ /**
235
+ * Convert CleanTable fields to QueryBuilder properties
236
+ */
237
+ function convertFieldsToProperties(fields) {
238
+ const properties = {};
239
+ fields.forEach((field) => {
240
+ properties[field.name] = {
241
+ name: field.name,
242
+ type: field.type.gqlType,
243
+ isNotNull: !field.type.gqlType.endsWith('!'),
244
+ isArray: field.type.isArray,
245
+ isArrayNotNull: false,
246
+ };
247
+ });
248
+ return properties;
249
+ }
250
+ /**
251
+ * Convert fields to nested properties for mutations
252
+ */
253
+ function convertFieldsToNestedProperties(fields) {
254
+ const properties = {};
255
+ fields.forEach((field) => {
256
+ properties[field.name] = {
257
+ name: field.name,
258
+ type: field.type.gqlType,
259
+ isNotNull: false, // Mutations typically allow optional fields
260
+ isArray: field.type.isArray,
261
+ isArrayNotNull: false,
262
+ };
263
+ });
264
+ return properties;
265
+ }
266
+ /**
267
+ * Create AST-based query builder for a table
268
+ */
269
+ function createASTQueryBuilder(tables) {
270
+ const metaObject = cleanTableToMetaObject(tables);
271
+ const introspectionSchema = generateIntrospectionSchema(tables);
272
+ return new query_builder_1.QueryBuilder({
273
+ meta: metaObject,
274
+ introspection: introspectionSchema,
275
+ });
276
+ }
277
+ /**
278
+ * Build a SELECT query for a table with optional filtering, sorting, and pagination
279
+ * Uses direct AST generation without intermediate conversions
280
+ */
281
+ function buildSelect(table, allTables, options = {}) {
282
+ const tableList = Array.from(allTables);
283
+ const selection = convertFieldSelectionToSelectionOptions(table, tableList, options.fieldSelection);
284
+ // Generate query directly using AST
285
+ const queryString = generateSelectQueryAST(table, tableList, selection, options);
286
+ return new typed_document_1.TypedDocumentString(queryString, {});
287
+ }
288
+ /**
289
+ * Build a single row query by primary key or unique field
290
+ */
291
+ function buildFindOne(table, _pkField = 'id') {
292
+ const queryString = generateFindOneQueryAST(table);
293
+ return new typed_document_1.TypedDocumentString(queryString, {});
294
+ }
295
+ /**
296
+ * Build a count query for a table
297
+ */
298
+ function buildCount(table) {
299
+ const queryString = generateCountQueryAST(table);
300
+ return new typed_document_1.TypedDocumentString(queryString, {});
301
+ }
302
+ function convertFieldSelectionToSelectionOptions(table, allTables, options) {
303
+ return (0, field_selector_1.convertToSelectionOptions)(table, allTables, options);
304
+ }
305
+ /**
306
+ * Generate SELECT query AST directly from CleanTable
307
+ */
308
+ function generateSelectQueryAST(table, allTables, selection, options) {
309
+ const pluralName = toCamelCasePlural(table.name);
310
+ // Generate field selections
311
+ const fieldSelections = generateFieldSelectionsFromOptions(table, allTables, selection);
312
+ // Build the query AST
313
+ const variableDefinitions = [];
314
+ const queryArgs = [];
315
+ // Add pagination variables if needed
316
+ const limitValue = options.limit ?? options.first;
317
+ if (limitValue !== undefined) {
318
+ variableDefinitions.push(t.variableDefinition({
319
+ variable: t.variable({ name: 'first' }),
320
+ type: t.namedType({ type: 'Int' }),
321
+ }));
322
+ queryArgs.push(t.argument({
323
+ name: 'first',
324
+ value: t.variable({ name: 'first' }),
325
+ }));
326
+ }
327
+ if (options.offset !== undefined) {
328
+ variableDefinitions.push(t.variableDefinition({
329
+ variable: t.variable({ name: 'offset' }),
330
+ type: t.namedType({ type: 'Int' }),
331
+ }));
332
+ queryArgs.push(t.argument({
333
+ name: 'offset',
334
+ value: t.variable({ name: 'offset' }),
335
+ }));
336
+ }
337
+ // Add cursor-based pagination variables if needed (for infinite scroll)
338
+ if (options.after !== undefined) {
339
+ variableDefinitions.push(t.variableDefinition({
340
+ variable: t.variable({ name: 'after' }),
341
+ type: t.namedType({ type: 'Cursor' }),
342
+ }));
343
+ queryArgs.push(t.argument({
344
+ name: 'after',
345
+ value: t.variable({ name: 'after' }),
346
+ }));
347
+ }
348
+ if (options.before !== undefined) {
349
+ variableDefinitions.push(t.variableDefinition({
350
+ variable: t.variable({ name: 'before' }),
351
+ type: t.namedType({ type: 'Cursor' }),
352
+ }));
353
+ queryArgs.push(t.argument({
354
+ name: 'before',
355
+ value: t.variable({ name: 'before' }),
356
+ }));
357
+ }
358
+ // Add filter variables if needed
359
+ if (options.where) {
360
+ variableDefinitions.push(t.variableDefinition({
361
+ variable: t.variable({ name: 'filter' }),
362
+ type: t.namedType({ type: `${table.name}Filter` }),
363
+ }));
364
+ queryArgs.push(t.argument({
365
+ name: 'filter',
366
+ value: t.variable({ name: 'filter' }),
367
+ }));
368
+ }
369
+ // Add orderBy variables if needed
370
+ if (options.orderBy && options.orderBy.length > 0) {
371
+ variableDefinitions.push(t.variableDefinition({
372
+ variable: t.variable({ name: 'orderBy' }),
373
+ // PostGraphile expects [ProductsOrderBy!] - list of non-null enum values
374
+ type: t.listType({
375
+ type: t.nonNullType({
376
+ type: t.namedType({ type: toOrderByTypeName(table.name) }),
377
+ }),
378
+ }),
379
+ }));
380
+ queryArgs.push(t.argument({
381
+ name: 'orderBy',
382
+ value: t.variable({ name: 'orderBy' }),
383
+ }));
384
+ }
385
+ // Build connection selections: totalCount, nodes, and optionally pageInfo
386
+ const connectionSelections = [
387
+ t.field({ name: 'totalCount' }),
388
+ t.field({
389
+ name: 'nodes',
390
+ selectionSet: t.selectionSet({
391
+ selections: fieldSelections,
392
+ }),
393
+ }),
394
+ ];
395
+ // Add pageInfo if requested (for cursor-based pagination / infinite scroll)
396
+ if (options.includePageInfo ||
397
+ options.after !== undefined ||
398
+ options.before !== undefined) {
399
+ connectionSelections.push(t.field({
400
+ name: 'pageInfo',
401
+ selectionSet: t.selectionSet({
402
+ selections: [
403
+ t.field({ name: 'hasNextPage' }),
404
+ t.field({ name: 'hasPreviousPage' }),
405
+ t.field({ name: 'startCursor' }),
406
+ t.field({ name: 'endCursor' }),
407
+ ],
408
+ }),
409
+ }));
410
+ }
411
+ const ast = t.document({
412
+ definitions: [
413
+ t.operationDefinition({
414
+ operation: 'query',
415
+ name: `${pluralName}Query`,
416
+ variableDefinitions,
417
+ selectionSet: t.selectionSet({
418
+ selections: [
419
+ t.field({
420
+ name: pluralName,
421
+ args: queryArgs,
422
+ selectionSet: t.selectionSet({
423
+ selections: connectionSelections,
424
+ }),
425
+ }),
426
+ ],
427
+ }),
428
+ }),
429
+ ],
430
+ });
431
+ return (0, graphql_1.print)(ast);
432
+ }
433
+ /**
434
+ * Generate field selections from SelectionOptions
435
+ */
436
+ function generateFieldSelectionsFromOptions(table, allTables, selection) {
437
+ const DEFAULT_NESTED_RELATION_FIRST = 20;
438
+ if (!selection) {
439
+ // Default to all non-relational fields (includes complex fields like JSON, geometry, etc.)
440
+ return table.fields
441
+ .filter((field) => !(0, field_selector_1.isRelationalField)(field.name, table))
442
+ .map((field) => {
443
+ if ((0, custom_ast_1.requiresSubfieldSelection)(field)) {
444
+ // For complex fields that require subfield selection, use custom AST generation
445
+ return (0, custom_ast_1.getCustomAstForCleanField)(field);
446
+ }
447
+ else {
448
+ // For simple fields, use basic field selection
449
+ return t.field({ name: field.name });
450
+ }
451
+ });
452
+ }
453
+ const fieldSelections = [];
454
+ Object.entries(selection).forEach(([fieldName, fieldOptions]) => {
455
+ if (fieldOptions === true) {
456
+ // Check if this field requires subfield selection
457
+ const field = table.fields.find((f) => f.name === fieldName);
458
+ if (field && (0, custom_ast_1.requiresSubfieldSelection)(field)) {
459
+ // Use custom AST generation for complex fields
460
+ fieldSelections.push((0, custom_ast_1.getCustomAstForCleanField)(field));
461
+ }
462
+ else {
463
+ // Simple field selection for scalar fields
464
+ fieldSelections.push(t.field({ name: fieldName }));
465
+ }
466
+ }
467
+ else if (typeof fieldOptions === 'object' && fieldOptions.select) {
468
+ // Nested field selection (for relation fields)
469
+ const nestedSelections = [];
470
+ // Find the related table to check for complex fields
471
+ const relatedTable = findRelatedTable(fieldName, table, allTables);
472
+ Object.entries(fieldOptions.select).forEach(([nestedField, include]) => {
473
+ if (include) {
474
+ // Check if this nested field requires subfield selection
475
+ const nestedFieldDef = relatedTable?.fields.find((f) => f.name === nestedField);
476
+ if (nestedFieldDef && (0, custom_ast_1.requiresSubfieldSelection)(nestedFieldDef)) {
477
+ // Use custom AST generation for complex nested fields
478
+ nestedSelections.push((0, custom_ast_1.getCustomAstForCleanField)(nestedFieldDef));
479
+ }
480
+ else {
481
+ // Simple field selection for scalar nested fields
482
+ nestedSelections.push(t.field({ name: nestedField }));
483
+ }
484
+ }
485
+ });
486
+ // Check if this is a hasMany relation that uses Connection pattern
487
+ const relationInfo = getRelationInfo(fieldName, table);
488
+ if (relationInfo &&
489
+ (relationInfo.type === 'hasMany' || relationInfo.type === 'manyToMany')) {
490
+ // For hasMany/manyToMany relations, wrap selections in nodes { ... }
491
+ fieldSelections.push(t.field({
492
+ name: fieldName,
493
+ args: [
494
+ t.argument({
495
+ name: 'first',
496
+ value: t.intValue({
497
+ value: DEFAULT_NESTED_RELATION_FIRST.toString(),
498
+ }),
499
+ }),
500
+ ],
501
+ selectionSet: t.selectionSet({
502
+ selections: [
503
+ t.field({
504
+ name: 'nodes',
505
+ selectionSet: t.selectionSet({
506
+ selections: nestedSelections,
507
+ }),
508
+ }),
509
+ ],
510
+ }),
511
+ }));
512
+ }
513
+ else {
514
+ // For belongsTo/hasOne relations, use direct selection
515
+ fieldSelections.push(t.field({
516
+ name: fieldName,
517
+ selectionSet: t.selectionSet({
518
+ selections: nestedSelections,
519
+ }),
520
+ }));
521
+ }
522
+ }
523
+ });
524
+ return fieldSelections;
525
+ }
526
+ /**
527
+ * Get relation information for a field
528
+ */
529
+ function getRelationInfo(fieldName, table) {
530
+ const { belongsTo, hasOne, hasMany, manyToMany } = table.relations;
531
+ // Check belongsTo relations
532
+ const belongsToRel = belongsTo.find((rel) => rel.fieldName === fieldName);
533
+ if (belongsToRel) {
534
+ return { type: 'belongsTo', relation: belongsToRel };
535
+ }
536
+ // Check hasOne relations
537
+ const hasOneRel = hasOne.find((rel) => rel.fieldName === fieldName);
538
+ if (hasOneRel) {
539
+ return { type: 'hasOne', relation: hasOneRel };
540
+ }
541
+ // Check hasMany relations
542
+ const hasManyRel = hasMany.find((rel) => rel.fieldName === fieldName);
543
+ if (hasManyRel) {
544
+ return { type: 'hasMany', relation: hasManyRel };
545
+ }
546
+ // Check manyToMany relations
547
+ const manyToManyRel = manyToMany.find((rel) => rel.fieldName === fieldName);
548
+ if (manyToManyRel) {
549
+ return { type: 'manyToMany', relation: manyToManyRel };
550
+ }
551
+ return null;
552
+ }
553
+ /**
554
+ * Find the related table for a given relation field
555
+ */
556
+ function findRelatedTable(relationField, table, allTables) {
557
+ // Find the related table name
558
+ let referencedTableName;
559
+ // Check belongsTo relations
560
+ const belongsToRel = table.relations.belongsTo.find((rel) => rel.fieldName === relationField);
561
+ if (belongsToRel) {
562
+ referencedTableName = belongsToRel.referencesTable;
563
+ }
564
+ // Check hasOne relations
565
+ if (!referencedTableName) {
566
+ const hasOneRel = table.relations.hasOne.find((rel) => rel.fieldName === relationField);
567
+ if (hasOneRel) {
568
+ referencedTableName = hasOneRel.referencedByTable;
569
+ }
570
+ }
571
+ // Check hasMany relations
572
+ if (!referencedTableName) {
573
+ const hasManyRel = table.relations.hasMany.find((rel) => rel.fieldName === relationField);
574
+ if (hasManyRel) {
575
+ referencedTableName = hasManyRel.referencedByTable;
576
+ }
577
+ }
578
+ // Check manyToMany relations
579
+ if (!referencedTableName) {
580
+ const manyToManyRel = table.relations.manyToMany.find((rel) => rel.fieldName === relationField);
581
+ if (manyToManyRel) {
582
+ referencedTableName = manyToManyRel.rightTable;
583
+ }
584
+ }
585
+ if (!referencedTableName) {
586
+ return null;
587
+ }
588
+ // Find the related table in allTables
589
+ return allTables.find((tbl) => tbl.name === referencedTableName) || null;
590
+ }
591
+ /**
592
+ * Generate FindOne query AST directly from CleanTable
593
+ */
594
+ function generateFindOneQueryAST(table) {
595
+ const singularName = inflection.camelize(table.name, true);
596
+ // Generate field selections (include all non-relational fields, including complex types)
597
+ const fieldSelections = table.fields
598
+ .filter((field) => !(0, field_selector_1.isRelationalField)(field.name, table))
599
+ .map((field) => {
600
+ if ((0, custom_ast_1.requiresSubfieldSelection)(field)) {
601
+ // For complex fields that require subfield selection, use custom AST generation
602
+ return (0, custom_ast_1.getCustomAstForCleanField)(field);
603
+ }
604
+ else {
605
+ // For simple fields, use basic field selection
606
+ return t.field({ name: field.name });
607
+ }
608
+ });
609
+ const ast = t.document({
610
+ definitions: [
611
+ t.operationDefinition({
612
+ operation: 'query',
613
+ name: `${singularName}Query`,
614
+ variableDefinitions: [
615
+ t.variableDefinition({
616
+ variable: t.variable({ name: 'id' }),
617
+ type: t.nonNullType({
618
+ type: t.namedType({ type: 'UUID' }),
619
+ }),
620
+ }),
621
+ ],
622
+ selectionSet: t.selectionSet({
623
+ selections: [
624
+ t.field({
625
+ name: singularName,
626
+ args: [
627
+ t.argument({
628
+ name: 'id',
629
+ value: t.variable({ name: 'id' }),
630
+ }),
631
+ ],
632
+ selectionSet: t.selectionSet({
633
+ selections: fieldSelections,
634
+ }),
635
+ }),
636
+ ],
637
+ }),
638
+ }),
639
+ ],
640
+ });
641
+ return (0, graphql_1.print)(ast);
642
+ }
643
+ /**
644
+ * Generate Count query AST directly from CleanTable
645
+ */
646
+ function generateCountQueryAST(table) {
647
+ const pluralName = toCamelCasePlural(table.name);
648
+ const ast = t.document({
649
+ definitions: [
650
+ t.operationDefinition({
651
+ operation: 'query',
652
+ name: `${pluralName}CountQuery`,
653
+ variableDefinitions: [
654
+ t.variableDefinition({
655
+ variable: t.variable({ name: 'filter' }),
656
+ type: t.namedType({ type: `${table.name}Filter` }),
657
+ }),
658
+ ],
659
+ selectionSet: t.selectionSet({
660
+ selections: [
661
+ t.field({
662
+ name: pluralName,
663
+ args: [
664
+ t.argument({
665
+ name: 'filter',
666
+ value: t.variable({ name: 'filter' }),
667
+ }),
668
+ ],
669
+ selectionSet: t.selectionSet({
670
+ selections: [t.field({ name: 'totalCount' })],
671
+ }),
672
+ }),
673
+ ],
674
+ }),
675
+ }),
676
+ ],
677
+ });
678
+ return (0, graphql_1.print)(ast);
679
+ }
package/index.d.ts CHANGED
@@ -1,3 +1,12 @@
1
- export * from './gql';
2
- export * from './codegen';
3
- export * from './options';
1
+ /**
2
+ * @constructive-io/graphql-codegen
3
+ *
4
+ * CLI-based GraphQL SDK generator for PostGraphile endpoints.
5
+ * Introspects via _meta query and generates typed queries, mutations,
6
+ * and React Query v5 hooks.
7
+ */
8
+ export * from './types';
9
+ export * from './core';
10
+ export * from './generators';
11
+ export * from './client';
12
+ export { defineConfig } from './types/config';