@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,163 @@
1
+ /**
2
+ * Codegen utilities - naming conventions, type mapping, and helpers
3
+ */
4
+ import type { CleanTable, CleanField, CleanFieldType } from '../../types/schema';
5
+ /** Lowercase first character */
6
+ export declare function lcFirst(str: string): string;
7
+ /** Uppercase first character */
8
+ export declare function ucFirst(str: string): string;
9
+ /** Convert to camelCase */
10
+ export declare function toCamelCase(str: string): string;
11
+ /** Convert to PascalCase */
12
+ export declare function toPascalCase(str: string): string;
13
+ /** Convert to SCREAMING_SNAKE_CASE */
14
+ export declare function toScreamingSnake(str: string): string;
15
+ export interface TableNames {
16
+ /** PascalCase singular (e.g., "Car") */
17
+ typeName: string;
18
+ /** camelCase singular (e.g., "car") */
19
+ singularName: string;
20
+ /** camelCase plural (e.g., "cars") */
21
+ pluralName: string;
22
+ /** PascalCase plural (e.g., "Cars") */
23
+ pluralTypeName: string;
24
+ }
25
+ /**
26
+ * Derive all naming variants from a table
27
+ */
28
+ export declare function getTableNames(table: CleanTable): TableNames;
29
+ /**
30
+ * Generate hook function name for list query
31
+ * e.g., "useCarsQuery"
32
+ */
33
+ export declare function getListQueryHookName(table: CleanTable): string;
34
+ /**
35
+ * Generate hook function name for single item query
36
+ * e.g., "useCarQuery"
37
+ */
38
+ export declare function getSingleQueryHookName(table: CleanTable): string;
39
+ /**
40
+ * Generate hook function name for create mutation
41
+ * e.g., "useCreateCarMutation"
42
+ */
43
+ export declare function getCreateMutationHookName(table: CleanTable): string;
44
+ /**
45
+ * Generate hook function name for update mutation
46
+ * e.g., "useUpdateCarMutation"
47
+ */
48
+ export declare function getUpdateMutationHookName(table: CleanTable): string;
49
+ /**
50
+ * Generate hook function name for delete mutation
51
+ * e.g., "useDeleteCarMutation"
52
+ */
53
+ export declare function getDeleteMutationHookName(table: CleanTable): string;
54
+ /**
55
+ * Generate file name for list query hook
56
+ * e.g., "useCarsQuery.ts"
57
+ */
58
+ export declare function getListQueryFileName(table: CleanTable): string;
59
+ /**
60
+ * Generate file name for single query hook
61
+ * e.g., "useCarQuery.ts"
62
+ */
63
+ export declare function getSingleQueryFileName(table: CleanTable): string;
64
+ /**
65
+ * Generate file name for create mutation hook
66
+ */
67
+ export declare function getCreateMutationFileName(table: CleanTable): string;
68
+ /**
69
+ * Generate file name for update mutation hook
70
+ */
71
+ export declare function getUpdateMutationFileName(table: CleanTable): string;
72
+ /**
73
+ * Generate file name for delete mutation hook
74
+ */
75
+ export declare function getDeleteMutationFileName(table: CleanTable): string;
76
+ /**
77
+ * Get the GraphQL query name for fetching all rows
78
+ * Uses inflection from _meta, falls back to convention
79
+ */
80
+ export declare function getAllRowsQueryName(table: CleanTable): string;
81
+ /**
82
+ * Get the GraphQL query name for fetching single row
83
+ */
84
+ export declare function getSingleRowQueryName(table: CleanTable): string;
85
+ /**
86
+ * Get the GraphQL mutation name for creating
87
+ */
88
+ export declare function getCreateMutationName(table: CleanTable): string;
89
+ /**
90
+ * Get the GraphQL mutation name for updating
91
+ */
92
+ export declare function getUpdateMutationName(table: CleanTable): string;
93
+ /**
94
+ * Get the GraphQL mutation name for deleting
95
+ */
96
+ export declare function getDeleteMutationName(table: CleanTable): string;
97
+ /**
98
+ * Get PostGraphile filter type name
99
+ * e.g., "CarFilter"
100
+ */
101
+ export declare function getFilterTypeName(table: CleanTable): string;
102
+ /**
103
+ * Get PostGraphile OrderBy enum type name
104
+ * e.g., "CarsOrderBy"
105
+ */
106
+ export declare function getOrderByTypeName(table: CleanTable): string;
107
+ /**
108
+ * Get PostGraphile create input type name
109
+ * e.g., "CreateCarInput"
110
+ */
111
+ export declare function getCreateInputTypeName(table: CleanTable): string;
112
+ /**
113
+ * Get PostGraphile patch type name for updates
114
+ * e.g., "CarPatch"
115
+ */
116
+ export declare function getPatchTypeName(table: CleanTable): string;
117
+ /**
118
+ * Get PostGraphile update input type name
119
+ * e.g., "UpdateCarInput"
120
+ */
121
+ export declare function getUpdateInputTypeName(table: CleanTable): string;
122
+ /**
123
+ * Get PostGraphile delete input type name
124
+ * e.g., "DeleteCarInput"
125
+ */
126
+ export declare function getDeleteInputTypeName(table: CleanTable): string;
127
+ /**
128
+ * Convert GraphQL type to TypeScript type
129
+ */
130
+ export declare function gqlTypeToTs(gqlType: string, isArray?: boolean): string;
131
+ /**
132
+ * Convert CleanFieldType to TypeScript type string
133
+ */
134
+ export declare function fieldTypeToTs(fieldType: CleanFieldType): string;
135
+ /**
136
+ * Get the PostGraphile filter type for a GraphQL scalar
137
+ */
138
+ export declare function getScalarFilterType(gqlType: string): string | null;
139
+ /**
140
+ * Check if a field is a relation field (not a scalar)
141
+ */
142
+ export declare function isRelationField(fieldName: string, table: CleanTable): boolean;
143
+ /**
144
+ * Get only scalar fields (non-relation fields)
145
+ */
146
+ export declare function getScalarFields(table: CleanTable): CleanField[];
147
+ /**
148
+ * Get primary key field names
149
+ */
150
+ export declare function getPrimaryKeyFields(table: CleanTable): string[];
151
+ /**
152
+ * Generate query key prefix for a table
153
+ * e.g., "cars" for list queries, "car" for detail queries
154
+ */
155
+ export declare function getQueryKeyPrefix(table: CleanTable): string;
156
+ /**
157
+ * Generate a doc comment header for generated files
158
+ */
159
+ export declare function getGeneratedFileHeader(description: string): string;
160
+ /**
161
+ * Indent a multi-line string
162
+ */
163
+ export declare function indent(str: string, spaces?: number): string;
@@ -0,0 +1,288 @@
1
+ import { scalarToTsType, scalarToFilterType } from './scalars';
2
+ // ============================================================================
3
+ // String manipulation
4
+ // ============================================================================
5
+ /** Lowercase first character */
6
+ export function lcFirst(str) {
7
+ return str.charAt(0).toLowerCase() + str.slice(1);
8
+ }
9
+ /** Uppercase first character */
10
+ export function ucFirst(str) {
11
+ return str.charAt(0).toUpperCase() + str.slice(1);
12
+ }
13
+ /** Convert to camelCase */
14
+ export function toCamelCase(str) {
15
+ return str
16
+ .replace(/[-_](.)/g, (_, char) => char.toUpperCase())
17
+ .replace(/^(.)/, (_, char) => char.toLowerCase());
18
+ }
19
+ /** Convert to PascalCase */
20
+ export function toPascalCase(str) {
21
+ return str
22
+ .replace(/[-_](.)/g, (_, char) => char.toUpperCase())
23
+ .replace(/^(.)/, (_, char) => char.toUpperCase());
24
+ }
25
+ /** Convert to SCREAMING_SNAKE_CASE */
26
+ export function toScreamingSnake(str) {
27
+ return str
28
+ .replace(/([A-Z])/g, '_$1')
29
+ .replace(/[-\s]/g, '_')
30
+ .toUpperCase()
31
+ .replace(/^_/, '');
32
+ }
33
+ /**
34
+ * Derive all naming variants from a table
35
+ */
36
+ export function getTableNames(table) {
37
+ const typeName = table.name;
38
+ const singularName = table.inflection?.tableFieldName || lcFirst(typeName);
39
+ const pluralName = table.query?.all || table.inflection?.allRows || singularName + 's';
40
+ const pluralTypeName = ucFirst(pluralName);
41
+ return {
42
+ typeName,
43
+ singularName,
44
+ pluralName,
45
+ pluralTypeName,
46
+ };
47
+ }
48
+ /**
49
+ * Generate hook function name for list query
50
+ * e.g., "useCarsQuery"
51
+ */
52
+ export function getListQueryHookName(table) {
53
+ const { pluralName } = getTableNames(table);
54
+ return `use${ucFirst(pluralName)}Query`;
55
+ }
56
+ /**
57
+ * Generate hook function name for single item query
58
+ * e.g., "useCarQuery"
59
+ */
60
+ export function getSingleQueryHookName(table) {
61
+ const { singularName } = getTableNames(table);
62
+ return `use${ucFirst(singularName)}Query`;
63
+ }
64
+ /**
65
+ * Generate hook function name for create mutation
66
+ * e.g., "useCreateCarMutation"
67
+ */
68
+ export function getCreateMutationHookName(table) {
69
+ const { typeName } = getTableNames(table);
70
+ return `useCreate${typeName}Mutation`;
71
+ }
72
+ /**
73
+ * Generate hook function name for update mutation
74
+ * e.g., "useUpdateCarMutation"
75
+ */
76
+ export function getUpdateMutationHookName(table) {
77
+ const { typeName } = getTableNames(table);
78
+ return `useUpdate${typeName}Mutation`;
79
+ }
80
+ /**
81
+ * Generate hook function name for delete mutation
82
+ * e.g., "useDeleteCarMutation"
83
+ */
84
+ export function getDeleteMutationHookName(table) {
85
+ const { typeName } = getTableNames(table);
86
+ return `useDelete${typeName}Mutation`;
87
+ }
88
+ /**
89
+ * Generate file name for list query hook
90
+ * e.g., "useCarsQuery.ts"
91
+ */
92
+ export function getListQueryFileName(table) {
93
+ return `${getListQueryHookName(table)}.ts`;
94
+ }
95
+ /**
96
+ * Generate file name for single query hook
97
+ * e.g., "useCarQuery.ts"
98
+ */
99
+ export function getSingleQueryFileName(table) {
100
+ return `${getSingleQueryHookName(table)}.ts`;
101
+ }
102
+ /**
103
+ * Generate file name for create mutation hook
104
+ */
105
+ export function getCreateMutationFileName(table) {
106
+ return `${getCreateMutationHookName(table)}.ts`;
107
+ }
108
+ /**
109
+ * Generate file name for update mutation hook
110
+ */
111
+ export function getUpdateMutationFileName(table) {
112
+ return `${getUpdateMutationHookName(table)}.ts`;
113
+ }
114
+ /**
115
+ * Generate file name for delete mutation hook
116
+ */
117
+ export function getDeleteMutationFileName(table) {
118
+ return `${getDeleteMutationHookName(table)}.ts`;
119
+ }
120
+ // ============================================================================
121
+ // GraphQL operation names
122
+ // ============================================================================
123
+ /**
124
+ * Get the GraphQL query name for fetching all rows
125
+ * Uses inflection from _meta, falls back to convention
126
+ */
127
+ export function getAllRowsQueryName(table) {
128
+ return table.query?.all || table.inflection?.allRows || lcFirst(table.name) + 's';
129
+ }
130
+ /**
131
+ * Get the GraphQL query name for fetching single row
132
+ */
133
+ export function getSingleRowQueryName(table) {
134
+ return table.query?.one || table.inflection?.tableFieldName || lcFirst(table.name);
135
+ }
136
+ /**
137
+ * Get the GraphQL mutation name for creating
138
+ */
139
+ export function getCreateMutationName(table) {
140
+ return table.query?.create || `create${table.name}`;
141
+ }
142
+ /**
143
+ * Get the GraphQL mutation name for updating
144
+ */
145
+ export function getUpdateMutationName(table) {
146
+ return table.query?.update || `update${table.name}`;
147
+ }
148
+ /**
149
+ * Get the GraphQL mutation name for deleting
150
+ */
151
+ export function getDeleteMutationName(table) {
152
+ return table.query?.delete || `delete${table.name}`;
153
+ }
154
+ // ============================================================================
155
+ // Type names
156
+ // ============================================================================
157
+ /**
158
+ * Get PostGraphile filter type name
159
+ * e.g., "CarFilter"
160
+ */
161
+ export function getFilterTypeName(table) {
162
+ return table.inflection?.filterType || `${table.name}Filter`;
163
+ }
164
+ /**
165
+ * Get PostGraphile OrderBy enum type name
166
+ * e.g., "CarsOrderBy"
167
+ */
168
+ export function getOrderByTypeName(table) {
169
+ return table.inflection?.orderByType || `${table.name}sOrderBy`;
170
+ }
171
+ /**
172
+ * Get PostGraphile create input type name
173
+ * e.g., "CreateCarInput"
174
+ */
175
+ export function getCreateInputTypeName(table) {
176
+ return table.inflection?.createInputType || `Create${table.name}Input`;
177
+ }
178
+ /**
179
+ * Get PostGraphile patch type name for updates
180
+ * e.g., "CarPatch"
181
+ */
182
+ export function getPatchTypeName(table) {
183
+ return table.inflection?.patchType || `${table.name}Patch`;
184
+ }
185
+ /**
186
+ * Get PostGraphile update input type name
187
+ * e.g., "UpdateCarInput"
188
+ */
189
+ export function getUpdateInputTypeName(table) {
190
+ return `Update${table.name}Input`;
191
+ }
192
+ /**
193
+ * Get PostGraphile delete input type name
194
+ * e.g., "DeleteCarInput"
195
+ */
196
+ export function getDeleteInputTypeName(table) {
197
+ return `Delete${table.name}Input`;
198
+ }
199
+ // ============================================================================
200
+ // Type mapping: GraphQL → TypeScript
201
+ // ============================================================================
202
+ /**
203
+ * Convert GraphQL type to TypeScript type
204
+ */
205
+ export function gqlTypeToTs(gqlType, isArray = false) {
206
+ // Remove non-null markers
207
+ const cleanType = gqlType.replace(/!/g, '');
208
+ // Look up in map, fallback to the type name itself (custom type)
209
+ const tsType = scalarToTsType(cleanType, { unknownScalar: 'name' });
210
+ return isArray ? `${tsType}[]` : tsType;
211
+ }
212
+ /**
213
+ * Convert CleanFieldType to TypeScript type string
214
+ */
215
+ export function fieldTypeToTs(fieldType) {
216
+ return gqlTypeToTs(fieldType.gqlType, fieldType.isArray);
217
+ }
218
+ // ============================================================================
219
+ // Type mapping: GraphQL → Filter type
220
+ // ============================================================================
221
+ /**
222
+ * Get the PostGraphile filter type for a GraphQL scalar
223
+ */
224
+ export function getScalarFilterType(gqlType) {
225
+ const cleanType = gqlType.replace(/!/g, '');
226
+ return scalarToFilterType(cleanType);
227
+ }
228
+ // ============================================================================
229
+ // Field filtering utilities
230
+ // ============================================================================
231
+ /**
232
+ * Check if a field is a relation field (not a scalar)
233
+ */
234
+ export function isRelationField(fieldName, table) {
235
+ const { belongsTo, hasOne, hasMany, manyToMany } = table.relations;
236
+ return (belongsTo.some((r) => r.fieldName === fieldName) ||
237
+ hasOne.some((r) => r.fieldName === fieldName) ||
238
+ hasMany.some((r) => r.fieldName === fieldName) ||
239
+ manyToMany.some((r) => r.fieldName === fieldName));
240
+ }
241
+ /**
242
+ * Get only scalar fields (non-relation fields)
243
+ */
244
+ export function getScalarFields(table) {
245
+ return table.fields.filter((f) => !isRelationField(f.name, table));
246
+ }
247
+ /**
248
+ * Get primary key field names
249
+ */
250
+ export function getPrimaryKeyFields(table) {
251
+ const pk = table.constraints?.primaryKey?.[0];
252
+ if (!pk)
253
+ return ['id']; // Default assumption
254
+ return pk.fields.map((f) => f.name);
255
+ }
256
+ // ============================================================================
257
+ // Query key generation
258
+ // ============================================================================
259
+ /**
260
+ * Generate query key prefix for a table
261
+ * e.g., "cars" for list queries, "car" for detail queries
262
+ */
263
+ export function getQueryKeyPrefix(table) {
264
+ return lcFirst(table.name);
265
+ }
266
+ // ============================================================================
267
+ // Code generation helpers
268
+ // ============================================================================
269
+ /**
270
+ * Generate a doc comment header for generated files
271
+ */
272
+ export function getGeneratedFileHeader(description) {
273
+ return `/**
274
+ * ${description}
275
+ * @generated by @constructive-io/graphql-codegen
276
+ * DO NOT EDIT - changes will be overwritten
277
+ */`;
278
+ }
279
+ /**
280
+ * Indent a multi-line string
281
+ */
282
+ export function indent(str, spaces = 2) {
283
+ const pad = ' '.repeat(spaces);
284
+ return str
285
+ .split('\n')
286
+ .map((line) => (line.trim() ? pad + line : line))
287
+ .join('\n');
288
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Generate ORM command - generates Prisma-like ORM client
3
+ *
4
+ * This command:
5
+ * 1. Fetches _meta query for table-based CRUD operations
6
+ * 2. Fetches __schema introspection for custom operations
7
+ * 3. Generates a Prisma-like ORM client with fluent API
8
+ */
9
+ export interface GenerateOrmOptions {
10
+ /** Path to config file */
11
+ config?: string;
12
+ /** GraphQL endpoint URL (overrides config) */
13
+ endpoint?: string;
14
+ /** Output directory (overrides config) */
15
+ output?: string;
16
+ /** Authorization header */
17
+ authorization?: string;
18
+ /** Verbose output */
19
+ verbose?: boolean;
20
+ /** Dry run - don't write files */
21
+ dryRun?: boolean;
22
+ /** Skip custom operations (only generate table CRUD) */
23
+ skipCustomOperations?: boolean;
24
+ }
25
+ export interface GenerateOrmResult {
26
+ success: boolean;
27
+ message: string;
28
+ tables?: string[];
29
+ customQueries?: string[];
30
+ customMutations?: string[];
31
+ filesWritten?: string[];
32
+ errors?: string[];
33
+ }
34
+ /**
35
+ * Execute the generate-orm command
36
+ */
37
+ export declare function generateOrmCommand(options?: GenerateOrmOptions): Promise<GenerateOrmResult>;
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Generate ORM command - generates Prisma-like ORM client
3
+ *
4
+ * This command:
5
+ * 1. Fetches _meta query for table-based CRUD operations
6
+ * 2. Fetches __schema introspection for custom operations
7
+ * 3. Generates a Prisma-like ORM client with fluent API
8
+ */
9
+ import { resolveConfig } from '../../types/config';
10
+ import { fetchMeta, validateEndpoint } from '../introspect/fetch-meta';
11
+ import { fetchSchema } from '../introspect/fetch-schema';
12
+ import { transformMetaToCleanTables, filterTables, } from '../introspect/transform';
13
+ import { transformSchemaToOperations, filterOperations, getTableOperationNames, getCustomOperations, } from '../introspect/transform-schema';
14
+ import { findConfigFile, loadConfigFile } from './init';
15
+ import { writeGeneratedFiles } from './generate';
16
+ import { generateOrm } from '../codegen/orm';
17
+ /**
18
+ * Execute the generate-orm command
19
+ */
20
+ export async function generateOrmCommand(options = {}) {
21
+ const log = options.verbose ? console.log : () => { };
22
+ // 1. Load config
23
+ log('Loading configuration...');
24
+ const configResult = await loadConfig(options);
25
+ if (!configResult.success) {
26
+ return {
27
+ success: false,
28
+ message: configResult.error,
29
+ };
30
+ }
31
+ const config = configResult.config;
32
+ // Use ORM output directory if specified, otherwise default
33
+ const outputDir = options.output || config.orm?.output || './generated/orm';
34
+ log(` Endpoint: ${config.endpoint}`);
35
+ log(` Output: ${outputDir}`);
36
+ // 2. Validate endpoint
37
+ const endpointValidation = validateEndpoint(config.endpoint);
38
+ if (!endpointValidation.valid) {
39
+ return {
40
+ success: false,
41
+ message: `Invalid endpoint: ${endpointValidation.error}`,
42
+ };
43
+ }
44
+ // Build authorization header if provided
45
+ const authHeader = options.authorization || config.headers['Authorization'];
46
+ // 3. Fetch _meta for table-based operations
47
+ log('Fetching schema metadata (_meta)...');
48
+ const metaResult = await fetchMeta({
49
+ endpoint: config.endpoint,
50
+ authorization: authHeader,
51
+ headers: config.headers,
52
+ timeout: 30000,
53
+ });
54
+ if (!metaResult.success) {
55
+ return {
56
+ success: false,
57
+ message: `Failed to fetch _meta: ${metaResult.error}`,
58
+ };
59
+ }
60
+ // 4. Transform to CleanTable[]
61
+ log('Transforming table schema...');
62
+ let tables = transformMetaToCleanTables(metaResult.data);
63
+ log(` Found ${tables.length} tables`);
64
+ // 5. Filter tables
65
+ tables = filterTables(tables, config.tables.include, config.tables.exclude);
66
+ log(` After filtering: ${tables.length} tables`);
67
+ if (tables.length === 0) {
68
+ return {
69
+ success: false,
70
+ message: 'No tables found after filtering. Check your include/exclude patterns.',
71
+ };
72
+ }
73
+ // Get table operation names for filtering custom operations
74
+ const tableOperationNames = getTableOperationNames(tables);
75
+ // 6. Fetch __schema for custom operations (unless skipped)
76
+ let customQueries = [];
77
+ let customMutations = [];
78
+ let customOperationsData;
79
+ if (!options.skipCustomOperations) {
80
+ log('Fetching schema introspection (__schema)...');
81
+ const schemaResult = await fetchSchema({
82
+ endpoint: config.endpoint,
83
+ authorization: authHeader,
84
+ headers: config.headers,
85
+ timeout: 30000,
86
+ });
87
+ if (schemaResult.success && schemaResult.data) {
88
+ log('Transforming custom operations...');
89
+ // Transform to CleanOperation[]
90
+ const { queries: allQueries, mutations: allMutations, typeRegistry } = transformSchemaToOperations(schemaResult.data);
91
+ log(` Found ${allQueries.length} queries and ${allMutations.length} mutations total`);
92
+ // Filter by config include/exclude
93
+ const filteredQueries = filterOperations(allQueries, config.queries.include, config.queries.exclude);
94
+ const filteredMutations = filterOperations(allMutations, config.mutations.include, config.mutations.exclude);
95
+ log(` After config filtering: ${filteredQueries.length} queries, ${filteredMutations.length} mutations`);
96
+ // Remove table operations (already handled by table generators)
97
+ const customQueriesOps = getCustomOperations(filteredQueries, tableOperationNames);
98
+ const customMutationsOps = getCustomOperations(filteredMutations, tableOperationNames);
99
+ log(` Custom operations: ${customQueriesOps.length} queries, ${customMutationsOps.length} mutations`);
100
+ customQueries = customQueriesOps.map((q) => q.name);
101
+ customMutations = customMutationsOps.map((m) => m.name);
102
+ customOperationsData = {
103
+ queries: customQueriesOps,
104
+ mutations: customMutationsOps,
105
+ typeRegistry,
106
+ };
107
+ }
108
+ else {
109
+ log(` Warning: Could not fetch __schema: ${schemaResult.error}`);
110
+ log(' Continuing with table-only generation...');
111
+ }
112
+ }
113
+ // 7. Generate ORM code
114
+ log('Generating ORM client...');
115
+ const { files: generatedFiles, stats } = generateOrm({
116
+ tables,
117
+ customOperations: customOperationsData,
118
+ config,
119
+ });
120
+ log(` Generated ${stats.tables} table models`);
121
+ log(` Generated ${stats.customQueries} custom query operations`);
122
+ log(` Generated ${stats.customMutations} custom mutation operations`);
123
+ log(` Total files: ${stats.totalFiles}`);
124
+ if (options.dryRun) {
125
+ return {
126
+ success: true,
127
+ message: `Dry run complete. Would generate ${generatedFiles.length} files for ${tables.length} tables and ${customQueries.length + customMutations.length} custom operations.`,
128
+ tables: tables.map((t) => t.name),
129
+ customQueries,
130
+ customMutations,
131
+ filesWritten: generatedFiles.map((f) => f.path),
132
+ };
133
+ }
134
+ // 8. Write files
135
+ log('Writing files...');
136
+ const writeResult = await writeGeneratedFiles(generatedFiles, outputDir, ['models', 'query', 'mutation']);
137
+ if (!writeResult.success) {
138
+ return {
139
+ success: false,
140
+ message: `Failed to write files: ${writeResult.errors?.join(', ')}`,
141
+ errors: writeResult.errors,
142
+ };
143
+ }
144
+ const totalOps = customQueries.length + customMutations.length;
145
+ const customOpsMsg = totalOps > 0 ? ` and ${totalOps} custom operations` : '';
146
+ return {
147
+ success: true,
148
+ message: `Generated ORM client for ${tables.length} tables${customOpsMsg}. Files written to ${outputDir}`,
149
+ tables: tables.map((t) => t.name),
150
+ customQueries,
151
+ customMutations,
152
+ filesWritten: writeResult.filesWritten,
153
+ };
154
+ }
155
+ async function loadConfig(options) {
156
+ // Find config file
157
+ let configPath = options.config;
158
+ if (!configPath) {
159
+ configPath = findConfigFile() ?? undefined;
160
+ }
161
+ let baseConfig = {};
162
+ if (configPath) {
163
+ const loadResult = await loadConfigFile(configPath);
164
+ if (!loadResult.success) {
165
+ return { success: false, error: loadResult.error };
166
+ }
167
+ baseConfig = loadResult.config;
168
+ }
169
+ // Override with CLI options
170
+ const mergedConfig = {
171
+ endpoint: options.endpoint || baseConfig.endpoint || '',
172
+ output: options.output || baseConfig.output,
173
+ headers: baseConfig.headers,
174
+ tables: baseConfig.tables,
175
+ queries: baseConfig.queries,
176
+ mutations: baseConfig.mutations,
177
+ excludeFields: baseConfig.excludeFields,
178
+ hooks: baseConfig.hooks,
179
+ postgraphile: baseConfig.postgraphile,
180
+ codegen: baseConfig.codegen,
181
+ orm: baseConfig.orm,
182
+ };
183
+ if (!mergedConfig.endpoint) {
184
+ return {
185
+ success: false,
186
+ error: 'No endpoint specified. Use --endpoint or create a config file with "graphql-codegen init".',
187
+ };
188
+ }
189
+ // Resolve with defaults
190
+ const config = resolveConfig(mergedConfig);
191
+ return { success: true, config };
192
+ }