@constructive-io/graphql-codegen 2.19.0 → 2.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. package/README.md +1818 -113
  2. package/__tests__/codegen/input-types-generator.test.d.ts +1 -0
  3. package/__tests__/codegen/input-types-generator.test.js +635 -0
  4. package/cli/codegen/barrel.d.ts +27 -0
  5. package/cli/codegen/barrel.js +163 -0
  6. package/cli/codegen/client.d.ts +4 -0
  7. package/cli/codegen/client.js +170 -0
  8. package/cli/codegen/custom-mutations.d.ts +38 -0
  9. package/cli/codegen/custom-mutations.js +149 -0
  10. package/cli/codegen/custom-queries.d.ts +38 -0
  11. package/cli/codegen/custom-queries.js +358 -0
  12. package/cli/codegen/filters.d.ts +27 -0
  13. package/cli/codegen/filters.js +357 -0
  14. package/cli/codegen/gql-ast.d.ts +41 -0
  15. package/cli/codegen/gql-ast.js +329 -0
  16. package/cli/codegen/index.d.ts +71 -0
  17. package/cli/codegen/index.js +147 -0
  18. package/cli/codegen/mutations.d.ts +30 -0
  19. package/cli/codegen/mutations.js +410 -0
  20. package/cli/codegen/orm/barrel.d.ts +18 -0
  21. package/cli/codegen/orm/barrel.js +48 -0
  22. package/cli/codegen/orm/client-generator.d.ts +45 -0
  23. package/cli/codegen/orm/client-generator.js +646 -0
  24. package/cli/codegen/orm/custom-ops-generator.d.ts +30 -0
  25. package/cli/codegen/orm/custom-ops-generator.js +350 -0
  26. package/cli/codegen/orm/index.d.ts +38 -0
  27. package/cli/codegen/orm/index.js +88 -0
  28. package/cli/codegen/orm/input-types-generator.d.ts +21 -0
  29. package/cli/codegen/orm/input-types-generator.js +705 -0
  30. package/cli/codegen/orm/input-types-generator.test.d.ts +1 -0
  31. package/cli/codegen/orm/input-types-generator.test.js +75 -0
  32. package/cli/codegen/orm/model-generator.d.ts +32 -0
  33. package/cli/codegen/orm/model-generator.js +264 -0
  34. package/cli/codegen/orm/query-builder.d.ts +161 -0
  35. package/cli/codegen/orm/query-builder.js +366 -0
  36. package/cli/codegen/orm/select-types.d.ts +169 -0
  37. package/cli/codegen/orm/select-types.js +16 -0
  38. package/cli/codegen/orm/select-types.test.d.ts +11 -0
  39. package/cli/codegen/orm/select-types.test.js +22 -0
  40. package/cli/codegen/queries.d.ts +25 -0
  41. package/cli/codegen/queries.js +438 -0
  42. package/cli/codegen/scalars.d.ts +12 -0
  43. package/cli/codegen/scalars.js +71 -0
  44. package/cli/codegen/schema-gql-ast.d.ts +51 -0
  45. package/cli/codegen/schema-gql-ast.js +385 -0
  46. package/cli/codegen/ts-ast.d.ts +122 -0
  47. package/cli/codegen/ts-ast.js +280 -0
  48. package/cli/codegen/type-resolver.d.ts +96 -0
  49. package/cli/codegen/type-resolver.js +246 -0
  50. package/cli/codegen/types.d.ts +12 -0
  51. package/cli/codegen/types.js +69 -0
  52. package/cli/codegen/utils.d.ts +163 -0
  53. package/cli/codegen/utils.js +326 -0
  54. package/cli/commands/generate-orm.d.ts +37 -0
  55. package/cli/commands/generate-orm.js +195 -0
  56. package/cli/commands/generate.d.ts +39 -0
  57. package/cli/commands/generate.js +299 -0
  58. package/cli/commands/index.d.ts +7 -0
  59. package/cli/commands/index.js +12 -0
  60. package/cli/commands/init.d.ts +35 -0
  61. package/cli/commands/init.js +176 -0
  62. package/cli/index.d.ts +4 -0
  63. package/cli/index.js +291 -0
  64. package/cli/introspect/fetch-meta.d.ts +31 -0
  65. package/cli/introspect/fetch-meta.js +108 -0
  66. package/cli/introspect/fetch-schema.d.ts +21 -0
  67. package/cli/introspect/fetch-schema.js +86 -0
  68. package/cli/introspect/index.d.ts +8 -0
  69. package/cli/introspect/index.js +16 -0
  70. package/cli/introspect/meta-query.d.ts +111 -0
  71. package/cli/introspect/meta-query.js +191 -0
  72. package/cli/introspect/schema-query.d.ts +20 -0
  73. package/cli/introspect/schema-query.js +123 -0
  74. package/cli/introspect/transform-schema.d.ts +74 -0
  75. package/cli/introspect/transform-schema.js +269 -0
  76. package/cli/introspect/transform-schema.test.d.ts +1 -0
  77. package/cli/introspect/transform-schema.test.js +67 -0
  78. package/cli/introspect/transform.d.ts +21 -0
  79. package/cli/introspect/transform.js +216 -0
  80. package/cli/watch/cache.d.ts +45 -0
  81. package/cli/watch/cache.js +111 -0
  82. package/cli/watch/debounce.d.ts +19 -0
  83. package/cli/watch/debounce.js +89 -0
  84. package/cli/watch/hash.d.ts +17 -0
  85. package/cli/watch/hash.js +48 -0
  86. package/cli/watch/index.d.ts +10 -0
  87. package/cli/watch/index.js +22 -0
  88. package/cli/watch/orchestrator.d.ts +63 -0
  89. package/cli/watch/orchestrator.js +228 -0
  90. package/cli/watch/poller.d.ts +65 -0
  91. package/cli/watch/poller.js +203 -0
  92. package/cli/watch/types.d.ts +67 -0
  93. package/cli/watch/types.js +5 -0
  94. package/client/error.d.ts +95 -0
  95. package/client/error.js +255 -0
  96. package/client/execute.d.ts +57 -0
  97. package/client/execute.js +124 -0
  98. package/client/index.d.ts +6 -0
  99. package/client/index.js +18 -0
  100. package/client/typed-document.d.ts +31 -0
  101. package/client/typed-document.js +44 -0
  102. package/core/ast.d.ts +10 -0
  103. package/core/ast.js +593 -0
  104. package/core/custom-ast.d.ts +35 -0
  105. package/core/custom-ast.js +204 -0
  106. package/core/index.d.ts +8 -0
  107. package/core/index.js +33 -0
  108. package/core/meta-object/convert.d.ts +65 -0
  109. package/core/meta-object/convert.js +63 -0
  110. package/core/meta-object/format.json +93 -0
  111. package/core/meta-object/index.d.ts +2 -0
  112. package/core/meta-object/index.js +18 -0
  113. package/core/meta-object/validate.d.ts +9 -0
  114. package/core/meta-object/validate.js +34 -0
  115. package/core/query-builder.d.ts +46 -0
  116. package/core/query-builder.js +412 -0
  117. package/core/types.d.ts +139 -0
  118. package/core/types.js +28 -0
  119. package/esm/__tests__/codegen/input-types-generator.test.d.ts +1 -0
  120. package/esm/__tests__/codegen/input-types-generator.test.js +633 -0
  121. package/esm/cli/codegen/barrel.d.ts +27 -0
  122. package/esm/cli/codegen/barrel.js +156 -0
  123. package/esm/cli/codegen/client.d.ts +4 -0
  124. package/esm/cli/codegen/client.js +167 -0
  125. package/esm/cli/codegen/custom-mutations.d.ts +38 -0
  126. package/esm/cli/codegen/custom-mutations.js +145 -0
  127. package/esm/cli/codegen/custom-queries.d.ts +38 -0
  128. package/esm/cli/codegen/custom-queries.js +354 -0
  129. package/esm/cli/codegen/filters.d.ts +27 -0
  130. package/esm/cli/codegen/filters.js +351 -0
  131. package/esm/cli/codegen/gql-ast.d.ts +41 -0
  132. package/esm/cli/codegen/gql-ast.js +288 -0
  133. package/esm/cli/codegen/index.d.ts +71 -0
  134. package/esm/cli/codegen/index.js +124 -0
  135. package/esm/cli/codegen/mutations.d.ts +30 -0
  136. package/esm/cli/codegen/mutations.js +404 -0
  137. package/esm/cli/codegen/orm/barrel.d.ts +18 -0
  138. package/esm/cli/codegen/orm/barrel.js +44 -0
  139. package/esm/cli/codegen/orm/client-generator.d.ts +45 -0
  140. package/esm/cli/codegen/orm/client-generator.js +640 -0
  141. package/esm/cli/codegen/orm/custom-ops-generator.d.ts +30 -0
  142. package/esm/cli/codegen/orm/custom-ops-generator.js +346 -0
  143. package/esm/cli/codegen/orm/index.d.ts +38 -0
  144. package/esm/cli/codegen/orm/index.js +75 -0
  145. package/esm/cli/codegen/orm/input-types-generator.d.ts +21 -0
  146. package/esm/cli/codegen/orm/input-types-generator.js +700 -0
  147. package/esm/cli/codegen/orm/input-types-generator.test.d.ts +1 -0
  148. package/esm/cli/codegen/orm/input-types-generator.test.js +73 -0
  149. package/esm/cli/codegen/orm/model-generator.d.ts +32 -0
  150. package/esm/cli/codegen/orm/model-generator.js +260 -0
  151. package/esm/cli/codegen/orm/query-builder.d.ts +161 -0
  152. package/esm/cli/codegen/orm/query-builder.js +353 -0
  153. package/esm/cli/codegen/orm/select-types.d.ts +169 -0
  154. package/esm/cli/codegen/orm/select-types.js +15 -0
  155. package/esm/cli/codegen/orm/select-types.test.d.ts +11 -0
  156. package/esm/cli/codegen/orm/select-types.test.js +21 -0
  157. package/esm/cli/codegen/queries.d.ts +25 -0
  158. package/esm/cli/codegen/queries.js +433 -0
  159. package/esm/cli/codegen/scalars.d.ts +12 -0
  160. package/esm/cli/codegen/scalars.js +66 -0
  161. package/esm/cli/codegen/schema-gql-ast.d.ts +51 -0
  162. package/esm/cli/codegen/schema-gql-ast.js +343 -0
  163. package/esm/cli/codegen/ts-ast.d.ts +122 -0
  164. package/esm/cli/codegen/ts-ast.js +260 -0
  165. package/esm/cli/codegen/type-resolver.d.ts +96 -0
  166. package/esm/cli/codegen/type-resolver.js +224 -0
  167. package/esm/cli/codegen/types.d.ts +12 -0
  168. package/esm/cli/codegen/types.js +65 -0
  169. package/esm/cli/codegen/utils.d.ts +163 -0
  170. package/esm/cli/codegen/utils.js +288 -0
  171. package/esm/cli/commands/generate-orm.d.ts +37 -0
  172. package/esm/cli/commands/generate-orm.js +192 -0
  173. package/esm/cli/commands/generate.d.ts +39 -0
  174. package/esm/cli/commands/generate.js +262 -0
  175. package/esm/cli/commands/index.d.ts +7 -0
  176. package/esm/cli/commands/index.js +5 -0
  177. package/esm/cli/commands/init.d.ts +35 -0
  178. package/esm/cli/commands/init.js +138 -0
  179. package/esm/cli/index.d.ts +4 -0
  180. package/esm/cli/index.js +256 -0
  181. package/esm/cli/introspect/fetch-meta.d.ts +31 -0
  182. package/esm/cli/introspect/fetch-meta.js +104 -0
  183. package/esm/cli/introspect/fetch-schema.d.ts +21 -0
  184. package/esm/cli/introspect/fetch-schema.js +83 -0
  185. package/esm/cli/introspect/index.d.ts +8 -0
  186. package/esm/cli/introspect/index.js +6 -0
  187. package/esm/cli/introspect/meta-query.d.ts +111 -0
  188. package/esm/cli/introspect/meta-query.js +188 -0
  189. package/esm/cli/introspect/schema-query.d.ts +20 -0
  190. package/esm/cli/introspect/schema-query.js +120 -0
  191. package/esm/cli/introspect/transform-schema.d.ts +74 -0
  192. package/esm/cli/introspect/transform-schema.js +259 -0
  193. package/esm/cli/introspect/transform-schema.test.d.ts +1 -0
  194. package/esm/cli/introspect/transform-schema.test.js +65 -0
  195. package/esm/cli/introspect/transform.d.ts +21 -0
  196. package/esm/cli/introspect/transform.js +210 -0
  197. package/esm/cli/watch/cache.d.ts +45 -0
  198. package/esm/cli/watch/cache.js +73 -0
  199. package/esm/cli/watch/debounce.d.ts +19 -0
  200. package/esm/cli/watch/debounce.js +85 -0
  201. package/esm/cli/watch/hash.d.ts +17 -0
  202. package/esm/cli/watch/hash.js +43 -0
  203. package/esm/cli/watch/index.d.ts +10 -0
  204. package/esm/cli/watch/index.js +8 -0
  205. package/esm/cli/watch/orchestrator.d.ts +63 -0
  206. package/esm/cli/watch/orchestrator.js +223 -0
  207. package/esm/cli/watch/poller.d.ts +65 -0
  208. package/esm/cli/watch/poller.js +198 -0
  209. package/esm/cli/watch/types.d.ts +67 -0
  210. package/esm/cli/watch/types.js +4 -0
  211. package/esm/client/error.d.ts +95 -0
  212. package/esm/client/error.js +249 -0
  213. package/esm/client/execute.d.ts +57 -0
  214. package/esm/client/execute.js +120 -0
  215. package/esm/client/index.d.ts +6 -0
  216. package/esm/client/index.js +6 -0
  217. package/esm/client/typed-document.d.ts +31 -0
  218. package/esm/client/typed-document.js +40 -0
  219. package/esm/core/ast.d.ts +10 -0
  220. package/esm/core/ast.js +549 -0
  221. package/esm/core/custom-ast.d.ts +35 -0
  222. package/esm/core/custom-ast.js +161 -0
  223. package/esm/core/index.d.ts +8 -0
  224. package/esm/core/index.js +12 -0
  225. package/esm/core/meta-object/convert.d.ts +65 -0
  226. package/esm/core/meta-object/convert.js +60 -0
  227. package/esm/core/meta-object/format.json +93 -0
  228. package/esm/core/meta-object/index.d.ts +2 -0
  229. package/esm/core/meta-object/index.js +2 -0
  230. package/esm/core/meta-object/validate.d.ts +9 -0
  231. package/esm/core/meta-object/validate.js +28 -0
  232. package/esm/core/query-builder.d.ts +46 -0
  233. package/esm/core/query-builder.js +375 -0
  234. package/esm/core/types.d.ts +139 -0
  235. package/esm/core/types.js +24 -0
  236. package/esm/generators/field-selector.d.ts +30 -0
  237. package/esm/generators/field-selector.js +355 -0
  238. package/esm/generators/index.d.ts +6 -0
  239. package/esm/generators/index.js +9 -0
  240. package/esm/generators/mutations.d.ts +31 -0
  241. package/esm/generators/mutations.js +197 -0
  242. package/esm/generators/select.d.ts +50 -0
  243. package/esm/generators/select.js +636 -0
  244. package/esm/index.d.ts +12 -0
  245. package/esm/index.js +17 -3
  246. package/esm/react/index.d.ts +5 -0
  247. package/esm/react/index.js +6 -0
  248. package/esm/types/config.d.ts +199 -0
  249. package/esm/types/config.js +106 -0
  250. package/esm/types/index.d.ts +9 -0
  251. package/esm/types/index.js +4 -0
  252. package/esm/types/introspection.d.ts +121 -0
  253. package/esm/types/introspection.js +54 -0
  254. package/esm/types/mutation.d.ts +45 -0
  255. package/esm/types/mutation.js +4 -0
  256. package/esm/types/query.d.ts +82 -0
  257. package/esm/types/query.js +4 -0
  258. package/esm/types/schema.d.ts +253 -0
  259. package/esm/types/schema.js +5 -0
  260. package/esm/types/selection.d.ts +43 -0
  261. package/esm/types/selection.js +4 -0
  262. package/esm/utils/index.d.ts +4 -0
  263. package/esm/utils/index.js +4 -0
  264. package/generators/field-selector.d.ts +30 -0
  265. package/generators/field-selector.js +361 -0
  266. package/generators/index.d.ts +6 -0
  267. package/generators/index.js +27 -0
  268. package/generators/mutations.d.ts +31 -0
  269. package/generators/mutations.js +235 -0
  270. package/generators/select.d.ts +50 -0
  271. package/generators/select.js +679 -0
  272. package/index.d.ts +12 -3
  273. package/index.js +19 -3
  274. package/package.json +59 -38
  275. package/react/index.d.ts +5 -0
  276. package/react/index.js +9 -0
  277. package/types/config.d.ts +199 -0
  278. package/types/config.js +111 -0
  279. package/types/index.d.ts +9 -0
  280. package/types/index.js +10 -0
  281. package/types/introspection.d.ts +121 -0
  282. package/types/introspection.js +62 -0
  283. package/types/mutation.d.ts +45 -0
  284. package/types/mutation.js +5 -0
  285. package/types/query.d.ts +82 -0
  286. package/types/query.js +5 -0
  287. package/types/schema.d.ts +253 -0
  288. package/types/schema.js +6 -0
  289. package/types/selection.d.ts +43 -0
  290. package/types/selection.js +5 -0
  291. package/utils/index.d.ts +4 -0
  292. package/utils/index.js +7 -0
  293. package/codegen.d.ts +0 -13
  294. package/codegen.js +0 -293
  295. package/esm/codegen.js +0 -253
  296. package/esm/gql.js +0 -939
  297. package/esm/options.js +0 -27
  298. package/gql.d.ts +0 -188
  299. package/gql.js +0 -992
  300. package/options.d.ts +0 -45
  301. package/options.js +0 -31
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ /**
3
+ * In-memory schema cache for watch mode
4
+ *
5
+ * Only stores the hash in memory - no file I/O during normal operation.
6
+ * Touch file feature is optional and only writes when explicitly configured.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.SchemaCache = void 0;
43
+ exports.touchFile = touchFile;
44
+ const fs = __importStar(require("node:fs"));
45
+ const path = __importStar(require("node:path"));
46
+ const hash_1 = require("./hash");
47
+ /**
48
+ * Lightweight in-memory schema cache
49
+ * Only stores the combined hash string to detect changes
50
+ */
51
+ class SchemaCache {
52
+ /** Current schema hash (in-memory only) */
53
+ currentHash = null;
54
+ /**
55
+ * Check if schema has changed by comparing hashes
56
+ * This is the hot path - must be efficient
57
+ */
58
+ async hasChanged(meta, schema) {
59
+ const newHash = await this.computeHash(meta, schema);
60
+ const changed = this.currentHash === null || this.currentHash !== newHash;
61
+ return { changed, newHash };
62
+ }
63
+ /**
64
+ * Update the cached hash (call after successful regeneration)
65
+ */
66
+ updateHash(hash) {
67
+ this.currentHash = hash;
68
+ }
69
+ /**
70
+ * Get the current cached hash
71
+ */
72
+ getHash() {
73
+ return this.currentHash;
74
+ }
75
+ /**
76
+ * Clear the cached hash
77
+ */
78
+ clear() {
79
+ this.currentHash = null;
80
+ }
81
+ /**
82
+ * Compute hash from meta and schema responses
83
+ */
84
+ async computeHash(meta, schema) {
85
+ // Hash each response separately then combine
86
+ // This is more efficient than stringifying both together
87
+ const metaHash = await (0, hash_1.hashObject)(meta);
88
+ const schemaHash = await (0, hash_1.hashObject)(schema);
89
+ return (0, hash_1.combineHashes)(metaHash, schemaHash);
90
+ }
91
+ }
92
+ exports.SchemaCache = SchemaCache;
93
+ /**
94
+ * Touch a file to signal schema change (for external tools like tsc/webpack)
95
+ * This is the only file I/O in watch mode, and it's optional.
96
+ */
97
+ function touchFile(filePath) {
98
+ // Ensure parent directory exists
99
+ const dir = path.dirname(filePath);
100
+ if (!fs.existsSync(dir)) {
101
+ fs.mkdirSync(dir, { recursive: true });
102
+ }
103
+ // Touch the file (create if doesn't exist, update mtime if it does)
104
+ const time = new Date();
105
+ try {
106
+ fs.utimesSync(filePath, time, time);
107
+ }
108
+ catch {
109
+ fs.closeSync(fs.openSync(filePath, 'w'));
110
+ }
111
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Debounce utility for regeneration
3
+ */
4
+ /**
5
+ * Creates a debounced function that delays invoking func until after wait milliseconds
6
+ * have elapsed since the last time the debounced function was invoked.
7
+ */
8
+ export declare function debounce<T extends (...args: unknown[]) => unknown>(func: T, wait: number): {
9
+ (...args: Parameters<T>): void;
10
+ cancel: () => void;
11
+ flush: () => void;
12
+ };
13
+ /**
14
+ * Creates an async debounced function
15
+ */
16
+ export declare function debounceAsync<T extends (...args: unknown[]) => Promise<unknown>>(func: T, wait: number): {
17
+ (...args: Parameters<T>): Promise<void>;
18
+ cancel: () => void;
19
+ };
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ /**
3
+ * Debounce utility for regeneration
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.debounce = debounce;
7
+ exports.debounceAsync = debounceAsync;
8
+ /**
9
+ * Creates a debounced function that delays invoking func until after wait milliseconds
10
+ * have elapsed since the last time the debounced function was invoked.
11
+ */
12
+ function debounce(func, wait) {
13
+ let timeoutId = null;
14
+ let lastArgs = null;
15
+ const debounced = (...args) => {
16
+ lastArgs = args;
17
+ if (timeoutId) {
18
+ clearTimeout(timeoutId);
19
+ }
20
+ timeoutId = setTimeout(() => {
21
+ timeoutId = null;
22
+ if (lastArgs) {
23
+ func(...lastArgs);
24
+ lastArgs = null;
25
+ }
26
+ }, wait);
27
+ };
28
+ debounced.cancel = () => {
29
+ if (timeoutId) {
30
+ clearTimeout(timeoutId);
31
+ timeoutId = null;
32
+ lastArgs = null;
33
+ }
34
+ };
35
+ debounced.flush = () => {
36
+ if (timeoutId && lastArgs) {
37
+ clearTimeout(timeoutId);
38
+ timeoutId = null;
39
+ func(...lastArgs);
40
+ lastArgs = null;
41
+ }
42
+ };
43
+ return debounced;
44
+ }
45
+ /**
46
+ * Creates an async debounced function
47
+ */
48
+ function debounceAsync(func, wait) {
49
+ let timeoutId = null;
50
+ let pendingPromise = null;
51
+ let pendingResolve = null;
52
+ const debounced = (...args) => {
53
+ if (timeoutId) {
54
+ clearTimeout(timeoutId);
55
+ }
56
+ // If there's already a pending promise, reuse it
57
+ if (!pendingPromise) {
58
+ pendingPromise = new Promise((resolve) => {
59
+ pendingResolve = resolve;
60
+ });
61
+ }
62
+ timeoutId = setTimeout(async () => {
63
+ timeoutId = null;
64
+ try {
65
+ await func(...args);
66
+ }
67
+ finally {
68
+ if (pendingResolve) {
69
+ pendingResolve();
70
+ pendingResolve = null;
71
+ pendingPromise = null;
72
+ }
73
+ }
74
+ }, wait);
75
+ return pendingPromise;
76
+ };
77
+ debounced.cancel = () => {
78
+ if (timeoutId) {
79
+ clearTimeout(timeoutId);
80
+ timeoutId = null;
81
+ }
82
+ if (pendingResolve) {
83
+ pendingResolve();
84
+ pendingResolve = null;
85
+ pendingPromise = null;
86
+ }
87
+ };
88
+ return debounced;
89
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Schema hashing utilities using Node.js crypto.subtle (Node 22+)
3
+ */
4
+ /**
5
+ * Compute SHA-256 hash of a string using Web Crypto API
6
+ * Uses crypto.subtle available in Node.js 22+
7
+ */
8
+ export declare function sha256(data: string): Promise<string>;
9
+ /**
10
+ * Compute hash of an object by JSON-stringifying it
11
+ * Objects are sorted by keys for consistent hashing
12
+ */
13
+ export declare function hashObject(obj: unknown): Promise<string>;
14
+ /**
15
+ * Combine multiple hashes into a single hash
16
+ */
17
+ export declare function combineHashes(...hashes: string[]): Promise<string>;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ /**
3
+ * Schema hashing utilities using Node.js crypto.subtle (Node 22+)
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.sha256 = sha256;
7
+ exports.hashObject = hashObject;
8
+ exports.combineHashes = combineHashes;
9
+ const node_crypto_1 = require("node:crypto");
10
+ /**
11
+ * Compute SHA-256 hash of a string using Web Crypto API
12
+ * Uses crypto.subtle available in Node.js 22+
13
+ */
14
+ async function sha256(data) {
15
+ const encoder = new TextEncoder();
16
+ const dataBuffer = encoder.encode(data);
17
+ const hashBuffer = await node_crypto_1.webcrypto.subtle.digest('SHA-256', dataBuffer);
18
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
19
+ return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
20
+ }
21
+ /**
22
+ * Compute hash of an object by JSON-stringifying it
23
+ * Objects are sorted by keys for consistent hashing
24
+ */
25
+ async function hashObject(obj) {
26
+ const json = JSON.stringify(obj, sortReplacer);
27
+ return sha256(json);
28
+ }
29
+ /**
30
+ * JSON.stringify replacer that sorts object keys for deterministic output
31
+ */
32
+ function sortReplacer(_key, value) {
33
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
34
+ return Object.keys(value)
35
+ .sort()
36
+ .reduce((sorted, key) => {
37
+ sorted[key] = value[key];
38
+ return sorted;
39
+ }, {});
40
+ }
41
+ return value;
42
+ }
43
+ /**
44
+ * Combine multiple hashes into a single hash
45
+ */
46
+ async function combineHashes(...hashes) {
47
+ return sha256(hashes.join(':'));
48
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Watch mode module exports
3
+ */
4
+ export { SchemaPoller, computeSchemaHash } from './poller';
5
+ export { SchemaCache, touchFile } from './cache';
6
+ export { sha256, hashObject, combineHashes } from './hash';
7
+ export { debounce, debounceAsync } from './debounce';
8
+ export { WatchOrchestrator, startWatch } from './orchestrator';
9
+ export type { PollResult, WatchOptions, PollEventType, PollEventHandler, PollEvent, GeneratorType, } from './types';
10
+ export type { WatchOrchestratorOptions, WatchStatus } from './orchestrator';
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ /**
3
+ * Watch mode module exports
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.startWatch = exports.WatchOrchestrator = exports.debounceAsync = exports.debounce = exports.combineHashes = exports.hashObject = exports.sha256 = exports.touchFile = exports.SchemaCache = exports.computeSchemaHash = exports.SchemaPoller = void 0;
7
+ var poller_1 = require("./poller");
8
+ Object.defineProperty(exports, "SchemaPoller", { enumerable: true, get: function () { return poller_1.SchemaPoller; } });
9
+ Object.defineProperty(exports, "computeSchemaHash", { enumerable: true, get: function () { return poller_1.computeSchemaHash; } });
10
+ var cache_1 = require("./cache");
11
+ Object.defineProperty(exports, "SchemaCache", { enumerable: true, get: function () { return cache_1.SchemaCache; } });
12
+ Object.defineProperty(exports, "touchFile", { enumerable: true, get: function () { return cache_1.touchFile; } });
13
+ var hash_1 = require("./hash");
14
+ Object.defineProperty(exports, "sha256", { enumerable: true, get: function () { return hash_1.sha256; } });
15
+ Object.defineProperty(exports, "hashObject", { enumerable: true, get: function () { return hash_1.hashObject; } });
16
+ Object.defineProperty(exports, "combineHashes", { enumerable: true, get: function () { return hash_1.combineHashes; } });
17
+ var debounce_1 = require("./debounce");
18
+ Object.defineProperty(exports, "debounce", { enumerable: true, get: function () { return debounce_1.debounce; } });
19
+ Object.defineProperty(exports, "debounceAsync", { enumerable: true, get: function () { return debounce_1.debounceAsync; } });
20
+ var orchestrator_1 = require("./orchestrator");
21
+ Object.defineProperty(exports, "WatchOrchestrator", { enumerable: true, get: function () { return orchestrator_1.WatchOrchestrator; } });
22
+ Object.defineProperty(exports, "startWatch", { enumerable: true, get: function () { return orchestrator_1.startWatch; } });
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Watch mode orchestrator
3
+ *
4
+ * Coordinates schema polling, change detection, and code regeneration
5
+ */
6
+ import type { ResolvedConfig } from '../../types/config';
7
+ import type { GeneratorType } from './types';
8
+ export interface WatchOrchestratorOptions {
9
+ config: ResolvedConfig;
10
+ generatorType: GeneratorType;
11
+ verbose: boolean;
12
+ authorization?: string;
13
+ /** Override output directory (for ORM) */
14
+ outputDir?: string;
15
+ /** Skip custom operations flag */
16
+ skipCustomOperations?: boolean;
17
+ }
18
+ export interface WatchStatus {
19
+ isRunning: boolean;
20
+ pollCount: number;
21
+ regenerateCount: number;
22
+ lastPollTime: number | null;
23
+ lastRegenTime: number | null;
24
+ lastError: string | null;
25
+ currentHash: string | null;
26
+ }
27
+ /**
28
+ * Main watch orchestrator class
29
+ */
30
+ export declare class WatchOrchestrator {
31
+ private options;
32
+ private watchOptions;
33
+ private poller;
34
+ private status;
35
+ private debouncedRegenerate;
36
+ private isShuttingDown;
37
+ constructor(options: WatchOrchestratorOptions);
38
+ private buildWatchOptions;
39
+ private setupEventHandlers;
40
+ /**
41
+ * Start watch mode
42
+ */
43
+ start(): Promise<void>;
44
+ /**
45
+ * Stop watch mode
46
+ */
47
+ stop(): Promise<void>;
48
+ /**
49
+ * Get current watch status
50
+ */
51
+ getStatus(): WatchStatus;
52
+ private regenerate;
53
+ private setupSignalHandlers;
54
+ private clearScreen;
55
+ private logHeader;
56
+ private log;
57
+ private logSuccess;
58
+ private logError;
59
+ }
60
+ /**
61
+ * Start watch mode for a generator
62
+ */
63
+ export declare function startWatch(options: WatchOrchestratorOptions): Promise<void>;
@@ -0,0 +1,228 @@
1
+ "use strict";
2
+ /**
3
+ * Watch mode orchestrator
4
+ *
5
+ * Coordinates schema polling, change detection, and code regeneration
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.WatchOrchestrator = void 0;
9
+ exports.startWatch = startWatch;
10
+ const poller_1 = require("./poller");
11
+ const debounce_1 = require("./debounce");
12
+ const generate_1 = require("../commands/generate");
13
+ const generate_orm_1 = require("../commands/generate-orm");
14
+ /**
15
+ * Main watch orchestrator class
16
+ */
17
+ class WatchOrchestrator {
18
+ options;
19
+ watchOptions;
20
+ poller;
21
+ status;
22
+ debouncedRegenerate;
23
+ isShuttingDown = false;
24
+ constructor(options) {
25
+ this.options = options;
26
+ this.watchOptions = this.buildWatchOptions();
27
+ this.poller = new poller_1.SchemaPoller(this.watchOptions);
28
+ this.status = {
29
+ isRunning: false,
30
+ pollCount: 0,
31
+ regenerateCount: 0,
32
+ lastPollTime: null,
33
+ lastRegenTime: null,
34
+ lastError: null,
35
+ currentHash: null,
36
+ };
37
+ // Create debounced regenerate function
38
+ this.debouncedRegenerate = (0, debounce_1.debounce)(() => this.regenerate(), options.config.watch.debounce);
39
+ // Set up event handlers
40
+ this.setupEventHandlers();
41
+ }
42
+ buildWatchOptions() {
43
+ const { config, verbose, authorization } = this.options;
44
+ return {
45
+ endpoint: config.endpoint,
46
+ authorization,
47
+ headers: config.headers,
48
+ pollInterval: config.watch.pollInterval,
49
+ debounce: config.watch.debounce,
50
+ touchFile: config.watch.touchFile,
51
+ clearScreen: config.watch.clearScreen,
52
+ verbose,
53
+ };
54
+ }
55
+ setupEventHandlers() {
56
+ this.poller.on('poll-start', () => {
57
+ this.status.pollCount++;
58
+ if (this.watchOptions.verbose) {
59
+ this.log('Polling endpoint...');
60
+ }
61
+ });
62
+ this.poller.on('poll-success', (event) => {
63
+ this.status.lastPollTime = event.timestamp;
64
+ this.status.lastError = null;
65
+ if (this.watchOptions.verbose) {
66
+ this.log(`Poll complete (${event.duration}ms)`);
67
+ }
68
+ });
69
+ this.poller.on('poll-error', (event) => {
70
+ this.status.lastError = event.error ?? 'Unknown error';
71
+ this.logError(`Poll failed: ${event.error}`);
72
+ });
73
+ this.poller.on('schema-changed', (event) => {
74
+ this.status.currentHash = event.hash ?? null;
75
+ this.log(`Schema changed! (${event.duration}ms)`);
76
+ this.debouncedRegenerate();
77
+ });
78
+ this.poller.on('schema-unchanged', () => {
79
+ if (this.watchOptions.verbose) {
80
+ this.log('Schema unchanged');
81
+ }
82
+ });
83
+ }
84
+ /**
85
+ * Start watch mode
86
+ */
87
+ async start() {
88
+ if (this.status.isRunning) {
89
+ return;
90
+ }
91
+ this.status.isRunning = true;
92
+ this.setupSignalHandlers();
93
+ // Clear screen on start if configured
94
+ if (this.watchOptions.clearScreen) {
95
+ this.clearScreen();
96
+ }
97
+ this.logHeader();
98
+ // Do initial generation (always generate on start, regardless of cache)
99
+ this.log('Running initial generation...');
100
+ await this.regenerate();
101
+ // Seed the in-memory cache with current schema hash (silent, no events)
102
+ // This prevents the first poll from triggering another regeneration
103
+ await this.poller.seedCache();
104
+ // Start polling loop
105
+ this.poller.start();
106
+ this.log(`Watching for schema changes (poll interval: ${this.watchOptions.pollInterval}ms)`);
107
+ }
108
+ /**
109
+ * Stop watch mode
110
+ */
111
+ async stop() {
112
+ if (!this.status.isRunning) {
113
+ return;
114
+ }
115
+ this.isShuttingDown = true;
116
+ this.debouncedRegenerate.cancel();
117
+ this.poller.stop();
118
+ this.status.isRunning = false;
119
+ this.log('Watch mode stopped');
120
+ }
121
+ /**
122
+ * Get current watch status
123
+ */
124
+ getStatus() {
125
+ return { ...this.status };
126
+ }
127
+ async regenerate() {
128
+ if (this.isShuttingDown) {
129
+ return;
130
+ }
131
+ const startTime = Date.now();
132
+ if (this.watchOptions.clearScreen) {
133
+ this.clearScreen();
134
+ this.logHeader();
135
+ }
136
+ this.log('Regenerating...');
137
+ try {
138
+ let result;
139
+ if (this.options.generatorType === 'generate') {
140
+ result = await (0, generate_1.generateCommand)({
141
+ endpoint: this.options.config.endpoint,
142
+ output: this.options.outputDir ?? this.options.config.output,
143
+ authorization: this.options.authorization,
144
+ verbose: this.watchOptions.verbose,
145
+ skipCustomOperations: this.options.skipCustomOperations,
146
+ });
147
+ }
148
+ else {
149
+ result = await (0, generate_orm_1.generateOrmCommand)({
150
+ endpoint: this.options.config.endpoint,
151
+ output: this.options.outputDir ?? this.options.config.orm?.output,
152
+ authorization: this.options.authorization,
153
+ verbose: this.watchOptions.verbose,
154
+ skipCustomOperations: this.options.skipCustomOperations,
155
+ });
156
+ }
157
+ const duration = Date.now() - startTime;
158
+ if (result.success) {
159
+ this.status.regenerateCount++;
160
+ this.status.lastRegenTime = Date.now();
161
+ this.logSuccess(`Generated in ${duration}ms`);
162
+ if (result.tables && result.tables.length > 0) {
163
+ this.log(` Tables: ${result.tables.length}`);
164
+ }
165
+ if (result.filesWritten && result.filesWritten.length > 0) {
166
+ this.log(` Files: ${result.filesWritten.length}`);
167
+ }
168
+ }
169
+ else {
170
+ this.logError(`Generation failed: ${result.message}`);
171
+ if (result.errors) {
172
+ result.errors.forEach((e) => this.logError(` ${e}`));
173
+ }
174
+ }
175
+ }
176
+ catch (err) {
177
+ const message = err instanceof Error ? err.message : 'Unknown error';
178
+ this.logError(`Generation error: ${message}`);
179
+ }
180
+ this.log(`\nWatching for changes...`);
181
+ }
182
+ setupSignalHandlers() {
183
+ const shutdown = async (signal) => {
184
+ this.log(`\nReceived ${signal}, shutting down...`);
185
+ await this.stop();
186
+ process.exit(0);
187
+ };
188
+ process.on('SIGINT', () => shutdown('SIGINT'));
189
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
190
+ }
191
+ clearScreen() {
192
+ // ANSI escape codes for clearing screen
193
+ process.stdout.write('\x1B[2J\x1B[0f');
194
+ }
195
+ logHeader() {
196
+ const generatorName = this.options.generatorType === 'generate'
197
+ ? 'React Query hooks'
198
+ : 'ORM client';
199
+ console.log(`\n${'─'.repeat(50)}`);
200
+ console.log(`graphql-codegen watch mode (${generatorName})`);
201
+ console.log(`Endpoint: ${this.options.config.endpoint}`);
202
+ console.log(`${'─'.repeat(50)}\n`);
203
+ }
204
+ log(message) {
205
+ const timestamp = new Date().toLocaleTimeString();
206
+ console.log(`[${timestamp}] ${message}`);
207
+ }
208
+ logSuccess(message) {
209
+ const timestamp = new Date().toLocaleTimeString();
210
+ console.log(`[${timestamp}] ✓ ${message}`);
211
+ }
212
+ logError(message) {
213
+ const timestamp = new Date().toLocaleTimeString();
214
+ console.error(`[${timestamp}] ✗ ${message}`);
215
+ }
216
+ }
217
+ exports.WatchOrchestrator = WatchOrchestrator;
218
+ /**
219
+ * Start watch mode for a generator
220
+ */
221
+ async function startWatch(options) {
222
+ const orchestrator = new WatchOrchestrator(options);
223
+ await orchestrator.start();
224
+ // Keep the process alive
225
+ await new Promise(() => {
226
+ // This promise never resolves - the process will exit via signal handlers
227
+ });
228
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Schema polling logic with EventEmitter pattern
3
+ *
4
+ * Uses in-memory hash comparison for efficiency.
5
+ * No file I/O during normal polling - only touchFile is optional file write.
6
+ */
7
+ import { EventEmitter } from 'node:events';
8
+ import type { MetaQueryResponse } from '../introspect/meta-query';
9
+ import type { IntrospectionQueryResponse } from '../../types/introspection';
10
+ import { SchemaCache } from './cache';
11
+ import type { PollResult, WatchOptions } from './types';
12
+ /**
13
+ * Schema poller that periodically introspects a GraphQL endpoint
14
+ * and emits events when the schema changes.
15
+ *
16
+ * Uses in-memory caching for hash comparison - no file I/O overhead.
17
+ */
18
+ export declare class SchemaPoller extends EventEmitter {
19
+ private options;
20
+ private cache;
21
+ private pollTimer;
22
+ private isPolling;
23
+ private consecutiveErrors;
24
+ private readonly MAX_CONSECUTIVE_ERRORS;
25
+ constructor(options: WatchOptions);
26
+ /**
27
+ * Start the polling loop
28
+ */
29
+ start(): void;
30
+ /**
31
+ * Stop the polling loop
32
+ */
33
+ stop(): void;
34
+ /**
35
+ * Perform a single poll operation
36
+ */
37
+ poll(): Promise<PollResult>;
38
+ /**
39
+ * Perform a single poll without starting the loop (for initial generation)
40
+ */
41
+ pollOnce(): Promise<PollResult>;
42
+ /**
43
+ * Seed the cache with current schema hash without emitting events.
44
+ * Call this after initial generation to prevent first poll from triggering regeneration.
45
+ */
46
+ seedCache(): Promise<void>;
47
+ /**
48
+ * Get the current cached schema hash
49
+ */
50
+ getCurrentHash(): string | null;
51
+ /**
52
+ * Get the cache instance for direct access
53
+ */
54
+ getCache(): SchemaCache;
55
+ /**
56
+ * Check if the poller is currently running
57
+ */
58
+ isRunning(): boolean;
59
+ private handleError;
60
+ private createEvent;
61
+ }
62
+ /**
63
+ * Utility to compute schema hash without full poll
64
+ */
65
+ export declare function computeSchemaHash(meta: MetaQueryResponse, schema: IntrospectionQueryResponse): Promise<string>;