@constructive-io/graphql-codegen 4.5.3 → 4.6.1
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.
- package/core/codegen/hooks-docs-generator.js +16 -16
- package/core/codegen/mutations.js +6 -6
- package/core/codegen/orm/custom-ops-generator.d.ts +2 -2
- package/core/codegen/orm/custom-ops-generator.js +15 -6
- package/core/codegen/orm/docs-generator.js +6 -6
- package/core/codegen/orm/index.js +4 -3
- package/core/codegen/orm/input-types-generator.d.ts +1 -1
- package/core/codegen/orm/input-types-generator.js +41 -17
- package/core/codegen/queries.js +12 -10
- package/core/codegen/schema-types-generator.d.ts +2 -0
- package/core/codegen/schema-types-generator.js +41 -12
- package/core/codegen/shared/index.js +2 -0
- package/core/codegen/utils.d.ts +14 -0
- package/core/codegen/utils.js +87 -0
- package/core/introspect/infer-tables.d.ts +5 -0
- package/core/introspect/infer-tables.js +54 -4
- package/core/pipeline/index.js +2 -1
- package/esm/core/codegen/hooks-docs-generator.js +16 -16
- package/esm/core/codegen/mutations.js +6 -6
- package/esm/core/codegen/orm/custom-ops-generator.d.ts +2 -2
- package/esm/core/codegen/orm/custom-ops-generator.js +17 -8
- package/esm/core/codegen/orm/docs-generator.js +6 -6
- package/esm/core/codegen/orm/index.js +4 -3
- package/esm/core/codegen/orm/input-types-generator.d.ts +1 -1
- package/esm/core/codegen/orm/input-types-generator.js +43 -19
- package/esm/core/codegen/queries.js +12 -10
- package/esm/core/codegen/schema-types-generator.d.ts +2 -0
- package/esm/core/codegen/schema-types-generator.js +43 -14
- package/esm/core/codegen/shared/index.js +2 -0
- package/esm/core/codegen/utils.d.ts +14 -0
- package/esm/core/codegen/utils.js +86 -0
- package/esm/core/introspect/infer-tables.d.ts +5 -0
- package/esm/core/introspect/infer-tables.js +55 -5
- package/esm/core/pipeline/index.js +2 -1
- package/esm/generators/field-selector.js +32 -7
- package/esm/generators/mutations.d.ts +1 -2
- package/esm/generators/mutations.js +12 -9
- package/esm/generators/naming-helpers.d.ts +48 -0
- package/esm/generators/naming-helpers.js +154 -0
- package/esm/generators/select.d.ts +1 -12
- package/esm/generators/select.js +96 -71
- package/esm/types/config.d.ts +6 -0
- package/esm/types/config.js +1 -0
- package/esm/types/query.d.ts +9 -0
- package/esm/types/schema.d.ts +8 -0
- package/generators/field-selector.js +32 -7
- package/generators/mutations.d.ts +1 -2
- package/generators/mutations.js +12 -9
- package/generators/naming-helpers.d.ts +48 -0
- package/generators/naming-helpers.js +169 -0
- package/generators/select.d.ts +1 -12
- package/generators/select.js +98 -72
- package/package.json +6 -6
- package/types/config.d.ts +6 -0
- package/types/config.js +1 -0
- package/types/query.d.ts +9 -0
- package/types/schema.d.ts +8 -0
|
@@ -43,14 +43,14 @@ function generateHooksReadme(tables, customOperations) {
|
|
|
43
43
|
lines.push('|------|------|-------------|');
|
|
44
44
|
for (const table of tables) {
|
|
45
45
|
const { singularName, pluralName } = (0, utils_1.getTableNames)(table);
|
|
46
|
-
lines.push(`| \`${(0, utils_1.getListQueryHookName)(table)}\` | Query | List all ${pluralName} |`);
|
|
46
|
+
lines.push(`| \`${(0, utils_1.getListQueryHookName)(table)}\` | Query | ${table.description || `List all ${pluralName}`} |`);
|
|
47
47
|
if ((0, utils_1.hasValidPrimaryKey)(table)) {
|
|
48
|
-
lines.push(`| \`${(0, utils_1.getSingleQueryHookName)(table)}\` | Query | Get one ${singularName} |`);
|
|
48
|
+
lines.push(`| \`${(0, utils_1.getSingleQueryHookName)(table)}\` | Query | ${table.description || `Get one ${singularName}`} |`);
|
|
49
49
|
}
|
|
50
|
-
lines.push(`| \`${(0, utils_1.getCreateMutationHookName)(table)}\` | Mutation | Create a ${singularName} |`);
|
|
50
|
+
lines.push(`| \`${(0, utils_1.getCreateMutationHookName)(table)}\` | Mutation | ${table.description || `Create a ${singularName}`} |`);
|
|
51
51
|
if ((0, utils_1.hasValidPrimaryKey)(table)) {
|
|
52
|
-
lines.push(`| \`${(0, utils_1.getUpdateMutationHookName)(table)}\` | Mutation | Update a ${singularName} |`);
|
|
53
|
-
lines.push(`| \`${(0, utils_1.getDeleteMutationHookName)(table)}\` | Mutation | Delete a ${singularName} |`);
|
|
52
|
+
lines.push(`| \`${(0, utils_1.getUpdateMutationHookName)(table)}\` | Mutation | ${table.description || `Update a ${singularName}`} |`);
|
|
53
|
+
lines.push(`| \`${(0, utils_1.getDeleteMutationHookName)(table)}\` | Mutation | ${table.description || `Delete a ${singularName}`} |`);
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
for (const op of customOperations) {
|
|
@@ -151,7 +151,7 @@ function generateHooksAgentsDocs(tables, customOperations) {
|
|
|
151
151
|
const scalarFields = (0, utils_1.getScalarFields)(table);
|
|
152
152
|
lines.push(`### HOOK: ${(0, utils_1.getListQueryHookName)(table)}`);
|
|
153
153
|
lines.push('');
|
|
154
|
-
lines.push(`List all ${pluralName}.`);
|
|
154
|
+
lines.push(`${table.description || `List all ${pluralName}`}.`);
|
|
155
155
|
lines.push('');
|
|
156
156
|
lines.push('```');
|
|
157
157
|
lines.push(`TYPE: query`);
|
|
@@ -170,7 +170,7 @@ function generateHooksAgentsDocs(tables, customOperations) {
|
|
|
170
170
|
if ((0, utils_1.hasValidPrimaryKey)(table)) {
|
|
171
171
|
lines.push(`### HOOK: ${(0, utils_1.getSingleQueryHookName)(table)}`);
|
|
172
172
|
lines.push('');
|
|
173
|
-
lines.push(`Get a single ${singularName} by ${pk.name}.`);
|
|
173
|
+
lines.push(`${table.description || `Get a single ${singularName} by ${pk.name}`}.`);
|
|
174
174
|
lines.push('');
|
|
175
175
|
lines.push('```');
|
|
176
176
|
lines.push(`TYPE: query`);
|
|
@@ -190,7 +190,7 @@ function generateHooksAgentsDocs(tables, customOperations) {
|
|
|
190
190
|
}
|
|
191
191
|
lines.push(`### HOOK: ${(0, utils_1.getCreateMutationHookName)(table)}`);
|
|
192
192
|
lines.push('');
|
|
193
|
-
lines.push(`Create a new ${singularName}.`);
|
|
193
|
+
lines.push(`${table.description || `Create a new ${singularName}`}.`);
|
|
194
194
|
lines.push('');
|
|
195
195
|
lines.push('```');
|
|
196
196
|
lines.push('TYPE: mutation');
|
|
@@ -202,7 +202,7 @@ function generateHooksAgentsDocs(tables, customOperations) {
|
|
|
202
202
|
if ((0, utils_1.hasValidPrimaryKey)(table)) {
|
|
203
203
|
lines.push(`### HOOK: ${(0, utils_1.getUpdateMutationHookName)(table)}`);
|
|
204
204
|
lines.push('');
|
|
205
|
-
lines.push(`Update an existing ${singularName}.`);
|
|
205
|
+
lines.push(`${table.description || `Update an existing ${singularName}`}.`);
|
|
206
206
|
lines.push('');
|
|
207
207
|
lines.push('```');
|
|
208
208
|
lines.push('TYPE: mutation');
|
|
@@ -213,7 +213,7 @@ function generateHooksAgentsDocs(tables, customOperations) {
|
|
|
213
213
|
lines.push('');
|
|
214
214
|
lines.push(`### HOOK: ${(0, utils_1.getDeleteMutationHookName)(table)}`);
|
|
215
215
|
lines.push('');
|
|
216
|
-
lines.push(`Delete a ${singularName}.`);
|
|
216
|
+
lines.push(`${table.description || `Delete a ${singularName}`}.`);
|
|
217
217
|
lines.push('');
|
|
218
218
|
lines.push('```');
|
|
219
219
|
lines.push('TYPE: mutation');
|
|
@@ -273,7 +273,7 @@ function getHooksMcpTools(tables, customOperations) {
|
|
|
273
273
|
const scalarFields = (0, utils_1.getScalarFields)(table);
|
|
274
274
|
tools.push({
|
|
275
275
|
name: `hooks_${(0, utils_1.lcFirst)(pluralName)}_query`,
|
|
276
|
-
description: `React Query hook to list all ${pluralName}`,
|
|
276
|
+
description: table.description || `React Query hook to list all ${pluralName}`,
|
|
277
277
|
inputSchema: {
|
|
278
278
|
type: 'object',
|
|
279
279
|
properties: {
|
|
@@ -287,7 +287,7 @@ function getHooksMcpTools(tables, customOperations) {
|
|
|
287
287
|
if ((0, utils_1.hasValidPrimaryKey)(table)) {
|
|
288
288
|
tools.push({
|
|
289
289
|
name: `hooks_${(0, utils_1.lcFirst)(singularName)}_query`,
|
|
290
|
-
description: `React Query hook to get a single ${singularName} by ${pk.name}`,
|
|
290
|
+
description: table.description || `React Query hook to get a single ${singularName} by ${pk.name}`,
|
|
291
291
|
inputSchema: {
|
|
292
292
|
type: 'object',
|
|
293
293
|
properties: {
|
|
@@ -302,7 +302,7 @@ function getHooksMcpTools(tables, customOperations) {
|
|
|
302
302
|
}
|
|
303
303
|
tools.push({
|
|
304
304
|
name: `hooks_create_${(0, utils_1.lcFirst)(singularName)}_mutation`,
|
|
305
|
-
description: `React Query mutation hook to create a ${singularName}`,
|
|
305
|
+
description: table.description || `React Query mutation hook to create a ${singularName}`,
|
|
306
306
|
inputSchema: {
|
|
307
307
|
type: 'object',
|
|
308
308
|
properties: Object.fromEntries(scalarFields
|
|
@@ -322,7 +322,7 @@ function getHooksMcpTools(tables, customOperations) {
|
|
|
322
322
|
if ((0, utils_1.hasValidPrimaryKey)(table)) {
|
|
323
323
|
tools.push({
|
|
324
324
|
name: `hooks_update_${(0, utils_1.lcFirst)(singularName)}_mutation`,
|
|
325
|
-
description: `React Query mutation hook to update a ${singularName}`,
|
|
325
|
+
description: table.description || `React Query mutation hook to update a ${singularName}`,
|
|
326
326
|
inputSchema: {
|
|
327
327
|
type: 'object',
|
|
328
328
|
properties: {
|
|
@@ -336,7 +336,7 @@ function getHooksMcpTools(tables, customOperations) {
|
|
|
336
336
|
});
|
|
337
337
|
tools.push({
|
|
338
338
|
name: `hooks_delete_${(0, utils_1.lcFirst)(singularName)}_mutation`,
|
|
339
|
-
description: `React Query mutation hook to delete a ${singularName}`,
|
|
339
|
+
description: table.description || `React Query mutation hook to delete a ${singularName}`,
|
|
340
340
|
inputSchema: {
|
|
341
341
|
type: 'object',
|
|
342
342
|
properties: {
|
|
@@ -390,7 +390,7 @@ function generateHooksSkills(tables, customOperations) {
|
|
|
390
390
|
fileName: `skills/${(0, utils_1.lcFirst)(singularName)}.md`,
|
|
391
391
|
content: (0, docs_utils_1.buildSkillFile)({
|
|
392
392
|
name: `hooks-${(0, utils_1.lcFirst)(singularName)}`,
|
|
393
|
-
description: `React Query hooks for ${table.name} data operations`,
|
|
393
|
+
description: table.description || `React Query hooks for ${table.name} data operations`,
|
|
394
394
|
language: 'typescript',
|
|
395
395
|
usage: [
|
|
396
396
|
`${(0, utils_1.getListQueryHookName)(table)}({ selection: { fields: { ${selectFields} } } })`,
|
|
@@ -115,7 +115,7 @@ function generateCreateMutationHook(table, options = {}) {
|
|
|
115
115
|
]);
|
|
116
116
|
const o1 = (0, hooks_ast_1.exportDeclareFunction)(hookName, (0, hooks_ast_1.createSTypeParam)(selectTypeName), [(0, hooks_ast_1.createFunctionParam)('params', o1ParamType)], (0, hooks_ast_1.useMutationResultType)(resultType((0, hooks_ast_1.sRef)()), createVarType));
|
|
117
117
|
(0, hooks_ast_1.addJSDocComment)(o1, [
|
|
118
|
-
`Mutation hook for creating a ${typeName}`,
|
|
118
|
+
table.description || `Mutation hook for creating a ${typeName}`,
|
|
119
119
|
'',
|
|
120
120
|
'@example',
|
|
121
121
|
'```tsx',
|
|
@@ -168,7 +168,7 @@ function generateCreateMutationHook(table, options = {}) {
|
|
|
168
168
|
statements.push((0, hooks_ast_1.exportFunction)(hookName, null, [(0, hooks_ast_1.createFunctionParam)('params', implParamType)], body));
|
|
169
169
|
return {
|
|
170
170
|
fileName: (0, utils_1.getCreateMutationFileName)(table),
|
|
171
|
-
content: (0, hooks_ast_1.generateHookFileCode)(`Create mutation hook for ${typeName}`, statements),
|
|
171
|
+
content: (0, hooks_ast_1.generateHookFileCode)(table.description || `Create mutation hook for ${typeName}`, statements),
|
|
172
172
|
};
|
|
173
173
|
}
|
|
174
174
|
function generateUpdateMutationHook(table, options = {}) {
|
|
@@ -224,7 +224,7 @@ function generateUpdateMutationHook(table, options = {}) {
|
|
|
224
224
|
]);
|
|
225
225
|
const o1 = (0, hooks_ast_1.exportDeclareFunction)(hookName, (0, hooks_ast_1.createSTypeParam)(selectTypeName), [(0, hooks_ast_1.createFunctionParam)('params', o1ParamType)], (0, hooks_ast_1.useMutationResultType)(resultType((0, hooks_ast_1.sRef)()), updateVarType));
|
|
226
226
|
(0, hooks_ast_1.addJSDocComment)(o1, [
|
|
227
|
-
`Mutation hook for updating a ${typeName}`,
|
|
227
|
+
table.description || `Mutation hook for updating a ${typeName}`,
|
|
228
228
|
'',
|
|
229
229
|
'@example',
|
|
230
230
|
'```tsx',
|
|
@@ -295,7 +295,7 @@ function generateUpdateMutationHook(table, options = {}) {
|
|
|
295
295
|
statements.push((0, hooks_ast_1.exportFunction)(hookName, null, [(0, hooks_ast_1.createFunctionParam)('params', implParamType)], body));
|
|
296
296
|
return {
|
|
297
297
|
fileName: (0, utils_1.getUpdateMutationFileName)(table),
|
|
298
|
-
content: (0, hooks_ast_1.generateHookFileCode)(`Update mutation hook for ${typeName}`, statements),
|
|
298
|
+
content: (0, hooks_ast_1.generateHookFileCode)(table.description || `Update mutation hook for ${typeName}`, statements),
|
|
299
299
|
};
|
|
300
300
|
}
|
|
301
301
|
function generateDeleteMutationHook(table, options = {}) {
|
|
@@ -348,7 +348,7 @@ function generateDeleteMutationHook(table, options = {}) {
|
|
|
348
348
|
]);
|
|
349
349
|
const o1 = (0, hooks_ast_1.exportDeclareFunction)(hookName, (0, hooks_ast_1.createSTypeParam)(selectTypeName), [(0, hooks_ast_1.createFunctionParam)('params', o1ParamType)], (0, hooks_ast_1.useMutationResultType)(resultType((0, hooks_ast_1.sRef)()), deleteVarType));
|
|
350
350
|
(0, hooks_ast_1.addJSDocComment)(o1, [
|
|
351
|
-
`Mutation hook for deleting a ${typeName} with typed selection`,
|
|
351
|
+
table.description || `Mutation hook for deleting a ${typeName} with typed selection`,
|
|
352
352
|
'',
|
|
353
353
|
'@example',
|
|
354
354
|
'```tsx',
|
|
@@ -413,7 +413,7 @@ function generateDeleteMutationHook(table, options = {}) {
|
|
|
413
413
|
statements.push((0, hooks_ast_1.exportFunction)(hookName, null, [(0, hooks_ast_1.createFunctionParam)('params', implParamType)], body));
|
|
414
414
|
return {
|
|
415
415
|
fileName: (0, utils_1.getDeleteMutationFileName)(table),
|
|
416
|
-
content: (0, hooks_ast_1.generateHookFileCode)(`Delete mutation hook for ${typeName}`, statements),
|
|
416
|
+
content: (0, hooks_ast_1.generateHookFileCode)(table.description || `Delete mutation hook for ${typeName}`, statements),
|
|
417
417
|
};
|
|
418
418
|
}
|
|
419
419
|
function generateAllMutationHooks(tables, options = {}) {
|
|
@@ -6,8 +6,8 @@ export interface GeneratedCustomOpsFile {
|
|
|
6
6
|
/**
|
|
7
7
|
* Generate the query/index.ts file for custom query operations
|
|
8
8
|
*/
|
|
9
|
-
export declare function generateCustomQueryOpsFile(operations: CleanOperation[]): GeneratedCustomOpsFile;
|
|
9
|
+
export declare function generateCustomQueryOpsFile(operations: CleanOperation[], comments?: boolean): GeneratedCustomOpsFile;
|
|
10
10
|
/**
|
|
11
11
|
* Generate the mutation/index.ts file for custom mutation operations
|
|
12
12
|
*/
|
|
13
|
-
export declare function generateCustomMutationOpsFile(operations: CleanOperation[]): GeneratedCustomOpsFile;
|
|
13
|
+
export declare function generateCustomMutationOpsFile(operations: CleanOperation[], comments?: boolean): GeneratedCustomOpsFile;
|
|
@@ -104,7 +104,7 @@ function createImportDeclaration(moduleSpecifier, namedImports, typeOnly = false
|
|
|
104
104
|
decl.importKind = typeOnly ? 'type' : 'value';
|
|
105
105
|
return decl;
|
|
106
106
|
}
|
|
107
|
-
function createVariablesInterface(op) {
|
|
107
|
+
function createVariablesInterface(op, comments = true) {
|
|
108
108
|
if (op.args.length === 0)
|
|
109
109
|
return null;
|
|
110
110
|
const varTypeName = `${(0, utils_1.ucFirst)(op.name)}Variables`;
|
|
@@ -112,10 +112,19 @@ function createVariablesInterface(op) {
|
|
|
112
112
|
const optional = !(0, type_resolver_1.isTypeRequired)(arg.type);
|
|
113
113
|
const prop = t.tsPropertySignature(t.identifier(arg.name), t.tsTypeAnnotation(parseTypeAnnotation((0, type_resolver_1.typeRefToTsType)(arg.type))));
|
|
114
114
|
prop.optional = optional;
|
|
115
|
+
const argDescription = (0, utils_1.stripSmartComments)(arg.description, comments);
|
|
116
|
+
if (argDescription) {
|
|
117
|
+
(0, babel_ast_1.addJSDocComment)(prop, argDescription.split('\n'));
|
|
118
|
+
}
|
|
115
119
|
return prop;
|
|
116
120
|
});
|
|
117
121
|
const interfaceDecl = t.tsInterfaceDeclaration(t.identifier(varTypeName), null, null, t.tsInterfaceBody(props));
|
|
118
|
-
|
|
122
|
+
const exportDecl = t.exportNamedDeclaration(interfaceDecl);
|
|
123
|
+
const opDescription = (0, utils_1.stripSmartComments)(op.description, comments);
|
|
124
|
+
if (opDescription) {
|
|
125
|
+
(0, babel_ast_1.addJSDocComment)(exportDecl, [`Variables for ${op.name}`, opDescription]);
|
|
126
|
+
}
|
|
127
|
+
return exportDecl;
|
|
119
128
|
}
|
|
120
129
|
function parseTypeAnnotation(typeStr) {
|
|
121
130
|
if (typeStr === 'string')
|
|
@@ -287,7 +296,7 @@ function buildOperationMethod(op, operationType) {
|
|
|
287
296
|
/**
|
|
288
297
|
* Generate the query/index.ts file for custom query operations
|
|
289
298
|
*/
|
|
290
|
-
function generateCustomQueryOpsFile(operations) {
|
|
299
|
+
function generateCustomQueryOpsFile(operations, comments = true) {
|
|
291
300
|
const statements = [];
|
|
292
301
|
// Collect all input type names and payload type names
|
|
293
302
|
const inputTypeNames = collectInputTypeNamesFromOps(operations);
|
|
@@ -315,7 +324,7 @@ function generateCustomQueryOpsFile(operations) {
|
|
|
315
324
|
statements.push(createImportDeclaration('../input-types', ['connectionFieldsMap']));
|
|
316
325
|
// Generate variable interfaces
|
|
317
326
|
for (const op of operations) {
|
|
318
|
-
const varInterface = createVariablesInterface(op);
|
|
327
|
+
const varInterface = createVariablesInterface(op, comments);
|
|
319
328
|
if (varInterface)
|
|
320
329
|
statements.push(varInterface);
|
|
321
330
|
}
|
|
@@ -337,7 +346,7 @@ function generateCustomQueryOpsFile(operations) {
|
|
|
337
346
|
/**
|
|
338
347
|
* Generate the mutation/index.ts file for custom mutation operations
|
|
339
348
|
*/
|
|
340
|
-
function generateCustomMutationOpsFile(operations) {
|
|
349
|
+
function generateCustomMutationOpsFile(operations, comments = true) {
|
|
341
350
|
const statements = [];
|
|
342
351
|
// Collect all input type names and payload type names
|
|
343
352
|
const inputTypeNames = collectInputTypeNamesFromOps(operations);
|
|
@@ -365,7 +374,7 @@ function generateCustomMutationOpsFile(operations) {
|
|
|
365
374
|
statements.push(createImportDeclaration('../input-types', ['connectionFieldsMap']));
|
|
366
375
|
// Generate variable interfaces
|
|
367
376
|
for (const op of operations) {
|
|
368
|
-
const varInterface = createVariablesInterface(op);
|
|
377
|
+
const varInterface = createVariablesInterface(op, comments);
|
|
369
378
|
if (varInterface)
|
|
370
379
|
statements.push(varInterface);
|
|
371
380
|
}
|
|
@@ -230,7 +230,7 @@ function getOrmMcpTools(tables, customOperations) {
|
|
|
230
230
|
const editableFields = (0, docs_utils_1.getEditableFields)(table);
|
|
231
231
|
tools.push({
|
|
232
232
|
name: `orm_${(0, utils_1.lcFirst)(singularName)}_findMany`,
|
|
233
|
-
description: `List all ${table.name} records via ORM`,
|
|
233
|
+
description: table.description || `List all ${table.name} records via ORM`,
|
|
234
234
|
inputSchema: {
|
|
235
235
|
type: 'object',
|
|
236
236
|
properties: {
|
|
@@ -247,7 +247,7 @@ function getOrmMcpTools(tables, customOperations) {
|
|
|
247
247
|
});
|
|
248
248
|
tools.push({
|
|
249
249
|
name: `orm_${(0, utils_1.lcFirst)(singularName)}_findOne`,
|
|
250
|
-
description: `Get a single ${table.name} record by ${pk.name}`,
|
|
250
|
+
description: table.description || `Get a single ${table.name} record by ${pk.name}`,
|
|
251
251
|
inputSchema: {
|
|
252
252
|
type: 'object',
|
|
253
253
|
properties: {
|
|
@@ -268,7 +268,7 @@ function getOrmMcpTools(tables, customOperations) {
|
|
|
268
268
|
}
|
|
269
269
|
tools.push({
|
|
270
270
|
name: `orm_${(0, utils_1.lcFirst)(singularName)}_create`,
|
|
271
|
-
description: `Create a new ${table.name} record`,
|
|
271
|
+
description: table.description || `Create a new ${table.name} record`,
|
|
272
272
|
inputSchema: {
|
|
273
273
|
type: 'object',
|
|
274
274
|
properties: createProps,
|
|
@@ -289,7 +289,7 @@ function getOrmMcpTools(tables, customOperations) {
|
|
|
289
289
|
}
|
|
290
290
|
tools.push({
|
|
291
291
|
name: `orm_${(0, utils_1.lcFirst)(singularName)}_update`,
|
|
292
|
-
description: `Update an existing ${table.name} record`,
|
|
292
|
+
description: table.description || `Update an existing ${table.name} record`,
|
|
293
293
|
inputSchema: {
|
|
294
294
|
type: 'object',
|
|
295
295
|
properties: updateProps,
|
|
@@ -298,7 +298,7 @@ function getOrmMcpTools(tables, customOperations) {
|
|
|
298
298
|
});
|
|
299
299
|
tools.push({
|
|
300
300
|
name: `orm_${(0, utils_1.lcFirst)(singularName)}_delete`,
|
|
301
|
-
description: `Delete a ${table.name} record by ${pk.name}`,
|
|
301
|
+
description: table.description || `Delete a ${table.name} record by ${pk.name}`,
|
|
302
302
|
inputSchema: {
|
|
303
303
|
type: 'object',
|
|
304
304
|
properties: {
|
|
@@ -356,7 +356,7 @@ function generateOrmSkills(tables, customOperations) {
|
|
|
356
356
|
fileName: `skills/${(0, utils_1.lcFirst)(singularName)}.md`,
|
|
357
357
|
content: (0, docs_utils_1.buildSkillFile)({
|
|
358
358
|
name: `orm-${(0, utils_1.lcFirst)(singularName)}`,
|
|
359
|
-
description: `ORM operations for ${table.name} records`,
|
|
359
|
+
description: table.description || `ORM operations for ${table.name} records`,
|
|
360
360
|
language: 'typescript',
|
|
361
361
|
usage: [
|
|
362
362
|
`db.${(0, utils_1.lcFirst)(singularName)}.findMany({ select: { id: true } }).execute()`,
|
|
@@ -12,6 +12,7 @@ const model_generator_1 = require("./model-generator");
|
|
|
12
12
|
*/
|
|
13
13
|
function generateOrm(options) {
|
|
14
14
|
const { tables, customOperations, sharedTypesPath } = options;
|
|
15
|
+
const commentsEnabled = options.config.codegen?.comments !== false;
|
|
15
16
|
const files = [];
|
|
16
17
|
// Use shared types when a sharedTypesPath is provided (unified output mode)
|
|
17
18
|
const useSharedTypes = !!sharedTypesPath;
|
|
@@ -69,7 +70,7 @@ function generateOrm(options) {
|
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
|
-
const inputTypesFile = (0, input_types_generator_1.generateInputTypesFile)(typeRegistry ?? new Map(), usedInputTypes, tables, usedPayloadTypes);
|
|
73
|
+
const inputTypesFile = (0, input_types_generator_1.generateInputTypesFile)(typeRegistry ?? new Map(), usedInputTypes, tables, usedPayloadTypes, commentsEnabled);
|
|
73
74
|
files.push({
|
|
74
75
|
path: inputTypesFile.fileName,
|
|
75
76
|
content: inputTypesFile.content,
|
|
@@ -77,11 +78,11 @@ function generateOrm(options) {
|
|
|
77
78
|
}
|
|
78
79
|
// 5. Generate custom operations (if any)
|
|
79
80
|
if (hasCustomQueries && customOperations?.queries) {
|
|
80
|
-
const queryOpsFile = (0, custom_ops_generator_1.generateCustomQueryOpsFile)(customOperations.queries);
|
|
81
|
+
const queryOpsFile = (0, custom_ops_generator_1.generateCustomQueryOpsFile)(customOperations.queries, commentsEnabled);
|
|
81
82
|
files.push({ path: queryOpsFile.fileName, content: queryOpsFile.content });
|
|
82
83
|
}
|
|
83
84
|
if (hasCustomMutations && customOperations?.mutations) {
|
|
84
|
-
const mutationOpsFile = (0, custom_ops_generator_1.generateCustomMutationOpsFile)(customOperations.mutations);
|
|
85
|
+
const mutationOpsFile = (0, custom_ops_generator_1.generateCustomMutationOpsFile)(customOperations.mutations, commentsEnabled);
|
|
85
86
|
files.push({
|
|
86
87
|
path: mutationOpsFile.fileName,
|
|
87
88
|
content: mutationOpsFile.content,
|
|
@@ -18,4 +18,4 @@ export declare function collectPayloadTypeNames(operations: Array<{
|
|
|
18
18
|
/**
|
|
19
19
|
* Generate comprehensive input-types.ts file using Babel AST
|
|
20
20
|
*/
|
|
21
|
-
export declare function generateInputTypesFile(typeRegistry: TypeRegistry, usedInputTypes: Set<string>, tables?: CleanTable[], usedPayloadTypes?: Set<string
|
|
21
|
+
export declare function generateInputTypesFile(typeRegistry: TypeRegistry, usedInputTypes: Set<string>, tables?: CleanTable[], usedPayloadTypes?: Set<string>, comments?: boolean): GeneratedInputTypesFile;
|
|
@@ -155,19 +155,26 @@ function parseTypeString(typeStr) {
|
|
|
155
155
|
/**
|
|
156
156
|
* Create an interface property signature
|
|
157
157
|
*/
|
|
158
|
-
function createPropertySignature(name, typeStr, optional) {
|
|
158
|
+
function createPropertySignature(name, typeStr, optional, description) {
|
|
159
159
|
const prop = t.tsPropertySignature(t.identifier(name), t.tsTypeAnnotation(parseTypeString(typeStr)));
|
|
160
160
|
prop.optional = optional;
|
|
161
|
+
if (description) {
|
|
162
|
+
(0, babel_ast_1.addJSDocComment)(prop, description.split('\n'));
|
|
163
|
+
}
|
|
161
164
|
return prop;
|
|
162
165
|
}
|
|
163
166
|
/**
|
|
164
167
|
* Create an exported interface declaration
|
|
165
168
|
*/
|
|
166
|
-
function createExportedInterface(name, properties) {
|
|
167
|
-
const props = properties.map((p) => createPropertySignature(p.name, p.type, p.optional));
|
|
169
|
+
function createExportedInterface(name, properties, description) {
|
|
170
|
+
const props = properties.map((p) => createPropertySignature(p.name, p.type, p.optional, p.description));
|
|
168
171
|
const body = t.tsInterfaceBody(props);
|
|
169
172
|
const interfaceDecl = t.tsInterfaceDeclaration(t.identifier(name), null, null, body);
|
|
170
|
-
|
|
173
|
+
const exportDecl = t.exportNamedDeclaration(interfaceDecl);
|
|
174
|
+
if (description) {
|
|
175
|
+
(0, babel_ast_1.addJSDocComment)(exportDecl, description.split('\n'));
|
|
176
|
+
}
|
|
177
|
+
return exportDecl;
|
|
171
178
|
}
|
|
172
179
|
/**
|
|
173
180
|
* Create an exported type alias declaration
|
|
@@ -348,7 +355,7 @@ function collectEnumTypesFromTables(tables, typeRegistry) {
|
|
|
348
355
|
/**
|
|
349
356
|
* Generate enum type statements
|
|
350
357
|
*/
|
|
351
|
-
function generateEnumTypes(typeRegistry, enumTypeNames) {
|
|
358
|
+
function generateEnumTypes(typeRegistry, enumTypeNames, comments = true) {
|
|
352
359
|
if (enumTypeNames.size === 0)
|
|
353
360
|
return [];
|
|
354
361
|
const statements = [];
|
|
@@ -358,7 +365,12 @@ function generateEnumTypes(typeRegistry, enumTypeNames) {
|
|
|
358
365
|
continue;
|
|
359
366
|
const unionType = createStringLiteralUnion(typeInfo.enumValues);
|
|
360
367
|
const typeAlias = t.tsTypeAliasDeclaration(t.identifier(typeName), null, unionType);
|
|
361
|
-
|
|
368
|
+
const exportDecl = t.exportNamedDeclaration(typeAlias);
|
|
369
|
+
const enumDescription = (0, utils_1.stripSmartComments)(typeInfo.description, comments);
|
|
370
|
+
if (enumDescription) {
|
|
371
|
+
(0, babel_ast_1.addJSDocComment)(exportDecl, enumDescription.split('\n'));
|
|
372
|
+
}
|
|
373
|
+
statements.push(exportDecl);
|
|
362
374
|
}
|
|
363
375
|
if (statements.length > 0) {
|
|
364
376
|
addSectionComment(statements, 'Enum Types');
|
|
@@ -418,6 +430,7 @@ function buildEntityProperties(table) {
|
|
|
418
430
|
name: field.name,
|
|
419
431
|
type: isNullable ? `${tsType} | null` : tsType,
|
|
420
432
|
optional: isNullable,
|
|
433
|
+
description: field.description,
|
|
421
434
|
});
|
|
422
435
|
}
|
|
423
436
|
return properties;
|
|
@@ -429,7 +442,7 @@ function generateEntityTypes(tables) {
|
|
|
429
442
|
const statements = [];
|
|
430
443
|
for (const table of tables) {
|
|
431
444
|
const { typeName } = (0, utils_1.getTableNames)(table);
|
|
432
|
-
statements.push(createExportedInterface(typeName, buildEntityProperties(table)));
|
|
445
|
+
statements.push(createExportedInterface(typeName, buildEntityProperties(table), table.description));
|
|
433
446
|
}
|
|
434
447
|
if (statements.length > 0) {
|
|
435
448
|
addSectionComment(statements, 'Entity Types');
|
|
@@ -1000,7 +1013,7 @@ function buildTableCrudTypeNames(tables) {
|
|
|
1000
1013
|
/**
|
|
1001
1014
|
* Generate custom input type statements from TypeRegistry
|
|
1002
1015
|
*/
|
|
1003
|
-
function generateCustomInputTypes(typeRegistry, usedInputTypes, tableCrudTypes) {
|
|
1016
|
+
function generateCustomInputTypes(typeRegistry, usedInputTypes, tableCrudTypes, comments = true) {
|
|
1004
1017
|
const statements = [];
|
|
1005
1018
|
const generatedTypes = new Set();
|
|
1006
1019
|
const typesToGenerate = new Set(Array.from(usedInputTypes));
|
|
@@ -1036,7 +1049,12 @@ function generateCustomInputTypes(typeRegistry, usedInputTypes, tableCrudTypes)
|
|
|
1036
1049
|
for (const field of typeInfo.inputFields) {
|
|
1037
1050
|
const optional = !isRequired(field.type);
|
|
1038
1051
|
const tsType = typeRefToTs(field.type);
|
|
1039
|
-
properties.push({
|
|
1052
|
+
properties.push({
|
|
1053
|
+
name: field.name,
|
|
1054
|
+
type: tsType,
|
|
1055
|
+
optional,
|
|
1056
|
+
description: (0, utils_1.stripSmartComments)(field.description, comments),
|
|
1057
|
+
});
|
|
1040
1058
|
// Follow nested Input types
|
|
1041
1059
|
const baseType = (0, type_resolver_1.getTypeBaseName)(field.type);
|
|
1042
1060
|
if (baseType &&
|
|
@@ -1045,12 +1063,17 @@ function generateCustomInputTypes(typeRegistry, usedInputTypes, tableCrudTypes)
|
|
|
1045
1063
|
typesToGenerate.add(baseType);
|
|
1046
1064
|
}
|
|
1047
1065
|
}
|
|
1048
|
-
statements.push(createExportedInterface(typeName, properties));
|
|
1066
|
+
statements.push(createExportedInterface(typeName, properties, (0, utils_1.stripSmartComments)(typeInfo.description, comments)));
|
|
1049
1067
|
}
|
|
1050
1068
|
else if (typeInfo.kind === 'ENUM' && typeInfo.enumValues) {
|
|
1051
1069
|
const unionType = createStringLiteralUnion(typeInfo.enumValues);
|
|
1052
1070
|
const typeAlias = t.tsTypeAliasDeclaration(t.identifier(typeName), null, unionType);
|
|
1053
|
-
|
|
1071
|
+
const enumExportDecl = t.exportNamedDeclaration(typeAlias);
|
|
1072
|
+
const enumDescription = (0, utils_1.stripSmartComments)(typeInfo.description, comments);
|
|
1073
|
+
if (enumDescription) {
|
|
1074
|
+
(0, babel_ast_1.addJSDocComment)(enumExportDecl, enumDescription.split('\n'));
|
|
1075
|
+
}
|
|
1076
|
+
statements.push(enumExportDecl);
|
|
1054
1077
|
}
|
|
1055
1078
|
else {
|
|
1056
1079
|
// Add comment for unsupported type kind
|
|
@@ -1084,7 +1107,7 @@ function collectPayloadTypeNames(operations) {
|
|
|
1084
1107
|
/**
|
|
1085
1108
|
* Generate payload/return type statements
|
|
1086
1109
|
*/
|
|
1087
|
-
function generatePayloadTypes(typeRegistry, usedPayloadTypes, alreadyGeneratedTypes) {
|
|
1110
|
+
function generatePayloadTypes(typeRegistry, usedPayloadTypes, alreadyGeneratedTypes, comments = true) {
|
|
1088
1111
|
const statements = [];
|
|
1089
1112
|
const generatedTypes = new Set(alreadyGeneratedTypes);
|
|
1090
1113
|
const typesToGenerate = new Set(Array.from(usedPayloadTypes));
|
|
@@ -1132,6 +1155,7 @@ function generatePayloadTypes(typeRegistry, usedPayloadTypes, alreadyGeneratedTy
|
|
|
1132
1155
|
name: field.name,
|
|
1133
1156
|
type: isNullable ? `${tsType} | null` : tsType,
|
|
1134
1157
|
optional: isNullable,
|
|
1158
|
+
description: (0, utils_1.stripSmartComments)(field.description, comments),
|
|
1135
1159
|
});
|
|
1136
1160
|
// Follow nested OBJECT types
|
|
1137
1161
|
if (baseType &&
|
|
@@ -1143,7 +1167,7 @@ function generatePayloadTypes(typeRegistry, usedPayloadTypes, alreadyGeneratedTy
|
|
|
1143
1167
|
}
|
|
1144
1168
|
}
|
|
1145
1169
|
}
|
|
1146
|
-
statements.push(createExportedInterface(typeName, interfaceProps));
|
|
1170
|
+
statements.push(createExportedInterface(typeName, interfaceProps, (0, utils_1.stripSmartComments)(typeInfo.description, comments)));
|
|
1147
1171
|
// Build Select type
|
|
1148
1172
|
const selectMembers = [];
|
|
1149
1173
|
for (const field of typeInfo.fields) {
|
|
@@ -1224,7 +1248,7 @@ function generateConnectionFieldsMap(tables, tableByName) {
|
|
|
1224
1248
|
/**
|
|
1225
1249
|
* Generate comprehensive input-types.ts file using Babel AST
|
|
1226
1250
|
*/
|
|
1227
|
-
function generateInputTypesFile(typeRegistry, usedInputTypes, tables, usedPayloadTypes) {
|
|
1251
|
+
function generateInputTypesFile(typeRegistry, usedInputTypes, tables, usedPayloadTypes, comments = true) {
|
|
1228
1252
|
const statements = [];
|
|
1229
1253
|
const tablesList = tables ?? [];
|
|
1230
1254
|
const hasTables = tablesList.length > 0;
|
|
@@ -1236,7 +1260,7 @@ function generateInputTypesFile(typeRegistry, usedInputTypes, tables, usedPayloa
|
|
|
1236
1260
|
// 1. Scalar filter types
|
|
1237
1261
|
statements.push(...generateScalarFilterTypes());
|
|
1238
1262
|
// 2. Enum types used by table fields
|
|
1239
|
-
statements.push(...generateEnumTypes(typeRegistry, enumTypes));
|
|
1263
|
+
statements.push(...generateEnumTypes(typeRegistry, enumTypes, comments));
|
|
1240
1264
|
// 2b. Unknown/custom scalar aliases for schema-specific scalars
|
|
1241
1265
|
statements.push(...generateCustomScalarTypes(customScalarTypes));
|
|
1242
1266
|
// 3. Entity and relation types (if tables provided)
|
|
@@ -1260,7 +1284,7 @@ function generateInputTypesFile(typeRegistry, usedInputTypes, tables, usedPayloa
|
|
|
1260
1284
|
statements.push(...generateConnectionFieldsMap(tablesList, tableByName));
|
|
1261
1285
|
// 7. Custom input types from TypeRegistry
|
|
1262
1286
|
const tableCrudTypes = tables ? buildTableCrudTypeNames(tables) : undefined;
|
|
1263
|
-
statements.push(...generateCustomInputTypes(typeRegistry, usedInputTypes, tableCrudTypes));
|
|
1287
|
+
statements.push(...generateCustomInputTypes(typeRegistry, usedInputTypes, tableCrudTypes, comments));
|
|
1264
1288
|
// 8. Payload/return types for custom operations
|
|
1265
1289
|
if (usedPayloadTypes && usedPayloadTypes.size > 0) {
|
|
1266
1290
|
const alreadyGeneratedTypes = new Set();
|
|
@@ -1270,7 +1294,7 @@ function generateInputTypesFile(typeRegistry, usedInputTypes, tables, usedPayloa
|
|
|
1270
1294
|
alreadyGeneratedTypes.add(typeName);
|
|
1271
1295
|
}
|
|
1272
1296
|
}
|
|
1273
|
-
statements.push(...generatePayloadTypes(typeRegistry, usedPayloadTypes, alreadyGeneratedTypes));
|
|
1297
|
+
statements.push(...generatePayloadTypes(typeRegistry, usedPayloadTypes, alreadyGeneratedTypes, comments));
|
|
1274
1298
|
}
|
|
1275
1299
|
// Generate code with file header
|
|
1276
1300
|
const header = (0, utils_1.getGeneratedFileHeader)('GraphQL types for ORM client');
|
package/core/codegen/queries.js
CHANGED
|
@@ -132,8 +132,9 @@ function generateListQueryHook(table, options = {}) {
|
|
|
132
132
|
};
|
|
133
133
|
// Hook
|
|
134
134
|
if (reactQueryEnabled) {
|
|
135
|
+
const descLine = table.description || `Query hook for fetching ${typeName} list`;
|
|
135
136
|
const docLines = [
|
|
136
|
-
|
|
137
|
+
descLine,
|
|
137
138
|
'',
|
|
138
139
|
'@example',
|
|
139
140
|
'```tsx',
|
|
@@ -205,7 +206,7 @@ function generateListQueryHook(table, options = {}) {
|
|
|
205
206
|
]);
|
|
206
207
|
const f1Decl = (0, hooks_ast_1.exportAsyncDeclareFunction)(fetchFnName, (0, hooks_ast_1.createSTypeParam)(selectTypeName), [(0, hooks_ast_1.createFunctionParam)('params', f1ParamType)], (0, hooks_ast_1.typeRef)('Promise', [listResultTypeAST((0, hooks_ast_1.sRef)())]));
|
|
207
208
|
(0, hooks_ast_1.addJSDocComment)(f1Decl, [
|
|
208
|
-
`Fetch ${typeName} list without React hooks`,
|
|
209
|
+
table.description || `Fetch ${typeName} list without React hooks`,
|
|
209
210
|
'',
|
|
210
211
|
'@example',
|
|
211
212
|
'```ts',
|
|
@@ -247,7 +248,7 @@ function generateListQueryHook(table, options = {}) {
|
|
|
247
248
|
(0, hooks_ast_1.createFunctionParam)('params', p1ParamType),
|
|
248
249
|
], (0, hooks_ast_1.typeRef)('Promise', [t.tsVoidKeyword()]));
|
|
249
250
|
(0, hooks_ast_1.addJSDocComment)(p1Decl, [
|
|
250
|
-
`Prefetch ${typeName} list for SSR or cache warming`,
|
|
251
|
+
table.description || `Prefetch ${typeName} list for SSR or cache warming`,
|
|
251
252
|
'',
|
|
252
253
|
'@example',
|
|
253
254
|
'```ts',
|
|
@@ -283,9 +284,9 @@ function generateListQueryHook(table, options = {}) {
|
|
|
283
284
|
(0, hooks_ast_1.createFunctionParam)('params', pImplParamType),
|
|
284
285
|
], pBody, (0, hooks_ast_1.typeRef)('Promise', [t.tsVoidKeyword()])));
|
|
285
286
|
}
|
|
286
|
-
const headerText = reactQueryEnabled
|
|
287
|
+
const headerText = table.description || (reactQueryEnabled
|
|
287
288
|
? `List query hook for ${typeName}`
|
|
288
|
-
: `List query functions for ${typeName}
|
|
289
|
+
: `List query functions for ${typeName}`);
|
|
289
290
|
return {
|
|
290
291
|
fileName: (0, utils_1.getListQueryFileName)(table),
|
|
291
292
|
content: (0, hooks_ast_1.generateHookFileCode)(headerText, statements),
|
|
@@ -369,8 +370,9 @@ function generateSingleQueryHook(table, options = {}) {
|
|
|
369
370
|
};
|
|
370
371
|
// Hook
|
|
371
372
|
if (reactQueryEnabled) {
|
|
373
|
+
const singleDescLine = table.description || `Query hook for fetching a single ${typeName}`;
|
|
372
374
|
const docLines = [
|
|
373
|
-
|
|
375
|
+
singleDescLine,
|
|
374
376
|
'',
|
|
375
377
|
'@example',
|
|
376
378
|
'```tsx',
|
|
@@ -447,7 +449,7 @@ function generateSingleQueryHook(table, options = {}) {
|
|
|
447
449
|
]);
|
|
448
450
|
const f1Decl = (0, hooks_ast_1.exportAsyncDeclareFunction)(fetchFnName, (0, hooks_ast_1.createSTypeParam)(selectTypeName), [(0, hooks_ast_1.createFunctionParam)('params', f1ParamType)], (0, hooks_ast_1.typeRef)('Promise', [singleResultTypeAST((0, hooks_ast_1.sRef)())]));
|
|
449
451
|
(0, hooks_ast_1.addJSDocComment)(f1Decl, [
|
|
450
|
-
`Fetch a single ${typeName} without React hooks`,
|
|
452
|
+
table.description || `Fetch a single ${typeName} without React hooks`,
|
|
451
453
|
'',
|
|
452
454
|
'@example',
|
|
453
455
|
'```ts',
|
|
@@ -489,7 +491,7 @@ function generateSingleQueryHook(table, options = {}) {
|
|
|
489
491
|
(0, hooks_ast_1.createFunctionParam)('params', p1ParamType),
|
|
490
492
|
], (0, hooks_ast_1.typeRef)('Promise', [t.tsVoidKeyword()]));
|
|
491
493
|
(0, hooks_ast_1.addJSDocComment)(p1Decl, [
|
|
492
|
-
`Prefetch a single ${typeName} for SSR or cache warming`,
|
|
494
|
+
table.description || `Prefetch a single ${typeName} for SSR or cache warming`,
|
|
493
495
|
'',
|
|
494
496
|
'@example',
|
|
495
497
|
'```ts',
|
|
@@ -527,9 +529,9 @@ function generateSingleQueryHook(table, options = {}) {
|
|
|
527
529
|
(0, hooks_ast_1.createFunctionParam)('params', pImplParamType),
|
|
528
530
|
], pBody, (0, hooks_ast_1.typeRef)('Promise', [t.tsVoidKeyword()])));
|
|
529
531
|
}
|
|
530
|
-
const headerText = reactQueryEnabled
|
|
532
|
+
const headerText = table.description || (reactQueryEnabled
|
|
531
533
|
? `Single item query hook for ${typeName}`
|
|
532
|
-
: `Single item query functions for ${typeName}
|
|
534
|
+
: `Single item query functions for ${typeName}`);
|
|
533
535
|
return {
|
|
534
536
|
fileName: (0, utils_1.getSingleQueryFileName)(table),
|
|
535
537
|
content: (0, hooks_ast_1.generateHookFileCode)(headerText, statements),
|
|
@@ -22,6 +22,8 @@ export interface GeneratedSchemaTypesFile {
|
|
|
22
22
|
export interface GenerateSchemaTypesOptions {
|
|
23
23
|
typeRegistry: TypeRegistry;
|
|
24
24
|
tableTypeNames: Set<string>;
|
|
25
|
+
/** Include descriptions as JSDoc comments. @default true */
|
|
26
|
+
comments?: boolean;
|
|
25
27
|
}
|
|
26
28
|
export interface PayloadTypesResult {
|
|
27
29
|
statements: t.Statement[];
|