@constructive-io/graphql-codegen 2.31.0 → 3.0.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 (270) hide show
  1. package/README.md +429 -1691
  2. package/cli/index.d.ts +5 -2
  3. package/cli/index.js +98 -581
  4. package/cli/shared.d.ts +35 -0
  5. package/cli/shared.js +106 -0
  6. package/{esm/cli → core}/codegen/barrel.d.ts +1 -1
  7. package/{cli → core}/codegen/barrel.js +1 -4
  8. package/{esm/cli → core}/codegen/index.d.ts +15 -5
  9. package/{cli → core}/codegen/index.js +44 -24
  10. package/{cli → core}/codegen/invalidation.d.ts +2 -2
  11. package/{esm/cli → core}/codegen/mutation-keys.d.ts +2 -2
  12. package/{cli → core}/codegen/orm/client-generator.js +2 -3
  13. package/{esm/cli → core}/codegen/orm/index.d.ts +9 -2
  14. package/{cli → core}/codegen/orm/index.js +3 -2
  15. package/{cli → core}/codegen/query-keys.d.ts +2 -2
  16. package/core/codegen/shared/index.d.ts +39 -0
  17. package/core/codegen/shared/index.js +118 -0
  18. package/core/config/index.d.ts +5 -0
  19. package/core/config/index.js +13 -0
  20. package/core/config/loader.d.ts +18 -0
  21. package/{cli/commands/init.js → core/config/loader.js} +7 -94
  22. package/core/config/resolver.d.ts +46 -0
  23. package/core/config/resolver.js +104 -0
  24. package/core/database/index.d.ts +43 -0
  25. package/core/database/index.js +85 -0
  26. package/core/generate.d.ts +22 -0
  27. package/core/generate.js +192 -0
  28. package/core/index.d.ts +13 -1
  29. package/core/index.js +22 -2
  30. package/{cli → core}/introspect/fetch-schema.js +58 -9
  31. package/core/introspect/source/api-schemas.d.ts +44 -0
  32. package/core/introspect/source/api-schemas.js +122 -0
  33. package/core/introspect/source/database.d.ts +32 -0
  34. package/core/introspect/source/database.js +91 -0
  35. package/core/introspect/source/index.d.ts +112 -0
  36. package/core/introspect/source/index.js +173 -0
  37. package/core/introspect/source/pgpm-module.d.ts +83 -0
  38. package/core/introspect/source/pgpm-module.js +200 -0
  39. package/core/output/index.d.ts +4 -0
  40. package/core/output/index.js +9 -0
  41. package/core/output/writer.d.ts +38 -0
  42. package/core/output/writer.js +156 -0
  43. package/{cli/commands/shared.d.ts → core/pipeline/index.d.ts} +5 -3
  44. package/{cli/commands/shared.js → core/pipeline/index.js} +12 -5
  45. package/{cli → core}/watch/orchestrator.d.ts +25 -3
  46. package/{cli → core}/watch/orchestrator.js +35 -27
  47. package/{cli → core}/watch/types.d.ts +1 -1
  48. package/esm/cli/index.d.ts +5 -2
  49. package/esm/cli/index.js +97 -547
  50. package/esm/cli/shared.d.ts +35 -0
  51. package/esm/cli/shared.js +101 -0
  52. package/{cli → esm/core}/codegen/barrel.d.ts +1 -1
  53. package/esm/{cli → core}/codegen/barrel.js +1 -4
  54. package/{cli → esm/core}/codegen/index.d.ts +15 -5
  55. package/esm/{cli → core}/codegen/index.js +44 -24
  56. package/esm/{cli → core}/codegen/invalidation.d.ts +2 -2
  57. package/{cli → esm/core}/codegen/mutation-keys.d.ts +2 -2
  58. package/esm/{cli → core}/codegen/orm/client-generator.js +2 -3
  59. package/{cli → esm/core}/codegen/orm/index.d.ts +9 -2
  60. package/esm/{cli → core}/codegen/orm/index.js +3 -2
  61. package/esm/{cli → core}/codegen/query-keys.d.ts +2 -2
  62. package/esm/core/codegen/shared/index.d.ts +39 -0
  63. package/esm/core/codegen/shared/index.js +79 -0
  64. package/esm/core/config/index.d.ts +5 -0
  65. package/esm/core/config/index.js +5 -0
  66. package/esm/core/config/loader.d.ts +18 -0
  67. package/esm/core/config/loader.js +71 -0
  68. package/esm/core/config/resolver.d.ts +46 -0
  69. package/esm/core/config/resolver.js +100 -0
  70. package/esm/core/database/index.d.ts +43 -0
  71. package/esm/core/database/index.js +48 -0
  72. package/esm/core/generate.d.ts +22 -0
  73. package/esm/core/generate.js +186 -0
  74. package/esm/core/index.d.ts +13 -1
  75. package/esm/core/index.js +20 -1
  76. package/esm/{cli → core}/introspect/fetch-schema.js +55 -9
  77. package/esm/core/introspect/source/api-schemas.d.ts +44 -0
  78. package/esm/core/introspect/source/api-schemas.js +117 -0
  79. package/esm/core/introspect/source/database.d.ts +32 -0
  80. package/esm/core/introspect/source/database.js +87 -0
  81. package/esm/core/introspect/source/index.d.ts +112 -0
  82. package/esm/core/introspect/source/index.js +154 -0
  83. package/esm/core/introspect/source/pgpm-module.d.ts +83 -0
  84. package/esm/core/introspect/source/pgpm-module.js +194 -0
  85. package/esm/core/output/index.d.ts +4 -0
  86. package/esm/core/output/index.js +4 -0
  87. package/esm/core/output/writer.d.ts +38 -0
  88. package/esm/core/output/writer.js +119 -0
  89. package/esm/{cli/commands/shared.d.ts → core/pipeline/index.d.ts} +5 -3
  90. package/esm/{cli/commands/shared.js → core/pipeline/index.js} +9 -5
  91. package/esm/{cli → core}/watch/orchestrator.d.ts +25 -3
  92. package/esm/{cli → core}/watch/orchestrator.js +35 -27
  93. package/esm/{cli → core}/watch/types.d.ts +1 -1
  94. package/esm/index.d.ts +8 -3
  95. package/esm/index.js +9 -3
  96. package/esm/types/config.d.ts +110 -136
  97. package/esm/types/config.js +23 -148
  98. package/esm/types/index.d.ts +2 -2
  99. package/esm/types/index.js +1 -1
  100. package/index.d.ts +8 -3
  101. package/index.js +18 -8
  102. package/package.json +19 -11
  103. package/types/config.d.ts +110 -136
  104. package/types/config.js +28 -152
  105. package/types/index.d.ts +2 -2
  106. package/types/index.js +3 -3
  107. package/cli/commands/generate-orm.d.ts +0 -53
  108. package/cli/commands/generate-orm.js +0 -292
  109. package/cli/commands/generate.d.ts +0 -66
  110. package/cli/commands/generate.js +0 -431
  111. package/cli/commands/index.d.ts +0 -9
  112. package/cli/commands/index.js +0 -14
  113. package/cli/commands/init.d.ts +0 -35
  114. package/cli/introspect/source/index.d.ts +0 -48
  115. package/cli/introspect/source/index.js +0 -72
  116. package/esm/cli/commands/generate-orm.d.ts +0 -53
  117. package/esm/cli/commands/generate-orm.js +0 -289
  118. package/esm/cli/commands/generate.d.ts +0 -66
  119. package/esm/cli/commands/generate.js +0 -393
  120. package/esm/cli/commands/index.d.ts +0 -9
  121. package/esm/cli/commands/index.js +0 -6
  122. package/esm/cli/commands/init.d.ts +0 -35
  123. package/esm/cli/commands/init.js +0 -158
  124. package/esm/cli/introspect/source/index.d.ts +0 -48
  125. package/esm/cli/introspect/source/index.js +0 -54
  126. /package/{cli → core}/codegen/babel-ast.d.ts +0 -0
  127. /package/{cli → core}/codegen/babel-ast.js +0 -0
  128. /package/{cli → core}/codegen/client.d.ts +0 -0
  129. /package/{cli → core}/codegen/client.js +0 -0
  130. /package/{cli → core}/codegen/custom-mutations.d.ts +0 -0
  131. /package/{cli → core}/codegen/custom-mutations.js +0 -0
  132. /package/{cli → core}/codegen/custom-queries.d.ts +0 -0
  133. /package/{cli → core}/codegen/custom-queries.js +0 -0
  134. /package/{cli → core}/codegen/gql-ast.d.ts +0 -0
  135. /package/{cli → core}/codegen/gql-ast.js +0 -0
  136. /package/{cli → core}/codegen/invalidation.js +0 -0
  137. /package/{cli → core}/codegen/mutation-keys.js +0 -0
  138. /package/{cli → core}/codegen/mutations.d.ts +0 -0
  139. /package/{cli → core}/codegen/mutations.js +0 -0
  140. /package/{cli → core}/codegen/orm/barrel.d.ts +0 -0
  141. /package/{cli → core}/codegen/orm/barrel.js +0 -0
  142. /package/{cli → core}/codegen/orm/client-generator.d.ts +0 -0
  143. /package/{cli → core}/codegen/orm/client.d.ts +0 -0
  144. /package/{cli → core}/codegen/orm/client.js +0 -0
  145. /package/{cli → core}/codegen/orm/custom-ops-generator.d.ts +0 -0
  146. /package/{cli → core}/codegen/orm/custom-ops-generator.js +0 -0
  147. /package/{cli → core}/codegen/orm/input-types-generator.d.ts +0 -0
  148. /package/{cli → core}/codegen/orm/input-types-generator.js +0 -0
  149. /package/{cli → core}/codegen/orm/model-generator.d.ts +0 -0
  150. /package/{cli → core}/codegen/orm/model-generator.js +0 -0
  151. /package/{cli → core}/codegen/orm/query-builder.d.ts +0 -0
  152. /package/{cli → core}/codegen/orm/query-builder.js +0 -0
  153. /package/{cli → core}/codegen/orm/query-builder.ts +0 -0
  154. /package/{cli → core}/codegen/orm/select-types.d.ts +0 -0
  155. /package/{cli → core}/codegen/orm/select-types.js +0 -0
  156. /package/{cli → core}/codegen/queries.d.ts +0 -0
  157. /package/{cli → core}/codegen/queries.js +0 -0
  158. /package/{cli → core}/codegen/query-keys.js +0 -0
  159. /package/{cli → core}/codegen/scalars.d.ts +0 -0
  160. /package/{cli → core}/codegen/scalars.js +0 -0
  161. /package/{cli → core}/codegen/schema-gql-ast.d.ts +0 -0
  162. /package/{cli → core}/codegen/schema-gql-ast.js +0 -0
  163. /package/{cli → core}/codegen/schema-types-generator.d.ts +0 -0
  164. /package/{cli → core}/codegen/schema-types-generator.js +0 -0
  165. /package/{cli → core}/codegen/type-resolver.d.ts +0 -0
  166. /package/{cli → core}/codegen/type-resolver.js +0 -0
  167. /package/{cli → core}/codegen/types.d.ts +0 -0
  168. /package/{cli → core}/codegen/types.js +0 -0
  169. /package/{cli → core}/codegen/utils.d.ts +0 -0
  170. /package/{cli → core}/codegen/utils.js +0 -0
  171. /package/{cli → core}/introspect/fetch-schema.d.ts +0 -0
  172. /package/{cli → core}/introspect/index.d.ts +0 -0
  173. /package/{cli → core}/introspect/index.js +0 -0
  174. /package/{cli → core}/introspect/infer-tables.d.ts +0 -0
  175. /package/{cli → core}/introspect/infer-tables.js +0 -0
  176. /package/{cli → core}/introspect/schema-query.d.ts +0 -0
  177. /package/{cli → core}/introspect/schema-query.js +0 -0
  178. /package/{cli → core}/introspect/source/endpoint.d.ts +0 -0
  179. /package/{cli → core}/introspect/source/endpoint.js +0 -0
  180. /package/{cli → core}/introspect/source/file.d.ts +0 -0
  181. /package/{cli → core}/introspect/source/file.js +0 -0
  182. /package/{cli → core}/introspect/source/types.d.ts +0 -0
  183. /package/{cli → core}/introspect/source/types.js +0 -0
  184. /package/{cli → core}/introspect/transform-schema.d.ts +0 -0
  185. /package/{cli → core}/introspect/transform-schema.js +0 -0
  186. /package/{cli → core}/introspect/transform.d.ts +0 -0
  187. /package/{cli → core}/introspect/transform.js +0 -0
  188. /package/{cli → core}/watch/cache.d.ts +0 -0
  189. /package/{cli → core}/watch/cache.js +0 -0
  190. /package/{cli → core}/watch/debounce.d.ts +0 -0
  191. /package/{cli → core}/watch/debounce.js +0 -0
  192. /package/{cli → core}/watch/hash.d.ts +0 -0
  193. /package/{cli → core}/watch/hash.js +0 -0
  194. /package/{cli → core}/watch/index.d.ts +0 -0
  195. /package/{cli → core}/watch/index.js +0 -0
  196. /package/{cli → core}/watch/poller.d.ts +0 -0
  197. /package/{cli → core}/watch/poller.js +0 -0
  198. /package/{cli → core}/watch/types.js +0 -0
  199. /package/esm/{cli → core}/codegen/babel-ast.d.ts +0 -0
  200. /package/esm/{cli → core}/codegen/babel-ast.js +0 -0
  201. /package/esm/{cli → core}/codegen/client.d.ts +0 -0
  202. /package/esm/{cli → core}/codegen/client.js +0 -0
  203. /package/esm/{cli → core}/codegen/custom-mutations.d.ts +0 -0
  204. /package/esm/{cli → core}/codegen/custom-mutations.js +0 -0
  205. /package/esm/{cli → core}/codegen/custom-queries.d.ts +0 -0
  206. /package/esm/{cli → core}/codegen/custom-queries.js +0 -0
  207. /package/esm/{cli → core}/codegen/gql-ast.d.ts +0 -0
  208. /package/esm/{cli → core}/codegen/gql-ast.js +0 -0
  209. /package/esm/{cli → core}/codegen/invalidation.js +0 -0
  210. /package/esm/{cli → core}/codegen/mutation-keys.js +0 -0
  211. /package/esm/{cli → core}/codegen/mutations.d.ts +0 -0
  212. /package/esm/{cli → core}/codegen/mutations.js +0 -0
  213. /package/esm/{cli → core}/codegen/orm/barrel.d.ts +0 -0
  214. /package/esm/{cli → core}/codegen/orm/barrel.js +0 -0
  215. /package/esm/{cli → core}/codegen/orm/client-generator.d.ts +0 -0
  216. /package/esm/{cli → core}/codegen/orm/client.d.ts +0 -0
  217. /package/esm/{cli → core}/codegen/orm/client.js +0 -0
  218. /package/esm/{cli → core}/codegen/orm/custom-ops-generator.d.ts +0 -0
  219. /package/esm/{cli → core}/codegen/orm/custom-ops-generator.js +0 -0
  220. /package/esm/{cli → core}/codegen/orm/input-types-generator.d.ts +0 -0
  221. /package/esm/{cli → core}/codegen/orm/input-types-generator.js +0 -0
  222. /package/esm/{cli → core}/codegen/orm/model-generator.d.ts +0 -0
  223. /package/esm/{cli → core}/codegen/orm/model-generator.js +0 -0
  224. /package/esm/{cli → core}/codegen/orm/query-builder.d.ts +0 -0
  225. /package/esm/{cli → core}/codegen/orm/query-builder.js +0 -0
  226. /package/esm/{cli → core}/codegen/orm/select-types.d.ts +0 -0
  227. /package/esm/{cli → core}/codegen/orm/select-types.js +0 -0
  228. /package/esm/{cli → core}/codegen/queries.d.ts +0 -0
  229. /package/esm/{cli → core}/codegen/queries.js +0 -0
  230. /package/esm/{cli → core}/codegen/query-keys.js +0 -0
  231. /package/esm/{cli → core}/codegen/scalars.d.ts +0 -0
  232. /package/esm/{cli → core}/codegen/scalars.js +0 -0
  233. /package/esm/{cli → core}/codegen/schema-gql-ast.d.ts +0 -0
  234. /package/esm/{cli → core}/codegen/schema-gql-ast.js +0 -0
  235. /package/esm/{cli → core}/codegen/schema-types-generator.d.ts +0 -0
  236. /package/esm/{cli → core}/codegen/schema-types-generator.js +0 -0
  237. /package/esm/{cli → core}/codegen/type-resolver.d.ts +0 -0
  238. /package/esm/{cli → core}/codegen/type-resolver.js +0 -0
  239. /package/esm/{cli → core}/codegen/types.d.ts +0 -0
  240. /package/esm/{cli → core}/codegen/types.js +0 -0
  241. /package/esm/{cli → core}/codegen/utils.d.ts +0 -0
  242. /package/esm/{cli → core}/codegen/utils.js +0 -0
  243. /package/esm/{cli → core}/introspect/fetch-schema.d.ts +0 -0
  244. /package/esm/{cli → core}/introspect/index.d.ts +0 -0
  245. /package/esm/{cli → core}/introspect/index.js +0 -0
  246. /package/esm/{cli → core}/introspect/infer-tables.d.ts +0 -0
  247. /package/esm/{cli → core}/introspect/infer-tables.js +0 -0
  248. /package/esm/{cli → core}/introspect/schema-query.d.ts +0 -0
  249. /package/esm/{cli → core}/introspect/schema-query.js +0 -0
  250. /package/esm/{cli → core}/introspect/source/endpoint.d.ts +0 -0
  251. /package/esm/{cli → core}/introspect/source/endpoint.js +0 -0
  252. /package/esm/{cli → core}/introspect/source/file.d.ts +0 -0
  253. /package/esm/{cli → core}/introspect/source/file.js +0 -0
  254. /package/esm/{cli → core}/introspect/source/types.d.ts +0 -0
  255. /package/esm/{cli → core}/introspect/source/types.js +0 -0
  256. /package/esm/{cli → core}/introspect/transform-schema.d.ts +0 -0
  257. /package/esm/{cli → core}/introspect/transform-schema.js +0 -0
  258. /package/esm/{cli → core}/introspect/transform.d.ts +0 -0
  259. /package/esm/{cli → core}/introspect/transform.js +0 -0
  260. /package/esm/{cli → core}/watch/cache.d.ts +0 -0
  261. /package/esm/{cli → core}/watch/cache.js +0 -0
  262. /package/esm/{cli → core}/watch/debounce.d.ts +0 -0
  263. /package/esm/{cli → core}/watch/debounce.js +0 -0
  264. /package/esm/{cli → core}/watch/hash.d.ts +0 -0
  265. /package/esm/{cli → core}/watch/hash.js +0 -0
  266. /package/esm/{cli → core}/watch/index.d.ts +0 -0
  267. /package/esm/{cli → core}/watch/index.js +0 -0
  268. /package/esm/{cli → core}/watch/poller.d.ts +0 -0
  269. /package/esm/{cli → core}/watch/poller.js +0 -0
  270. /package/esm/{cli → core}/watch/types.js +0 -0
@@ -1,393 +0,0 @@
1
- /**
2
- * Generate command - generates SDK from GraphQL schema
3
- *
4
- * This command:
5
- * 1. Fetches schema from endpoint or loads from file
6
- * 2. Infers table metadata from introspection (replaces _meta)
7
- * 3. Generates hooks for both table CRUD and custom operations
8
- */
9
- import * as fs from 'node:fs';
10
- import * as path from 'node:path';
11
- import { execSync } from 'node:child_process';
12
- import { isMultiConfig, mergeConfig, resolveConfig } from '../../types/config';
13
- import { createSchemaSource, validateSourceOptions, } from '../introspect/source';
14
- import { runCodegenPipeline, validateTablesFound } from './shared';
15
- import { findConfigFile, loadConfigFile } from './init';
16
- import { generate } from '../codegen';
17
- /**
18
- * Execute the generate command
19
- */
20
- export async function generateCommand(options = {}) {
21
- if (options.verbose) {
22
- console.log('Loading configuration...');
23
- }
24
- const configResult = await loadConfig(options);
25
- if (!configResult.success) {
26
- return {
27
- success: false,
28
- message: configResult.error,
29
- };
30
- }
31
- const targets = configResult.targets ?? [];
32
- if (targets.length === 0) {
33
- return {
34
- success: false,
35
- message: 'No targets resolved from configuration.',
36
- };
37
- }
38
- const isMultiTarget = configResult.isMulti ?? targets.length > 1;
39
- const results = [];
40
- for (const target of targets) {
41
- const result = await generateForTarget(target, options, isMultiTarget);
42
- results.push(result);
43
- }
44
- if (!isMultiTarget) {
45
- const [result] = results;
46
- return {
47
- success: result.success,
48
- message: result.message,
49
- targets: results,
50
- tables: result.tables,
51
- customQueries: result.customQueries,
52
- customMutations: result.customMutations,
53
- filesWritten: result.filesWritten,
54
- errors: result.errors,
55
- };
56
- }
57
- const successCount = results.filter((result) => result.success).length;
58
- const failedCount = results.length - successCount;
59
- const summaryMessage = failedCount === 0
60
- ? `Generated SDK for ${results.length} targets.`
61
- : `Generated SDK for ${successCount} of ${results.length} targets.`;
62
- return {
63
- success: failedCount === 0,
64
- message: summaryMessage,
65
- targets: results,
66
- errors: failedCount > 0
67
- ? results.flatMap((result) => result.errors ?? [])
68
- : undefined,
69
- };
70
- }
71
- async function generateForTarget(target, options, isMultiTarget) {
72
- const config = target.config;
73
- const prefix = isMultiTarget ? `[${target.name}] ` : '';
74
- const log = options.verbose
75
- ? (message) => console.log(`${prefix}${message}`)
76
- : () => { };
77
- const formatMessage = (message) => isMultiTarget ? `Target "${target.name}": ${message}` : message;
78
- if (isMultiTarget) {
79
- console.log(`\nTarget "${target.name}"`);
80
- const sourceLabel = config.schema
81
- ? `schema: ${config.schema}`
82
- : `endpoint: ${config.endpoint}`;
83
- console.log(` Source: ${sourceLabel}`);
84
- console.log(` Output: ${config.output}`);
85
- }
86
- // 1. Validate source
87
- const sourceValidation = validateSourceOptions({
88
- endpoint: config.endpoint || undefined,
89
- schema: config.schema || undefined,
90
- });
91
- if (!sourceValidation.valid) {
92
- return {
93
- name: target.name,
94
- output: config.output,
95
- success: false,
96
- message: formatMessage(sourceValidation.error),
97
- };
98
- }
99
- const source = createSchemaSource({
100
- endpoint: config.endpoint || undefined,
101
- schema: config.schema || undefined,
102
- authorization: options.authorization || config.headers['Authorization'],
103
- headers: config.headers,
104
- });
105
- // 2. Run the codegen pipeline
106
- let pipelineResult;
107
- try {
108
- pipelineResult = await runCodegenPipeline({
109
- source,
110
- config,
111
- verbose: options.verbose,
112
- skipCustomOperations: options.skipCustomOperations,
113
- });
114
- }
115
- catch (err) {
116
- return {
117
- name: target.name,
118
- output: config.output,
119
- success: false,
120
- message: formatMessage(`Failed to fetch schema: ${err instanceof Error ? err.message : 'Unknown error'}`),
121
- };
122
- }
123
- const { tables, customOperations, stats } = pipelineResult;
124
- // 3. Validate tables found
125
- const tablesValidation = validateTablesFound(tables);
126
- if (!tablesValidation.valid) {
127
- return {
128
- name: target.name,
129
- output: config.output,
130
- success: false,
131
- message: formatMessage(tablesValidation.error),
132
- };
133
- }
134
- // 4. Generate code
135
- console.log(`${prefix}Generating code...`);
136
- const { files: generatedFiles, stats: genStats } = generate({
137
- tables,
138
- customOperations: {
139
- queries: customOperations.queries,
140
- mutations: customOperations.mutations,
141
- typeRegistry: customOperations.typeRegistry,
142
- },
143
- config,
144
- });
145
- console.log(`${prefix}Generated ${genStats.totalFiles} files`);
146
- log(` ${genStats.queryHooks} table query hooks`);
147
- log(` ${genStats.mutationHooks} table mutation hooks`);
148
- log(` ${genStats.customQueryHooks} custom query hooks`);
149
- log(` ${genStats.customMutationHooks} custom mutation hooks`);
150
- const customQueries = customOperations.queries.map((q) => q.name);
151
- const customMutations = customOperations.mutations.map((m) => m.name);
152
- if (options.dryRun) {
153
- return {
154
- name: target.name,
155
- output: config.output,
156
- success: true,
157
- message: formatMessage(`Dry run complete. Would generate ${generatedFiles.length} files for ${tables.length} tables and ${stats.customQueries + stats.customMutations} custom operations.`),
158
- tables: tables.map((t) => t.name),
159
- customQueries,
160
- customMutations,
161
- filesWritten: generatedFiles.map((f) => f.path),
162
- };
163
- }
164
- // 5. Write files
165
- log('Writing files...');
166
- const writeResult = await writeGeneratedFiles(generatedFiles, config.output, [
167
- 'queries',
168
- 'mutations',
169
- ]);
170
- if (!writeResult.success) {
171
- return {
172
- name: target.name,
173
- output: config.output,
174
- success: false,
175
- message: formatMessage(`Failed to write files: ${writeResult.errors?.join(', ')}`),
176
- errors: writeResult.errors,
177
- };
178
- }
179
- const totalOps = customQueries.length + customMutations.length;
180
- const customOpsMsg = totalOps > 0 ? ` and ${totalOps} custom operations` : '';
181
- return {
182
- name: target.name,
183
- output: config.output,
184
- success: true,
185
- message: formatMessage(`Generated SDK for ${tables.length} tables${customOpsMsg}. Files written to ${config.output}`),
186
- tables: tables.map((t) => t.name),
187
- customQueries,
188
- customMutations,
189
- filesWritten: writeResult.filesWritten,
190
- };
191
- }
192
- function buildTargetOverrides(options) {
193
- const overrides = {};
194
- if (options.endpoint) {
195
- overrides.endpoint = options.endpoint;
196
- overrides.schema = undefined;
197
- }
198
- if (options.schema) {
199
- overrides.schema = options.schema;
200
- overrides.endpoint = undefined;
201
- }
202
- if (options.output) {
203
- overrides.output = options.output;
204
- }
205
- return overrides;
206
- }
207
- async function loadConfig(options) {
208
- if (options.endpoint && options.schema) {
209
- return {
210
- success: false,
211
- error: 'Cannot use both --endpoint and --schema. Choose one source.',
212
- };
213
- }
214
- // Find config file
215
- let configPath = options.config;
216
- if (!configPath) {
217
- configPath = findConfigFile() ?? undefined;
218
- }
219
- let baseConfig = {};
220
- if (configPath) {
221
- const loadResult = await loadConfigFile(configPath);
222
- if (!loadResult.success) {
223
- return { success: false, error: loadResult.error };
224
- }
225
- baseConfig = loadResult.config;
226
- }
227
- const overrides = buildTargetOverrides(options);
228
- if (isMultiConfig(baseConfig)) {
229
- if (Object.keys(baseConfig.targets).length === 0) {
230
- return {
231
- success: false,
232
- error: 'Config file defines no targets.',
233
- };
234
- }
235
- if (!options.target &&
236
- (options.endpoint || options.schema || options.output)) {
237
- return {
238
- success: false,
239
- error: 'Multiple targets configured. Use --target with --endpoint, --schema, or --output.',
240
- };
241
- }
242
- if (options.target && !baseConfig.targets[options.target]) {
243
- return {
244
- success: false,
245
- error: `Target "${options.target}" not found in config file.`,
246
- };
247
- }
248
- const selectedTargets = options.target
249
- ? { [options.target]: baseConfig.targets[options.target] }
250
- : baseConfig.targets;
251
- const defaults = baseConfig.defaults ?? {};
252
- const resolvedTargets = [];
253
- for (const [name, target] of Object.entries(selectedTargets)) {
254
- let mergedTarget = mergeConfig(defaults, target);
255
- if (options.target && name === options.target) {
256
- mergedTarget = mergeConfig(mergedTarget, overrides);
257
- }
258
- if (!mergedTarget.endpoint && !mergedTarget.schema) {
259
- return {
260
- success: false,
261
- error: `Target "${name}" is missing an endpoint or schema.`,
262
- };
263
- }
264
- resolvedTargets.push({
265
- name,
266
- config: resolveConfig(mergedTarget),
267
- });
268
- }
269
- return {
270
- success: true,
271
- targets: resolvedTargets,
272
- isMulti: true,
273
- };
274
- }
275
- if (options.target) {
276
- return {
277
- success: false,
278
- error: 'Config file does not define targets. Remove --target to continue.',
279
- };
280
- }
281
- const mergedConfig = mergeConfig(baseConfig, overrides);
282
- if (!mergedConfig.endpoint && !mergedConfig.schema) {
283
- return {
284
- success: false,
285
- error: 'No source specified. Use --endpoint or --schema, or create a config file with "graphql-codegen init".',
286
- };
287
- }
288
- return {
289
- success: true,
290
- targets: [{ name: 'default', config: resolveConfig(mergedConfig) }],
291
- isMulti: false,
292
- };
293
- }
294
- export async function writeGeneratedFiles(files, outputDir, subdirs, options = {}) {
295
- const { showProgress = true } = options;
296
- const errors = [];
297
- const written = [];
298
- const total = files.length;
299
- const isTTY = process.stdout.isTTY;
300
- // Ensure output directory exists
301
- try {
302
- fs.mkdirSync(outputDir, { recursive: true });
303
- }
304
- catch (err) {
305
- const message = err instanceof Error ? err.message : 'Unknown error';
306
- return {
307
- success: false,
308
- errors: [`Failed to create output directory: ${message}`],
309
- };
310
- }
311
- // Create subdirectories
312
- for (const subdir of subdirs) {
313
- const subdirPath = path.join(outputDir, subdir);
314
- try {
315
- fs.mkdirSync(subdirPath, { recursive: true });
316
- }
317
- catch (err) {
318
- const message = err instanceof Error ? err.message : 'Unknown error';
319
- errors.push(`Failed to create directory ${subdirPath}: ${message}`);
320
- }
321
- }
322
- if (errors.length > 0) {
323
- return { success: false, errors };
324
- }
325
- for (let i = 0; i < files.length; i++) {
326
- const file = files[i];
327
- const filePath = path.join(outputDir, file.path);
328
- // Show progress
329
- if (showProgress) {
330
- const progress = Math.round(((i + 1) / total) * 100);
331
- if (isTTY) {
332
- process.stdout.write(`\rWriting files: ${i + 1}/${total} (${progress}%)`);
333
- }
334
- else if (i % 100 === 0 || i === total - 1) {
335
- // Non-TTY: periodic updates for CI/CD
336
- console.log(`Writing files: ${i + 1}/${total}`);
337
- }
338
- }
339
- // Ensure parent directory exists
340
- const parentDir = path.dirname(filePath);
341
- try {
342
- fs.mkdirSync(parentDir, { recursive: true });
343
- }
344
- catch {
345
- // Ignore if already exists
346
- }
347
- try {
348
- fs.writeFileSync(filePath, file.content, 'utf-8');
349
- written.push(filePath);
350
- }
351
- catch (err) {
352
- const message = err instanceof Error ? err.message : 'Unknown error';
353
- errors.push(`Failed to write ${filePath}: ${message}`);
354
- }
355
- }
356
- // Clear progress line
357
- if (showProgress && isTTY) {
358
- process.stdout.write('\r' + ' '.repeat(40) + '\r');
359
- }
360
- // Format all generated files with prettier
361
- if (errors.length === 0) {
362
- if (showProgress) {
363
- console.log('Formatting generated files...');
364
- }
365
- const formatResult = formatOutput(outputDir);
366
- if (!formatResult.success && showProgress) {
367
- console.warn('Warning: Failed to format generated files:', formatResult.error);
368
- }
369
- }
370
- return {
371
- success: errors.length === 0,
372
- filesWritten: written,
373
- errors: errors.length > 0 ? errors : undefined,
374
- };
375
- }
376
- /**
377
- * Format generated files using prettier
378
- * Runs prettier on the output directory after all files are written
379
- */
380
- export function formatOutput(outputDir) {
381
- const absoluteOutputDir = path.resolve(outputDir);
382
- try {
383
- execSync(`npx prettier --write --single-quote --trailing-comma all --tab-width 2 --semi "${absoluteOutputDir}"`, {
384
- stdio: 'pipe',
385
- encoding: 'utf-8',
386
- });
387
- return { success: true };
388
- }
389
- catch (err) {
390
- const message = err instanceof Error ? err.message : String(err);
391
- return { success: false, error: message };
392
- }
393
- }
@@ -1,9 +0,0 @@
1
- /**
2
- * CLI commands exports
3
- */
4
- export { initCommand, findConfigFile, loadConfigFile } from './init';
5
- export type { InitOptions, InitResult } from './init';
6
- export { generateCommand } from './generate';
7
- export type { GenerateOptions, GenerateResult, GenerateTargetResult } from './generate';
8
- export { generateOrmCommand } from './generate-orm';
9
- export type { GenerateOrmOptions, GenerateOrmResult, GenerateOrmTargetResult } from './generate-orm';
@@ -1,6 +0,0 @@
1
- /**
2
- * CLI commands exports
3
- */
4
- export { initCommand, findConfigFile, loadConfigFile } from './init';
5
- export { generateCommand } from './generate';
6
- export { generateOrmCommand } from './generate-orm';
@@ -1,35 +0,0 @@
1
- export interface InitOptions {
2
- /** Target directory for the config file */
3
- directory?: string;
4
- /** Force overwrite existing config */
5
- force?: boolean;
6
- /** GraphQL endpoint URL to pre-populate */
7
- endpoint?: string;
8
- /** Output directory to pre-populate */
9
- output?: string;
10
- }
11
- export interface InitResult {
12
- success: boolean;
13
- message: string;
14
- configPath?: string;
15
- }
16
- /**
17
- * Execute the init command
18
- */
19
- export declare function initCommand(options?: InitOptions): Promise<InitResult>;
20
- /**
21
- * Find the nearest config file by walking up directories
22
- */
23
- export declare function findConfigFile(startDir?: string): string | null;
24
- /**
25
- * Load and validate a config file
26
- *
27
- * Uses jiti to support TypeScript config files (.ts) in addition to
28
- * JavaScript (.js, .mjs, .cjs) without requiring the user to have
29
- * tsx or ts-node installed.
30
- */
31
- export declare function loadConfigFile(configPath: string): Promise<{
32
- success: boolean;
33
- config?: any;
34
- error?: string;
35
- }>;
@@ -1,158 +0,0 @@
1
- /**
2
- * Init command - creates a new graphql-codegen configuration file
3
- */
4
- import * as fs from 'node:fs';
5
- import * as path from 'node:path';
6
- import { createJiti } from 'jiti';
7
- const CONFIG_FILENAME = 'graphql-codegen.config.ts';
8
- const CONFIG_TEMPLATE = `import { defineConfig } from '@constructive-io/graphql-codegen';
9
-
10
- export default defineConfig({
11
- // GraphQL endpoint URL (PostGraphile with _meta plugin)
12
- endpoint: '{{ENDPOINT}}',
13
-
14
- // Output directory for generated files
15
- output: '{{OUTPUT}}',
16
-
17
- // Optional: Multi-target config (use instead of endpoint/output)
18
- // defaults: {
19
- // headers: { Authorization: 'Bearer YOUR_TOKEN' },
20
- // },
21
- // targets: {
22
- // public: { endpoint: 'https://api.example.com/graphql', output: './generated/public' },
23
- // admin: { schema: './admin.schema.graphql', output: './generated/admin' },
24
- // },
25
-
26
- // Optional: Tables to include/exclude (supports glob patterns)
27
- // tables: {
28
- // include: ['*'],
29
- // exclude: ['_*', 'pg_*'],
30
- // },
31
-
32
- // Optional: Authorization header for authenticated endpoints
33
- // headers: {
34
- // Authorization: 'Bearer YOUR_TOKEN',
35
- // },
36
-
37
- // Optional: Watch mode settings (in-memory caching, no file I/O)
38
- // watch: {
39
- // pollInterval: 3000, // ms
40
- // debounce: 800, // ms
41
- // clearScreen: true,
42
- // touchFile: '.trigger', // Optional: file to touch on change
43
- // },
44
- });
45
- `;
46
- /**
47
- * Execute the init command
48
- */
49
- export async function initCommand(options = {}) {
50
- const { directory = process.cwd(), force = false, endpoint = '', output = './generated', } = options;
51
- const configPath = path.join(directory, CONFIG_FILENAME);
52
- // Check if config already exists
53
- if (fs.existsSync(configPath) && !force) {
54
- return {
55
- success: false,
56
- message: `Configuration file already exists: ${configPath}\nUse --force to overwrite.`,
57
- };
58
- }
59
- // Generate config content
60
- const content = CONFIG_TEMPLATE.replace('{{ENDPOINT}}', endpoint || 'http://localhost:5000/graphql').replace('{{OUTPUT}}', output);
61
- try {
62
- // Ensure directory exists
63
- fs.mkdirSync(directory, { recursive: true });
64
- // Write config file
65
- fs.writeFileSync(configPath, content, 'utf-8');
66
- return {
67
- success: true,
68
- message: `Created configuration file: ${configPath}`,
69
- configPath,
70
- };
71
- }
72
- catch (err) {
73
- const message = err instanceof Error ? err.message : 'Unknown error';
74
- return {
75
- success: false,
76
- message: `Failed to create configuration file: ${message}`,
77
- };
78
- }
79
- }
80
- /**
81
- * Find the nearest config file by walking up directories
82
- */
83
- export function findConfigFile(startDir = process.cwd()) {
84
- let currentDir = startDir;
85
- while (true) {
86
- const configPath = path.join(currentDir, CONFIG_FILENAME);
87
- if (fs.existsSync(configPath)) {
88
- return configPath;
89
- }
90
- const parentDir = path.dirname(currentDir);
91
- if (parentDir === currentDir) {
92
- // Reached root
93
- return null;
94
- }
95
- currentDir = parentDir;
96
- }
97
- }
98
- /**
99
- * Load and validate a config file
100
- *
101
- * Uses jiti to support TypeScript config files (.ts) in addition to
102
- * JavaScript (.js, .mjs, .cjs) without requiring the user to have
103
- * tsx or ts-node installed.
104
- */
105
- export async function loadConfigFile(configPath) {
106
- const resolvedPath = path.resolve(configPath);
107
- if (!fs.existsSync(resolvedPath)) {
108
- return {
109
- success: false,
110
- error: `Config file not found: ${resolvedPath}`,
111
- };
112
- }
113
- try {
114
- // Use jiti to load TypeScript/ESM config files seamlessly
115
- // jiti handles .ts, .js, .mjs, .cjs and ESM/CJS interop
116
- const jiti = createJiti(__filename, {
117
- interopDefault: true,
118
- debug: process.env.JITI_DEBUG === '1',
119
- });
120
- // jiti.import() with { default: true } returns mod?.default ?? mod
121
- const config = await jiti.import(resolvedPath, { default: true });
122
- if (!config || typeof config !== 'object') {
123
- return {
124
- success: false,
125
- error: 'Config file must export a configuration object',
126
- };
127
- }
128
- const hasEndpoint = 'endpoint' in config;
129
- const hasSchema = 'schema' in config;
130
- const hasTargets = 'targets' in config;
131
- if (!hasEndpoint && !hasSchema && !hasTargets) {
132
- return {
133
- success: false,
134
- error: 'Config file must define "endpoint", "schema", or "targets".',
135
- };
136
- }
137
- if (hasTargets) {
138
- const targets = config.targets;
139
- if (!targets || typeof targets !== 'object' || Array.isArray(targets)) {
140
- return {
141
- success: false,
142
- error: 'Config file "targets" must be an object of named configs.',
143
- };
144
- }
145
- }
146
- return {
147
- success: true,
148
- config,
149
- };
150
- }
151
- catch (err) {
152
- const message = err instanceof Error ? err.message : 'Unknown error';
153
- return {
154
- success: false,
155
- error: `Failed to load config file: ${message}`,
156
- };
157
- }
158
- }
@@ -1,48 +0,0 @@
1
- /**
2
- * Schema Source Module
3
- *
4
- * Provides a unified interface for loading GraphQL schemas from different sources:
5
- * - Live GraphQL endpoints (via introspection)
6
- * - Static .graphql schema files
7
- */
8
- export * from './types';
9
- export * from './endpoint';
10
- export * from './file';
11
- import type { SchemaSource } from './types';
12
- export interface CreateSchemaSourceOptions {
13
- /**
14
- * GraphQL endpoint URL (for live introspection)
15
- */
16
- endpoint?: string;
17
- /**
18
- * Path to GraphQL schema file (.graphql)
19
- */
20
- schema?: string;
21
- /**
22
- * Optional authorization header for endpoint requests
23
- */
24
- authorization?: string;
25
- /**
26
- * Optional additional headers for endpoint requests
27
- */
28
- headers?: Record<string, string>;
29
- /**
30
- * Request timeout in milliseconds (for endpoint requests)
31
- */
32
- timeout?: number;
33
- }
34
- /**
35
- * Create a schema source based on configuration
36
- *
37
- * @param options - Source configuration
38
- * @returns Appropriate SchemaSource implementation
39
- * @throws Error if neither endpoint nor schema is provided
40
- */
41
- export declare function createSchemaSource(options: CreateSchemaSourceOptions): SchemaSource;
42
- /**
43
- * Validate that source options are valid (at least one source specified)
44
- */
45
- export declare function validateSourceOptions(options: CreateSchemaSourceOptions): {
46
- valid: boolean;
47
- error?: string;
48
- };