@constructive-io/graphql-codegen 4.0.2 → 4.1.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 (93) hide show
  1. package/cli/handler.d.ts +13 -0
  2. package/cli/handler.js +74 -0
  3. package/cli/index.js +11 -57
  4. package/core/codegen/barrel.d.ts +1 -0
  5. package/core/codegen/barrel.js +5 -2
  6. package/core/codegen/cli/arg-mapper.d.ts +4 -0
  7. package/core/codegen/cli/arg-mapper.js +117 -0
  8. package/core/codegen/cli/command-map-generator.d.ts +16 -0
  9. package/core/codegen/cli/command-map-generator.js +338 -0
  10. package/core/codegen/cli/custom-command-generator.d.ts +8 -0
  11. package/core/codegen/cli/custom-command-generator.js +155 -0
  12. package/core/codegen/cli/docs-generator.d.ts +26 -0
  13. package/core/codegen/cli/docs-generator.js +1399 -0
  14. package/core/codegen/cli/executor-generator.d.ts +11 -0
  15. package/core/codegen/cli/executor-generator.js +217 -0
  16. package/core/codegen/cli/index.d.ts +53 -0
  17. package/core/codegen/cli/index.js +153 -0
  18. package/core/codegen/cli/infra-generator.d.ts +9 -0
  19. package/core/codegen/cli/infra-generator.js +1195 -0
  20. package/core/codegen/cli/table-command-generator.d.ts +7 -0
  21. package/core/codegen/cli/table-command-generator.js +323 -0
  22. package/core/codegen/docs-utils.d.ts +30 -0
  23. package/core/codegen/docs-utils.js +122 -0
  24. package/core/codegen/hooks-docs-generator.d.ts +6 -0
  25. package/core/codegen/hooks-docs-generator.js +468 -0
  26. package/core/codegen/orm/docs-generator.d.ts +6 -0
  27. package/core/codegen/orm/docs-generator.js +416 -0
  28. package/core/codegen/target-docs-generator.d.ts +20 -0
  29. package/core/codegen/target-docs-generator.js +110 -0
  30. package/core/database/index.d.ts +0 -12
  31. package/core/database/index.js +2 -19
  32. package/core/generate.d.ts +34 -2
  33. package/core/generate.js +453 -12
  34. package/core/index.d.ts +0 -2
  35. package/core/index.js +0 -2
  36. package/core/introspect/source/database.js +2 -2
  37. package/core/introspect/source/pgpm-module.js +2 -2
  38. package/core/output/index.d.ts +1 -1
  39. package/core/output/index.js +1 -2
  40. package/core/output/writer.d.ts +0 -10
  41. package/core/output/writer.js +0 -31
  42. package/esm/cli/handler.d.ts +13 -0
  43. package/esm/cli/handler.js +71 -0
  44. package/esm/cli/index.js +11 -57
  45. package/esm/core/codegen/barrel.d.ts +1 -0
  46. package/esm/core/codegen/barrel.js +5 -2
  47. package/esm/core/codegen/cli/arg-mapper.d.ts +4 -0
  48. package/esm/core/codegen/cli/arg-mapper.js +80 -0
  49. package/esm/core/codegen/cli/command-map-generator.d.ts +16 -0
  50. package/esm/core/codegen/cli/command-map-generator.js +301 -0
  51. package/esm/core/codegen/cli/custom-command-generator.d.ts +8 -0
  52. package/esm/core/codegen/cli/custom-command-generator.js +119 -0
  53. package/esm/core/codegen/cli/docs-generator.d.ts +26 -0
  54. package/esm/core/codegen/cli/docs-generator.js +1387 -0
  55. package/esm/core/codegen/cli/executor-generator.d.ts +11 -0
  56. package/esm/core/codegen/cli/executor-generator.js +180 -0
  57. package/esm/core/codegen/cli/index.d.ts +53 -0
  58. package/esm/core/codegen/cli/index.js +128 -0
  59. package/esm/core/codegen/cli/infra-generator.d.ts +9 -0
  60. package/esm/core/codegen/cli/infra-generator.js +1156 -0
  61. package/esm/core/codegen/cli/table-command-generator.d.ts +7 -0
  62. package/esm/core/codegen/cli/table-command-generator.js +287 -0
  63. package/esm/core/codegen/docs-utils.d.ts +30 -0
  64. package/esm/core/codegen/docs-utils.js +112 -0
  65. package/esm/core/codegen/hooks-docs-generator.d.ts +6 -0
  66. package/esm/core/codegen/hooks-docs-generator.js +462 -0
  67. package/esm/core/codegen/orm/docs-generator.d.ts +6 -0
  68. package/esm/core/codegen/orm/docs-generator.js +410 -0
  69. package/esm/core/codegen/target-docs-generator.d.ts +20 -0
  70. package/esm/core/codegen/target-docs-generator.js +105 -0
  71. package/esm/core/database/index.d.ts +0 -12
  72. package/esm/core/database/index.js +1 -17
  73. package/esm/core/generate.d.ts +34 -2
  74. package/esm/core/generate.js +417 -12
  75. package/esm/core/index.d.ts +0 -2
  76. package/esm/core/index.js +0 -2
  77. package/esm/core/introspect/source/database.js +2 -2
  78. package/esm/core/introspect/source/pgpm-module.js +2 -2
  79. package/esm/core/output/index.d.ts +1 -1
  80. package/esm/core/output/index.js +1 -1
  81. package/esm/core/output/writer.d.ts +0 -10
  82. package/esm/core/output/writer.js +0 -30
  83. package/esm/generators/index.d.ts +0 -3
  84. package/esm/generators/index.js +0 -3
  85. package/esm/index.d.ts +4 -3
  86. package/esm/index.js +4 -2
  87. package/esm/types/config.d.ts +78 -0
  88. package/generators/index.d.ts +0 -3
  89. package/generators/index.js +0 -3
  90. package/index.d.ts +4 -3
  91. package/index.js +7 -2
  92. package/package.json +8 -7
  93. package/types/config.d.ts +78 -0
@@ -0,0 +1,462 @@
1
+ import { buildSkillFile, formatArgType, getReadmeHeader, getReadmeFooter, gqlTypeToJsonSchemaType, } from './docs-utils';
2
+ import { getTableNames, getScalarFields, getPrimaryKeyInfo, getListQueryHookName, getSingleQueryHookName, getCreateMutationHookName, getUpdateMutationHookName, getDeleteMutationHookName, hasValidPrimaryKey, ucFirst, lcFirst, fieldTypeToTs, } from './utils';
3
+ function getCustomHookName(op) {
4
+ if (op.kind === 'query') {
5
+ return `use${ucFirst(op.name)}Query`;
6
+ }
7
+ return `use${ucFirst(op.name)}Mutation`;
8
+ }
9
+ export function generateHooksReadme(tables, customOperations) {
10
+ const lines = [];
11
+ lines.push(...getReadmeHeader('React Query Hooks'));
12
+ lines.push('## Setup');
13
+ lines.push('');
14
+ lines.push('```typescript');
15
+ lines.push("import { QueryClient, QueryClientProvider } from '@tanstack/react-query';");
16
+ lines.push("import { configure } from './hooks';");
17
+ lines.push('');
18
+ lines.push('configure({');
19
+ lines.push(" endpoint: 'https://api.example.com/graphql',");
20
+ lines.push(" headers: { Authorization: 'Bearer <token>' },");
21
+ lines.push('});');
22
+ lines.push('');
23
+ lines.push('const queryClient = new QueryClient();');
24
+ lines.push('');
25
+ lines.push('function App() {');
26
+ lines.push(' return (');
27
+ lines.push(' <QueryClientProvider client={queryClient}>');
28
+ lines.push(' <YourApp />');
29
+ lines.push(' </QueryClientProvider>');
30
+ lines.push(' );');
31
+ lines.push('}');
32
+ lines.push('```');
33
+ lines.push('');
34
+ lines.push('## Hooks');
35
+ lines.push('');
36
+ lines.push('| Hook | Type | Description |');
37
+ lines.push('|------|------|-------------|');
38
+ for (const table of tables) {
39
+ const { singularName, pluralName } = getTableNames(table);
40
+ lines.push(`| \`${getListQueryHookName(table)}\` | Query | List all ${pluralName} |`);
41
+ if (hasValidPrimaryKey(table)) {
42
+ lines.push(`| \`${getSingleQueryHookName(table)}\` | Query | Get one ${singularName} |`);
43
+ }
44
+ lines.push(`| \`${getCreateMutationHookName(table)}\` | Mutation | Create a ${singularName} |`);
45
+ if (hasValidPrimaryKey(table)) {
46
+ lines.push(`| \`${getUpdateMutationHookName(table)}\` | Mutation | Update a ${singularName} |`);
47
+ lines.push(`| \`${getDeleteMutationHookName(table)}\` | Mutation | Delete a ${singularName} |`);
48
+ }
49
+ }
50
+ for (const op of customOperations) {
51
+ lines.push(`| \`${getCustomHookName(op)}\` | ${ucFirst(op.kind)} | ${op.description || op.name} |`);
52
+ }
53
+ lines.push('');
54
+ if (tables.length > 0) {
55
+ lines.push('## Table Hooks');
56
+ lines.push('');
57
+ for (const table of tables) {
58
+ const { singularName, pluralName } = getTableNames(table);
59
+ const pk = getPrimaryKeyInfo(table)[0];
60
+ const scalarFields = getScalarFields(table);
61
+ lines.push(`### ${table.name}`);
62
+ lines.push('');
63
+ lines.push('```typescript');
64
+ lines.push(`// List all ${pluralName}`);
65
+ lines.push(`const { data, isLoading } = ${getListQueryHookName(table)}({`);
66
+ lines.push(` selection: { fields: { ${scalarFields.map((f) => `${f.name}: true`).join(', ')} } },`);
67
+ lines.push('});');
68
+ lines.push('');
69
+ if (hasValidPrimaryKey(table)) {
70
+ lines.push(`// Get one ${singularName}`);
71
+ lines.push(`const { data: item } = ${getSingleQueryHookName(table)}({`);
72
+ lines.push(` ${pk.name}: '<value>',`);
73
+ lines.push(` selection: { fields: { ${scalarFields.map((f) => `${f.name}: true`).join(', ')} } },`);
74
+ lines.push('});');
75
+ lines.push('');
76
+ }
77
+ lines.push(`// Create a ${singularName}`);
78
+ lines.push(`const { mutate: create } = ${getCreateMutationHookName(table)}({`);
79
+ lines.push(` selection: { fields: { ${pk.name}: true } },`);
80
+ lines.push('});');
81
+ lines.push(`create({ ${scalarFields.filter((f) => f.name !== pk.name && f.name !== 'nodeId' && f.name !== 'createdAt' && f.name !== 'updatedAt').map((f) => `${f.name}: '<value>'`).join(', ')} });`);
82
+ lines.push('```');
83
+ lines.push('');
84
+ }
85
+ }
86
+ if (customOperations.length > 0) {
87
+ lines.push('## Custom Operation Hooks');
88
+ lines.push('');
89
+ for (const op of customOperations) {
90
+ const hookName = getCustomHookName(op);
91
+ lines.push(`### \`${hookName}\``);
92
+ lines.push('');
93
+ lines.push(op.description || op.name);
94
+ lines.push('');
95
+ lines.push(`- **Type:** ${op.kind}`);
96
+ if (op.args.length > 0) {
97
+ lines.push('- **Arguments:**');
98
+ lines.push('');
99
+ lines.push(' | Argument | Type |');
100
+ lines.push(' |----------|------|');
101
+ for (const arg of op.args) {
102
+ lines.push(` | \`${arg.name}\` | ${formatArgType(arg)} |`);
103
+ }
104
+ }
105
+ else {
106
+ lines.push('- **Arguments:** none');
107
+ }
108
+ lines.push('');
109
+ }
110
+ }
111
+ lines.push(...getReadmeFooter());
112
+ return {
113
+ fileName: 'README.md',
114
+ content: lines.join('\n'),
115
+ };
116
+ }
117
+ export function generateHooksAgentsDocs(tables, customOperations) {
118
+ const lines = [];
119
+ lines.push('# React Query Hooks - Agent Reference');
120
+ lines.push('');
121
+ lines.push('> @generated by @constructive-io/graphql-codegen - DO NOT EDIT');
122
+ lines.push('> This document is structured for LLM/agent consumption.');
123
+ lines.push('');
124
+ lines.push('## OVERVIEW');
125
+ lines.push('');
126
+ lines.push('React Query hooks wrapping ORM operations for data fetching and mutations.');
127
+ lines.push('All query hooks return `UseQueryResult`. All mutation hooks return `UseMutationResult`.');
128
+ lines.push('');
129
+ lines.push('## SETUP');
130
+ lines.push('');
131
+ lines.push('```typescript');
132
+ lines.push("import { configure } from './hooks';");
133
+ lines.push("import { QueryClient, QueryClientProvider } from '@tanstack/react-query';");
134
+ lines.push('');
135
+ lines.push("configure({ endpoint: 'https://api.example.com/graphql' });");
136
+ lines.push('const queryClient = new QueryClient();');
137
+ lines.push('// Wrap app in <QueryClientProvider client={queryClient}>');
138
+ lines.push('```');
139
+ lines.push('');
140
+ lines.push('## HOOKS');
141
+ lines.push('');
142
+ for (const table of tables) {
143
+ const { singularName, pluralName } = getTableNames(table);
144
+ const pk = getPrimaryKeyInfo(table)[0];
145
+ const scalarFields = getScalarFields(table);
146
+ lines.push(`### HOOK: ${getListQueryHookName(table)}`);
147
+ lines.push('');
148
+ lines.push(`List all ${pluralName}.`);
149
+ lines.push('');
150
+ lines.push('```');
151
+ lines.push(`TYPE: query`);
152
+ lines.push(`USAGE: ${getListQueryHookName(table)}({ selection: { fields: { ... } } })`);
153
+ lines.push('');
154
+ lines.push('INPUT:');
155
+ lines.push(' selection: { fields: Record<string, boolean> } - Fields to select');
156
+ lines.push('');
157
+ lines.push('OUTPUT: UseQueryResult<Array<{');
158
+ for (const f of scalarFields) {
159
+ lines.push(` ${f.name}: ${fieldTypeToTs(f.type)}`);
160
+ }
161
+ lines.push('}>>');
162
+ lines.push('```');
163
+ lines.push('');
164
+ if (hasValidPrimaryKey(table)) {
165
+ lines.push(`### HOOK: ${getSingleQueryHookName(table)}`);
166
+ lines.push('');
167
+ lines.push(`Get a single ${singularName} by ${pk.name}.`);
168
+ lines.push('');
169
+ lines.push('```');
170
+ lines.push(`TYPE: query`);
171
+ lines.push(`USAGE: ${getSingleQueryHookName(table)}({ ${pk.name}: '<value>', selection: { fields: { ... } } })`);
172
+ lines.push('');
173
+ lines.push('INPUT:');
174
+ lines.push(` ${pk.name}: ${pk.tsType} (required)`);
175
+ lines.push(' selection: { fields: Record<string, boolean> } - Fields to select');
176
+ lines.push('');
177
+ lines.push('OUTPUT: UseQueryResult<{');
178
+ for (const f of scalarFields) {
179
+ lines.push(` ${f.name}: ${fieldTypeToTs(f.type)}`);
180
+ }
181
+ lines.push('}>');
182
+ lines.push('```');
183
+ lines.push('');
184
+ }
185
+ lines.push(`### HOOK: ${getCreateMutationHookName(table)}`);
186
+ lines.push('');
187
+ lines.push(`Create a new ${singularName}.`);
188
+ lines.push('');
189
+ lines.push('```');
190
+ lines.push('TYPE: mutation');
191
+ lines.push(`USAGE: const { mutate } = ${getCreateMutationHookName(table)}({ selection: { fields: { ... } } })`);
192
+ lines.push('');
193
+ lines.push('OUTPUT: UseMutationResult');
194
+ lines.push('```');
195
+ lines.push('');
196
+ if (hasValidPrimaryKey(table)) {
197
+ lines.push(`### HOOK: ${getUpdateMutationHookName(table)}`);
198
+ lines.push('');
199
+ lines.push(`Update an existing ${singularName}.`);
200
+ lines.push('');
201
+ lines.push('```');
202
+ lines.push('TYPE: mutation');
203
+ lines.push(`USAGE: const { mutate } = ${getUpdateMutationHookName(table)}({ selection: { fields: { ... } } })`);
204
+ lines.push('');
205
+ lines.push('OUTPUT: UseMutationResult');
206
+ lines.push('```');
207
+ lines.push('');
208
+ lines.push(`### HOOK: ${getDeleteMutationHookName(table)}`);
209
+ lines.push('');
210
+ lines.push(`Delete a ${singularName}.`);
211
+ lines.push('');
212
+ lines.push('```');
213
+ lines.push('TYPE: mutation');
214
+ lines.push(`USAGE: const { mutate } = ${getDeleteMutationHookName(table)}({})`);
215
+ lines.push('');
216
+ lines.push('OUTPUT: UseMutationResult');
217
+ lines.push('```');
218
+ lines.push('');
219
+ }
220
+ }
221
+ if (customOperations.length > 0) {
222
+ lines.push('## CUSTOM OPERATION HOOKS');
223
+ lines.push('');
224
+ for (const op of customOperations) {
225
+ const hookName = getCustomHookName(op);
226
+ lines.push(`### HOOK: ${hookName}`);
227
+ lines.push('');
228
+ lines.push(op.description || op.name);
229
+ lines.push('');
230
+ lines.push('```');
231
+ lines.push(`TYPE: ${op.kind}`);
232
+ if (op.args.length > 0) {
233
+ if (op.kind === 'mutation') {
234
+ lines.push(`USAGE: const { mutate } = ${hookName}()`);
235
+ lines.push(` mutate({ ${op.args.map((a) => `${a.name}: <value>`).join(', ')} })`);
236
+ }
237
+ else {
238
+ lines.push(`USAGE: ${hookName}({ ${op.args.map((a) => `${a.name}: <value>`).join(', ')} })`);
239
+ }
240
+ lines.push('');
241
+ lines.push('INPUT:');
242
+ for (const arg of op.args) {
243
+ lines.push(` ${arg.name}: ${formatArgType(arg)}`);
244
+ }
245
+ }
246
+ else {
247
+ lines.push(`USAGE: ${hookName}()`);
248
+ lines.push('');
249
+ lines.push('INPUT: none');
250
+ }
251
+ lines.push('');
252
+ lines.push(`OUTPUT: ${op.kind === 'query' ? 'UseQueryResult' : 'UseMutationResult'}`);
253
+ lines.push('```');
254
+ lines.push('');
255
+ }
256
+ }
257
+ return {
258
+ fileName: 'AGENTS.md',
259
+ content: lines.join('\n'),
260
+ };
261
+ }
262
+ export function getHooksMcpTools(tables, customOperations) {
263
+ const tools = [];
264
+ for (const table of tables) {
265
+ const { singularName, pluralName } = getTableNames(table);
266
+ const pk = getPrimaryKeyInfo(table)[0];
267
+ const scalarFields = getScalarFields(table);
268
+ tools.push({
269
+ name: `hooks_${lcFirst(pluralName)}_query`,
270
+ description: `React Query hook to list all ${pluralName}`,
271
+ inputSchema: {
272
+ type: 'object',
273
+ properties: {
274
+ fields: {
275
+ type: 'object',
276
+ description: `Fields to select: { ${scalarFields.map((f) => f.name).join(', ')} }`,
277
+ },
278
+ },
279
+ },
280
+ });
281
+ if (hasValidPrimaryKey(table)) {
282
+ tools.push({
283
+ name: `hooks_${lcFirst(singularName)}_query`,
284
+ description: `React Query hook to get a single ${singularName} by ${pk.name}`,
285
+ inputSchema: {
286
+ type: 'object',
287
+ properties: {
288
+ [pk.name]: {
289
+ type: gqlTypeToJsonSchemaType(pk.gqlType),
290
+ description: `${table.name} ${pk.name}`,
291
+ },
292
+ },
293
+ required: [pk.name],
294
+ },
295
+ });
296
+ }
297
+ tools.push({
298
+ name: `hooks_create_${lcFirst(singularName)}_mutation`,
299
+ description: `React Query mutation hook to create a ${singularName}`,
300
+ inputSchema: {
301
+ type: 'object',
302
+ properties: Object.fromEntries(scalarFields
303
+ .filter((f) => f.name !== pk.name &&
304
+ f.name !== 'nodeId' &&
305
+ f.name !== 'createdAt' &&
306
+ f.name !== 'updatedAt')
307
+ .map((f) => [
308
+ f.name,
309
+ {
310
+ type: gqlTypeToJsonSchemaType(f.type.gqlType),
311
+ description: `${table.name} ${f.name}`,
312
+ },
313
+ ])),
314
+ },
315
+ });
316
+ if (hasValidPrimaryKey(table)) {
317
+ tools.push({
318
+ name: `hooks_update_${lcFirst(singularName)}_mutation`,
319
+ description: `React Query mutation hook to update a ${singularName}`,
320
+ inputSchema: {
321
+ type: 'object',
322
+ properties: {
323
+ [pk.name]: {
324
+ type: gqlTypeToJsonSchemaType(pk.gqlType),
325
+ description: `${table.name} ${pk.name}`,
326
+ },
327
+ },
328
+ required: [pk.name],
329
+ },
330
+ });
331
+ tools.push({
332
+ name: `hooks_delete_${lcFirst(singularName)}_mutation`,
333
+ description: `React Query mutation hook to delete a ${singularName}`,
334
+ inputSchema: {
335
+ type: 'object',
336
+ properties: {
337
+ [pk.name]: {
338
+ type: gqlTypeToJsonSchemaType(pk.gqlType),
339
+ description: `${table.name} ${pk.name}`,
340
+ },
341
+ },
342
+ required: [pk.name],
343
+ },
344
+ });
345
+ }
346
+ }
347
+ for (const op of customOperations) {
348
+ const hookName = getCustomHookName(op);
349
+ const props = {};
350
+ const required = [];
351
+ for (const arg of op.args) {
352
+ const isRequired = arg.type.kind === 'NON_NULL';
353
+ const baseType = isRequired && arg.type.ofType ? arg.type.ofType : arg.type;
354
+ props[arg.name] = {
355
+ type: gqlTypeToJsonSchemaType(baseType.name ?? 'String'),
356
+ description: arg.description || arg.name,
357
+ };
358
+ if (isRequired) {
359
+ required.push(arg.name);
360
+ }
361
+ }
362
+ tools.push({
363
+ name: `hooks_${hookName}`,
364
+ description: op.description || `${ucFirst(op.kind)} hook for ${op.name}`,
365
+ inputSchema: {
366
+ type: 'object',
367
+ properties: props,
368
+ ...(required.length > 0 ? { required } : {}),
369
+ },
370
+ });
371
+ }
372
+ return tools;
373
+ }
374
+ export function generateHooksSkills(tables, customOperations) {
375
+ const files = [];
376
+ for (const table of tables) {
377
+ const { singularName, pluralName } = getTableNames(table);
378
+ const pk = getPrimaryKeyInfo(table)[0];
379
+ const scalarFields = getScalarFields(table);
380
+ const selectFields = scalarFields
381
+ .map((f) => `${f.name}: true`)
382
+ .join(', ');
383
+ files.push({
384
+ fileName: `skills/${lcFirst(singularName)}.md`,
385
+ content: buildSkillFile({
386
+ name: `hooks-${lcFirst(singularName)}`,
387
+ description: `React Query hooks for ${table.name} data operations`,
388
+ language: 'typescript',
389
+ usage: [
390
+ `${getListQueryHookName(table)}({ selection: { fields: { ${selectFields} } } })`,
391
+ ...(hasValidPrimaryKey(table)
392
+ ? [
393
+ `${getSingleQueryHookName(table)}({ ${pk.name}: '<value>', selection: { fields: { ${selectFields} } } })`,
394
+ ]
395
+ : []),
396
+ `${getCreateMutationHookName(table)}({ selection: { fields: { ${pk.name}: true } } })`,
397
+ ...(hasValidPrimaryKey(table)
398
+ ? [
399
+ `${getUpdateMutationHookName(table)}({ selection: { fields: { ${pk.name}: true } } })`,
400
+ `${getDeleteMutationHookName(table)}({})`,
401
+ ]
402
+ : []),
403
+ ],
404
+ examples: [
405
+ {
406
+ description: `List all ${pluralName}`,
407
+ code: [
408
+ `const { data, isLoading } = ${getListQueryHookName(table)}({`,
409
+ ` selection: { fields: { ${selectFields} } },`,
410
+ '});',
411
+ ],
412
+ },
413
+ {
414
+ description: `Create a ${singularName}`,
415
+ code: [
416
+ `const { mutate } = ${getCreateMutationHookName(table)}({`,
417
+ ` selection: { fields: { ${pk.name}: true } },`,
418
+ '});',
419
+ `mutate({ ${scalarFields.filter((f) => f.name !== pk.name && f.name !== 'nodeId' && f.name !== 'createdAt' && f.name !== 'updatedAt').map((f) => `${f.name}: '<value>'`).join(', ')} });`,
420
+ ],
421
+ },
422
+ ],
423
+ }),
424
+ });
425
+ }
426
+ for (const op of customOperations) {
427
+ const hookName = getCustomHookName(op);
428
+ const callArgs = op.args.length > 0
429
+ ? `{ ${op.args.map((a) => `${a.name}: '<value>'`).join(', ')} }`
430
+ : '';
431
+ files.push({
432
+ fileName: `skills/${op.name}.md`,
433
+ content: buildSkillFile({
434
+ name: `hooks-${op.name}`,
435
+ description: op.description ||
436
+ `React Query ${op.kind} hook for ${op.name}`,
437
+ language: 'typescript',
438
+ usage: [
439
+ op.kind === 'mutation'
440
+ ? `const { mutate } = ${hookName}(); mutate(${callArgs});`
441
+ : `${hookName}(${callArgs})`,
442
+ ],
443
+ examples: [
444
+ {
445
+ description: `Use ${hookName}`,
446
+ code: op.kind === 'mutation'
447
+ ? [
448
+ `const { mutate, isLoading } = ${hookName}();`,
449
+ ...(callArgs
450
+ ? [`mutate(${callArgs});`]
451
+ : ['mutate();']),
452
+ ]
453
+ : [
454
+ `const { data, isLoading } = ${hookName}(${callArgs});`,
455
+ ],
456
+ },
457
+ ],
458
+ }),
459
+ });
460
+ }
461
+ return files;
462
+ }
@@ -0,0 +1,6 @@
1
+ import type { CleanOperation, CleanTable } from '../../../types/schema';
2
+ import type { GeneratedDocFile, McpTool } from '../docs-utils';
3
+ export declare function generateOrmReadme(tables: CleanTable[], customOperations: CleanOperation[]): GeneratedDocFile;
4
+ export declare function generateOrmAgentsDocs(tables: CleanTable[], customOperations: CleanOperation[]): GeneratedDocFile;
5
+ export declare function getOrmMcpTools(tables: CleanTable[], customOperations: CleanOperation[]): McpTool[];
6
+ export declare function generateOrmSkills(tables: CleanTable[], customOperations: CleanOperation[]): GeneratedDocFile[];