@constructive-io/graphql-codegen 4.24.5 → 4.25.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.
- package/core/codegen/cli/docs-generator.d.ts +2 -4
- package/core/codegen/cli/docs-generator.js +74 -472
- package/core/codegen/cli/index.d.ts +2 -2
- package/core/codegen/cli/index.js +1 -3
- package/core/codegen/cli/table-command-generator.js +165 -16
- package/core/codegen/docs-utils.d.ts +0 -6
- package/core/codegen/docs-utils.js +3 -4
- package/core/codegen/hooks-docs-generator.d.ts +1 -2
- package/core/codegen/hooks-docs-generator.js +0 -113
- package/core/codegen/orm/docs-generator.d.ts +1 -2
- package/core/codegen/orm/docs-generator.js +0 -126
- package/core/codegen/target-docs-generator.d.ts +1 -2
- package/core/codegen/target-docs-generator.js +0 -13
- package/core/codegen/templates/cli-utils.ts +117 -0
- package/core/codegen/utils.d.ts +2 -2
- package/core/codegen/utils.js +2 -2
- package/core/generate.js +0 -26
- package/esm/core/codegen/cli/docs-generator.d.ts +2 -4
- package/esm/core/codegen/cli/docs-generator.js +75 -471
- package/esm/core/codegen/cli/index.d.ts +2 -2
- package/esm/core/codegen/cli/index.js +1 -1
- package/esm/core/codegen/cli/table-command-generator.js +166 -17
- package/esm/core/codegen/docs-utils.d.ts +0 -6
- package/esm/core/codegen/docs-utils.js +3 -4
- package/esm/core/codegen/hooks-docs-generator.d.ts +1 -2
- package/esm/core/codegen/hooks-docs-generator.js +2 -114
- package/esm/core/codegen/orm/docs-generator.d.ts +1 -2
- package/esm/core/codegen/orm/docs-generator.js +1 -126
- package/esm/core/codegen/target-docs-generator.d.ts +1 -2
- package/esm/core/codegen/target-docs-generator.js +0 -12
- package/esm/core/codegen/utils.d.ts +2 -2
- package/esm/core/codegen/utils.js +2 -2
- package/esm/core/generate.js +4 -30
- package/esm/types/config.d.ts +1 -8
- package/package.json +9 -9
- package/types/config.d.ts +1 -8
|
@@ -39,6 +39,7 @@ const t = __importStar(require("@babel/types"));
|
|
|
39
39
|
const komoji_1 = require("komoji");
|
|
40
40
|
const babel_ast_1 = require("../babel-ast");
|
|
41
41
|
const utils_1 = require("../utils");
|
|
42
|
+
const docs_utils_1 = require("../docs-utils");
|
|
42
43
|
function createImportDeclaration(moduleSpecifier, namedImports, typeOnly = false) {
|
|
43
44
|
const specifiers = namedImports.map((name) => t.importSpecifier(t.identifier(name), t.identifier(name)));
|
|
44
45
|
const decl = t.importDeclaration(specifiers, t.stringLiteral(moduleSpecifier));
|
|
@@ -190,7 +191,7 @@ function buildArgvType() {
|
|
|
190
191
|
}
|
|
191
192
|
function buildSubcommandSwitch(subcommands, handlerPrefix, usageVarName) {
|
|
192
193
|
const cases = subcommands.map((sub) => t.switchCase(t.stringLiteral(sub), [
|
|
193
|
-
t.returnStatement(t.callExpression(t.identifier(`${handlerPrefix}${(0, utils_1.
|
|
194
|
+
t.returnStatement(t.callExpression(t.identifier(`${handlerPrefix}${(0, utils_1.toPascalCase)(sub)}`), [
|
|
194
195
|
t.identifier('argv'),
|
|
195
196
|
t.identifier('prompter'),
|
|
196
197
|
])),
|
|
@@ -203,17 +204,27 @@ function buildSubcommandSwitch(subcommands, handlerPrefix, usageVarName) {
|
|
|
203
204
|
}
|
|
204
205
|
function buildListHandler(table, targetName, typeRegistry) {
|
|
205
206
|
const { singularName } = (0, utils_1.getTableNames)(table);
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
207
|
+
const defaultSelectObj = buildSelectObject(table, typeRegistry);
|
|
208
|
+
// --- Build the try body ---
|
|
209
|
+
const tryBody = [];
|
|
210
|
+
// const defaultSelect = { id: true, name: true, ... };
|
|
211
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
212
|
+
t.variableDeclarator(t.identifier('defaultSelect'), defaultSelectObj),
|
|
213
|
+
]));
|
|
214
|
+
// const findManyArgs = parseFindManyArgs(argv, defaultSelect);
|
|
215
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
216
|
+
t.variableDeclarator(t.identifier('findManyArgs'), t.callExpression(t.identifier('parseFindManyArgs'), [
|
|
217
|
+
t.identifier('argv'),
|
|
218
|
+
t.identifier('defaultSelect'),
|
|
219
|
+
])),
|
|
220
|
+
]));
|
|
221
|
+
tryBody.push(buildGetClientStatement(targetName));
|
|
222
|
+
// const result = await client.<singular>.findMany(findManyArgs).execute();
|
|
223
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
224
|
+
t.variableDeclarator(t.identifier('result'), t.awaitExpression(t.callExpression(t.memberExpression(t.callExpression(t.memberExpression(t.memberExpression(t.identifier('client'), t.identifier(singularName)), t.identifier('findMany')), [t.identifier('findManyArgs')]), t.identifier('execute')), []))),
|
|
225
|
+
]));
|
|
226
|
+
tryBody.push(buildJsonLog(t.identifier('result')));
|
|
227
|
+
const argvParam = t.identifier('argv');
|
|
217
228
|
argvParam.typeAnnotation = buildArgvType();
|
|
218
229
|
const prompterParam = t.identifier('_prompter');
|
|
219
230
|
prompterParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Inquirerer')));
|
|
@@ -221,6 +232,129 @@ function buildListHandler(table, targetName, typeRegistry) {
|
|
|
221
232
|
t.tryStatement(t.blockStatement(tryBody), buildErrorCatch('Failed to list records.')),
|
|
222
233
|
]), false, true);
|
|
223
234
|
}
|
|
235
|
+
/**
|
|
236
|
+
* Build a `handleFindFirst` function — CLI equivalent of the TS SDK's findFirst().
|
|
237
|
+
* Accepts --fields, --where.<field>.<op>, --condition.<field>.<op> flags.
|
|
238
|
+
* Internally calls findMany with first:1 and returns a single record (or null).
|
|
239
|
+
*/
|
|
240
|
+
function buildFindFirstHandler(table, targetName, typeRegistry) {
|
|
241
|
+
const { singularName } = (0, utils_1.getTableNames)(table);
|
|
242
|
+
const defaultSelectObj = buildSelectObject(table, typeRegistry);
|
|
243
|
+
const tryBody = [];
|
|
244
|
+
// const defaultSelect = { ... };
|
|
245
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
246
|
+
t.variableDeclarator(t.identifier('defaultSelect'), defaultSelectObj),
|
|
247
|
+
]));
|
|
248
|
+
// const findFirstArgs = parseFindFirstArgs(argv, defaultSelect);
|
|
249
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
250
|
+
t.variableDeclarator(t.identifier('findFirstArgs'), t.callExpression(t.identifier('parseFindFirstArgs'), [
|
|
251
|
+
t.identifier('argv'),
|
|
252
|
+
t.identifier('defaultSelect'),
|
|
253
|
+
])),
|
|
254
|
+
]));
|
|
255
|
+
tryBody.push(buildGetClientStatement(targetName));
|
|
256
|
+
// const result = await client.<singular>.findFirst(findFirstArgs).execute();
|
|
257
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
258
|
+
t.variableDeclarator(t.identifier('result'), t.awaitExpression(t.callExpression(t.memberExpression(t.callExpression(t.memberExpression(t.memberExpression(t.identifier('client'), t.identifier(singularName)), t.identifier('findFirst')), [t.identifier('findFirstArgs')]), t.identifier('execute')), []))),
|
|
259
|
+
]));
|
|
260
|
+
tryBody.push(buildJsonLog(t.identifier('result')));
|
|
261
|
+
const argvParam = t.identifier('argv');
|
|
262
|
+
argvParam.typeAnnotation = buildArgvType();
|
|
263
|
+
const prompterParam = t.identifier('_prompter');
|
|
264
|
+
prompterParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Inquirerer')));
|
|
265
|
+
return t.functionDeclaration(t.identifier('handleFindFirst'), [argvParam, prompterParam], t.blockStatement([
|
|
266
|
+
t.tryStatement(t.blockStatement(tryBody), buildErrorCatch('Failed to find record.')),
|
|
267
|
+
]), false, true);
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Build a `handleSearch` function for tables with search-capable fields.
|
|
271
|
+
* Extracts the first positional arg as the query string and auto-builds a
|
|
272
|
+
* `where` clause that targets all detected search fields (tsvector, BM25,
|
|
273
|
+
* trigram, vector embedding). Supports --limit, --offset, --fields, --orderBy.
|
|
274
|
+
*/
|
|
275
|
+
function buildSearchHandler(table, specialGroups, targetName, typeRegistry) {
|
|
276
|
+
const { singularName } = (0, utils_1.getTableNames)(table);
|
|
277
|
+
const defaultSelectObj = buildSelectObject(table, typeRegistry);
|
|
278
|
+
const tryBody = [];
|
|
279
|
+
// const query = Array.isArray(argv._) && argv._.length > 0 ? String(argv._[0]) : undefined;
|
|
280
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
281
|
+
t.variableDeclarator(t.identifier('query'), t.conditionalExpression(t.logicalExpression('&&', t.callExpression(t.memberExpression(t.identifier('Array'), t.identifier('isArray')), [t.memberExpression(t.identifier('argv'), t.identifier('_'))]), t.binaryExpression('>', t.memberExpression(t.memberExpression(t.identifier('argv'), t.identifier('_')), t.identifier('length')), t.numericLiteral(0))), t.callExpression(t.identifier('String'), [
|
|
282
|
+
t.memberExpression(t.memberExpression(t.identifier('argv'), t.identifier('_')), t.numericLiteral(0), true),
|
|
283
|
+
]), t.identifier('undefined'))),
|
|
284
|
+
]));
|
|
285
|
+
// if (!query) { console.error('Usage: ... search <query>'); process.exit(1); }
|
|
286
|
+
tryBody.push(t.ifStatement(t.unaryExpression('!', t.identifier('query')), t.blockStatement([
|
|
287
|
+
t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('error')), [t.stringLiteral('Error: search requires a <query> argument')])),
|
|
288
|
+
t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('process'), t.identifier('exit')), [t.numericLiteral(1)])),
|
|
289
|
+
])));
|
|
290
|
+
// Build the where clause properties from detected search fields
|
|
291
|
+
// e.g. { tsvContent: { query }, bm25Body: { query }, trgmTitle: { value: query, threshold: 0.3 }, vectorEmbedding: { value: query } }
|
|
292
|
+
const whereProps = [];
|
|
293
|
+
for (const group of specialGroups) {
|
|
294
|
+
for (const field of group.fields) {
|
|
295
|
+
if (field.type.pgType?.toLowerCase() === 'tsvector') {
|
|
296
|
+
// tsvector field: { query }
|
|
297
|
+
whereProps.push(t.objectProperty(t.identifier(field.name), t.objectExpression([
|
|
298
|
+
t.objectProperty(t.identifier('query'), t.identifier('query'), false, true),
|
|
299
|
+
])));
|
|
300
|
+
}
|
|
301
|
+
else if (/Bm25Score$/.test(field.name)) {
|
|
302
|
+
// BM25 computed score field — derive the input field name:
|
|
303
|
+
// bodyBm25Score -> bm25Body (strip trailing "Bm25Score", prefix with "bm25")
|
|
304
|
+
const baseName = field.name.replace(/Bm25Score$/, '');
|
|
305
|
+
const inputFieldName = `bm25${baseName.charAt(0).toUpperCase()}${baseName.slice(1)}`;
|
|
306
|
+
whereProps.push(t.objectProperty(t.identifier(inputFieldName), t.objectExpression([
|
|
307
|
+
t.objectProperty(t.identifier('query'), t.identifier('query'), false, true),
|
|
308
|
+
])));
|
|
309
|
+
}
|
|
310
|
+
else if (/TrgmSimilarity$/.test(field.name)) {
|
|
311
|
+
// Trigram computed score field — derive the input field name:
|
|
312
|
+
// titleTrgmSimilarity -> trgmTitle
|
|
313
|
+
const baseName = field.name.replace(/TrgmSimilarity$/, '');
|
|
314
|
+
const inputFieldName = `trgm${baseName.charAt(0).toUpperCase()}${baseName.slice(1)}`;
|
|
315
|
+
whereProps.push(t.objectProperty(t.identifier(inputFieldName), t.objectExpression([
|
|
316
|
+
t.objectProperty(t.identifier('value'), t.identifier('query')),
|
|
317
|
+
t.objectProperty(t.identifier('threshold'), t.numericLiteral(0.3)),
|
|
318
|
+
])));
|
|
319
|
+
}
|
|
320
|
+
else if (group.category === 'embedding') {
|
|
321
|
+
// Vector embedding field: { value: query }
|
|
322
|
+
whereProps.push(t.objectProperty(t.identifier(field.name), t.objectExpression([
|
|
323
|
+
t.objectProperty(t.identifier('value'), t.identifier('query')),
|
|
324
|
+
])));
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
// const searchWhere = { tsvContent: { query }, ... };
|
|
329
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
330
|
+
t.variableDeclarator(t.identifier('searchWhere'), t.objectExpression(whereProps)),
|
|
331
|
+
]));
|
|
332
|
+
// const defaultSelect = { ... };
|
|
333
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
334
|
+
t.variableDeclarator(t.identifier('defaultSelect'), defaultSelectObj),
|
|
335
|
+
]));
|
|
336
|
+
// const findManyArgs = parseFindManyArgs(argv, defaultSelect, searchWhere);
|
|
337
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
338
|
+
t.variableDeclarator(t.identifier('findManyArgs'), t.callExpression(t.identifier('parseFindManyArgs'), [
|
|
339
|
+
t.identifier('argv'),
|
|
340
|
+
t.identifier('defaultSelect'),
|
|
341
|
+
t.identifier('searchWhere'),
|
|
342
|
+
])),
|
|
343
|
+
]));
|
|
344
|
+
tryBody.push(buildGetClientStatement(targetName));
|
|
345
|
+
// const result = await client.<singular>.findMany(findManyArgs).execute();
|
|
346
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
347
|
+
t.variableDeclarator(t.identifier('result'), t.awaitExpression(t.callExpression(t.memberExpression(t.callExpression(t.memberExpression(t.memberExpression(t.identifier('client'), t.identifier(singularName)), t.identifier('findMany')), [t.identifier('findManyArgs')]), t.identifier('execute')), []))),
|
|
348
|
+
]));
|
|
349
|
+
tryBody.push(buildJsonLog(t.identifier('result')));
|
|
350
|
+
const argvParam = t.identifier('argv');
|
|
351
|
+
argvParam.typeAnnotation = buildArgvType();
|
|
352
|
+
const prompterParam = t.identifier('_prompter');
|
|
353
|
+
prompterParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Inquirerer')));
|
|
354
|
+
return t.functionDeclaration(t.identifier('handleSearch'), [argvParam, prompterParam], t.blockStatement([
|
|
355
|
+
t.tryStatement(t.blockStatement(tryBody), buildErrorCatch('Failed to search records.')),
|
|
356
|
+
]), false, true);
|
|
357
|
+
}
|
|
224
358
|
function buildGetHandler(table, targetName, typeRegistry) {
|
|
225
359
|
const { singularName } = (0, utils_1.getTableNames)(table);
|
|
226
360
|
const pkFields = (0, utils_1.getPrimaryKeyInfo)(table);
|
|
@@ -431,7 +565,7 @@ function generateTableCommand(table, options) {
|
|
|
431
565
|
]));
|
|
432
566
|
statements.push(createImportDeclaration(executorPath, ['getClient']));
|
|
433
567
|
const utilsPath = options?.targetName ? '../../utils' : '../utils';
|
|
434
|
-
statements.push(createImportDeclaration(utilsPath, ['coerceAnswers', 'stripUndefined']));
|
|
568
|
+
statements.push(createImportDeclaration(utilsPath, ['coerceAnswers', 'parseFindFirstArgs', 'parseFindManyArgs', 'stripUndefined']));
|
|
435
569
|
statements.push(createImportDeclaration(utilsPath, ['FieldSchema'], true));
|
|
436
570
|
// Import ORM input types for proper type assertions in mutation handlers.
|
|
437
571
|
// These types ensure that cleanedData is cast to the correct ORM input type
|
|
@@ -463,7 +597,12 @@ function generateTableCommand(table, options) {
|
|
|
463
597
|
const hasUpdate = table.query?.update !== undefined && table.query?.update !== null;
|
|
464
598
|
const hasDelete = table.query?.delete !== undefined && table.query?.delete !== null;
|
|
465
599
|
const hasGet = table.query?.one !== null || hasUpdate || hasDelete;
|
|
466
|
-
|
|
600
|
+
// Detect whether this table has search-capable fields (tsvector, BM25, trgm, vector embedding)
|
|
601
|
+
const specialGroups = (0, docs_utils_1.categorizeSpecialFields)(table, options?.typeRegistry);
|
|
602
|
+
const hasSearchFields = specialGroups.some((g) => g.category === 'search' || g.category === 'embedding');
|
|
603
|
+
const subcommands = ['list', 'find-first'];
|
|
604
|
+
if (hasSearchFields)
|
|
605
|
+
subcommands.push('search');
|
|
467
606
|
if (hasGet)
|
|
468
607
|
subcommands.push('get');
|
|
469
608
|
subcommands.push('create');
|
|
@@ -476,8 +615,11 @@ function generateTableCommand(table, options) {
|
|
|
476
615
|
`${commandName} <command>`,
|
|
477
616
|
'',
|
|
478
617
|
'Commands:',
|
|
479
|
-
` list List
|
|
618
|
+
` list List ${singularName} records`,
|
|
619
|
+
` find-first Find first matching ${singularName} record`,
|
|
480
620
|
];
|
|
621
|
+
if (hasSearchFields)
|
|
622
|
+
usageLines.push(` search <query> Search ${singularName} records`);
|
|
481
623
|
if (hasGet)
|
|
482
624
|
usageLines.push(` get Get a ${singularName} by ID`);
|
|
483
625
|
usageLines.push(` create Create a new ${singularName}`);
|
|
@@ -485,7 +627,11 @@ function generateTableCommand(table, options) {
|
|
|
485
627
|
usageLines.push(` update Update an existing ${singularName}`);
|
|
486
628
|
if (hasDelete)
|
|
487
629
|
usageLines.push(` delete Delete a ${singularName}`);
|
|
488
|
-
usageLines.push('', ' --
|
|
630
|
+
usageLines.push('', 'List Options:', ' --limit <n> Max number of records to return (forward pagination)', ' --last <n> Number of records from the end (backward pagination)', ' --after <cursor> Cursor for forward pagination', ' --before <cursor> Cursor for backward pagination', ' --offset <n> Number of records to skip', ' --fields <fields> Comma-separated list of fields to return', ' --where.<field>.<op> Filter (dot-notation, e.g. --where.name.equalTo foo)', ' --condition.<f>.<op> Condition filter (dot-notation)', ' --orderBy <values> Comma-separated ordering values (e.g. NAME_ASC,CREATED_AT_DESC)', '', 'Find-First Options:', ' --fields <fields> Comma-separated list of fields to return', ' --where.<field>.<op> Filter (dot-notation, e.g. --where.status.equalTo active)', ' --condition.<f>.<op> Condition filter (dot-notation)', '');
|
|
631
|
+
if (hasSearchFields) {
|
|
632
|
+
usageLines.push('Search Options:', ' <query> Search query string (required)', ' --limit <n> Max number of records to return', ' --offset <n> Number of records to skip', ' --fields <fields> Comma-separated list of fields to return', ' --orderBy <values> Comma-separated list of ordering values', '');
|
|
633
|
+
}
|
|
634
|
+
usageLines.push(' --help, -h Show this help message', '');
|
|
489
635
|
statements.push(t.variableDeclaration('const', [
|
|
490
636
|
t.variableDeclarator(t.identifier('usage'), t.stringLiteral(usageLines.join('\n'))),
|
|
491
637
|
]));
|
|
@@ -547,6 +693,9 @@ function generateTableCommand(table, options) {
|
|
|
547
693
|
const tn = options?.targetName;
|
|
548
694
|
const ormTypes = { createInputTypeName, patchTypeName, innerFieldName };
|
|
549
695
|
statements.push(buildListHandler(table, tn, options?.typeRegistry));
|
|
696
|
+
statements.push(buildFindFirstHandler(table, tn, options?.typeRegistry));
|
|
697
|
+
if (hasSearchFields)
|
|
698
|
+
statements.push(buildSearchHandler(table, specialGroups, tn, options?.typeRegistry));
|
|
550
699
|
if (hasGet)
|
|
551
700
|
statements.push(buildGetHandler(table, tn, options?.typeRegistry));
|
|
552
701
|
statements.push(buildMutationHandler(table, 'create', tn, options?.typeRegistry, ormTypes));
|
|
@@ -4,12 +4,6 @@ export interface GeneratedDocFile {
|
|
|
4
4
|
fileName: string;
|
|
5
5
|
content: string;
|
|
6
6
|
}
|
|
7
|
-
export interface McpTool {
|
|
8
|
-
name: string;
|
|
9
|
-
description: string;
|
|
10
|
-
inputSchema: Record<string, unknown>;
|
|
11
|
-
_meta?: Record<string, unknown>;
|
|
12
|
-
}
|
|
13
7
|
export interface SkillDefinition {
|
|
14
8
|
name: string;
|
|
15
9
|
description: string;
|
|
@@ -50,18 +50,17 @@ function getReadmeFooter() {
|
|
|
50
50
|
}
|
|
51
51
|
function resolveDocsConfig(docs) {
|
|
52
52
|
if (docs === true) {
|
|
53
|
-
return { readme: true, agents: true,
|
|
53
|
+
return { readme: true, agents: true, skills: true };
|
|
54
54
|
}
|
|
55
55
|
if (docs === false) {
|
|
56
|
-
return { readme: false, agents: false,
|
|
56
|
+
return { readme: false, agents: false, skills: false };
|
|
57
57
|
}
|
|
58
58
|
if (!docs) {
|
|
59
|
-
return { readme: true, agents: true,
|
|
59
|
+
return { readme: true, agents: true, skills: false };
|
|
60
60
|
}
|
|
61
61
|
return {
|
|
62
62
|
readme: docs.readme ?? true,
|
|
63
63
|
agents: docs.agents ?? true,
|
|
64
|
-
mcp: docs.mcp ?? false,
|
|
65
64
|
skills: docs.skills ?? false,
|
|
66
65
|
};
|
|
67
66
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { Operation, Table, TypeRegistry } from '../../types/schema';
|
|
2
|
-
import type { GeneratedDocFile
|
|
2
|
+
import type { GeneratedDocFile } from './docs-utils';
|
|
3
3
|
export declare function generateHooksReadme(tables: Table[], customOperations: Operation[], registry?: TypeRegistry): GeneratedDocFile;
|
|
4
4
|
export declare function generateHooksAgentsDocs(tables: Table[], customOperations: Operation[]): GeneratedDocFile;
|
|
5
|
-
export declare function getHooksMcpTools(tables: Table[], customOperations: Operation[]): McpTool[];
|
|
6
5
|
export declare function generateHooksSkills(tables: Table[], customOperations: Operation[], targetName: string, registry?: TypeRegistry): GeneratedDocFile[];
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateHooksReadme = generateHooksReadme;
|
|
4
4
|
exports.generateHooksAgentsDocs = generateHooksAgentsDocs;
|
|
5
|
-
exports.getHooksMcpTools = getHooksMcpTools;
|
|
6
5
|
exports.generateHooksSkills = generateHooksSkills;
|
|
7
6
|
const komoji_1 = require("komoji");
|
|
8
7
|
const docs_utils_1 = require("./docs-utils");
|
|
@@ -167,118 +166,6 @@ function generateHooksAgentsDocs(tables, customOperations) {
|
|
|
167
166
|
content: lines.join('\n'),
|
|
168
167
|
};
|
|
169
168
|
}
|
|
170
|
-
function getHooksMcpTools(tables, customOperations) {
|
|
171
|
-
const tools = [];
|
|
172
|
-
for (const table of tables) {
|
|
173
|
-
const { singularName, pluralName } = (0, utils_1.getTableNames)(table);
|
|
174
|
-
const pk = (0, utils_1.getPrimaryKeyInfo)(table)[0];
|
|
175
|
-
const scalarFields = (0, utils_1.getScalarFields)(table);
|
|
176
|
-
tools.push({
|
|
177
|
-
name: `hooks_${(0, utils_1.lcFirst)(pluralName)}_query`,
|
|
178
|
-
description: table.description || `React Query hook to list all ${pluralName}`,
|
|
179
|
-
inputSchema: {
|
|
180
|
-
type: 'object',
|
|
181
|
-
properties: {
|
|
182
|
-
fields: {
|
|
183
|
-
type: 'object',
|
|
184
|
-
description: `Fields to select: { ${scalarFields.map((f) => f.name).join(', ')} }`,
|
|
185
|
-
},
|
|
186
|
-
},
|
|
187
|
-
},
|
|
188
|
-
});
|
|
189
|
-
if ((0, utils_1.hasValidPrimaryKey)(table)) {
|
|
190
|
-
tools.push({
|
|
191
|
-
name: `hooks_${(0, utils_1.lcFirst)(singularName)}_query`,
|
|
192
|
-
description: table.description || `React Query hook to get a single ${singularName} by ${pk.name}`,
|
|
193
|
-
inputSchema: {
|
|
194
|
-
type: 'object',
|
|
195
|
-
properties: {
|
|
196
|
-
[pk.name]: {
|
|
197
|
-
type: (0, docs_utils_1.gqlTypeToJsonSchemaType)(pk.gqlType),
|
|
198
|
-
description: `${table.name} ${pk.name}`,
|
|
199
|
-
},
|
|
200
|
-
},
|
|
201
|
-
required: [pk.name],
|
|
202
|
-
},
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
tools.push({
|
|
206
|
-
name: `hooks_create_${(0, utils_1.lcFirst)(singularName)}_mutation`,
|
|
207
|
-
description: table.description || `React Query mutation hook to create a ${singularName}`,
|
|
208
|
-
inputSchema: {
|
|
209
|
-
type: 'object',
|
|
210
|
-
properties: Object.fromEntries(scalarFields
|
|
211
|
-
.filter((f) => f.name !== pk.name &&
|
|
212
|
-
f.name !== 'nodeId' &&
|
|
213
|
-
f.name !== 'createdAt' &&
|
|
214
|
-
f.name !== 'updatedAt')
|
|
215
|
-
.map((f) => [
|
|
216
|
-
f.name,
|
|
217
|
-
{
|
|
218
|
-
type: (0, docs_utils_1.gqlTypeToJsonSchemaType)(f.type.gqlType),
|
|
219
|
-
description: `${table.name} ${f.name}`,
|
|
220
|
-
},
|
|
221
|
-
])),
|
|
222
|
-
},
|
|
223
|
-
});
|
|
224
|
-
if ((0, utils_1.hasValidPrimaryKey)(table)) {
|
|
225
|
-
tools.push({
|
|
226
|
-
name: `hooks_update_${(0, utils_1.lcFirst)(singularName)}_mutation`,
|
|
227
|
-
description: table.description || `React Query mutation hook to update a ${singularName}`,
|
|
228
|
-
inputSchema: {
|
|
229
|
-
type: 'object',
|
|
230
|
-
properties: {
|
|
231
|
-
[pk.name]: {
|
|
232
|
-
type: (0, docs_utils_1.gqlTypeToJsonSchemaType)(pk.gqlType),
|
|
233
|
-
description: `${table.name} ${pk.name}`,
|
|
234
|
-
},
|
|
235
|
-
},
|
|
236
|
-
required: [pk.name],
|
|
237
|
-
},
|
|
238
|
-
});
|
|
239
|
-
tools.push({
|
|
240
|
-
name: `hooks_delete_${(0, utils_1.lcFirst)(singularName)}_mutation`,
|
|
241
|
-
description: table.description || `React Query mutation hook to delete a ${singularName}`,
|
|
242
|
-
inputSchema: {
|
|
243
|
-
type: 'object',
|
|
244
|
-
properties: {
|
|
245
|
-
[pk.name]: {
|
|
246
|
-
type: (0, docs_utils_1.gqlTypeToJsonSchemaType)(pk.gqlType),
|
|
247
|
-
description: `${table.name} ${pk.name}`,
|
|
248
|
-
},
|
|
249
|
-
},
|
|
250
|
-
required: [pk.name],
|
|
251
|
-
},
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
for (const op of customOperations) {
|
|
256
|
-
const hookName = getCustomHookName(op);
|
|
257
|
-
const props = {};
|
|
258
|
-
const required = [];
|
|
259
|
-
for (const arg of op.args) {
|
|
260
|
-
const isRequired = arg.type.kind === 'NON_NULL';
|
|
261
|
-
const baseType = isRequired && arg.type.ofType ? arg.type.ofType : arg.type;
|
|
262
|
-
props[arg.name] = {
|
|
263
|
-
type: (0, docs_utils_1.gqlTypeToJsonSchemaType)(baseType.name ?? 'String'),
|
|
264
|
-
description: arg.description || arg.name,
|
|
265
|
-
};
|
|
266
|
-
if (isRequired) {
|
|
267
|
-
required.push(arg.name);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
tools.push({
|
|
271
|
-
name: `hooks_${hookName}`,
|
|
272
|
-
description: op.description || `${(0, utils_1.ucFirst)(op.kind)} hook for ${op.name}`,
|
|
273
|
-
inputSchema: {
|
|
274
|
-
type: 'object',
|
|
275
|
-
properties: props,
|
|
276
|
-
...(required.length > 0 ? { required } : {}),
|
|
277
|
-
},
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
return tools;
|
|
281
|
-
}
|
|
282
169
|
function generateHooksSkills(tables, customOperations, targetName, registry) {
|
|
283
170
|
const files = [];
|
|
284
171
|
const skillName = `hooks-${targetName}`;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { Operation, Table, TypeRegistry } from '../../../types/schema';
|
|
2
|
-
import type { GeneratedDocFile
|
|
2
|
+
import type { GeneratedDocFile } from '../docs-utils';
|
|
3
3
|
export declare function generateOrmReadme(tables: Table[], customOperations: Operation[], registry?: TypeRegistry): GeneratedDocFile;
|
|
4
4
|
export declare function generateOrmAgentsDocs(tables: Table[], customOperations: Operation[]): GeneratedDocFile;
|
|
5
|
-
export declare function getOrmMcpTools(tables: Table[], customOperations: Operation[]): McpTool[];
|
|
6
5
|
export declare function generateOrmSkills(tables: Table[], customOperations: Operation[], targetName: string, registry?: TypeRegistry): GeneratedDocFile[];
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateOrmReadme = generateOrmReadme;
|
|
4
4
|
exports.generateOrmAgentsDocs = generateOrmAgentsDocs;
|
|
5
|
-
exports.getOrmMcpTools = getOrmMcpTools;
|
|
6
5
|
exports.generateOrmSkills = generateOrmSkills;
|
|
7
6
|
const komoji_1 = require("komoji");
|
|
8
7
|
const docs_utils_1 = require("../docs-utils");
|
|
@@ -160,131 +159,6 @@ function generateOrmAgentsDocs(tables, customOperations) {
|
|
|
160
159
|
content: lines.join('\n'),
|
|
161
160
|
};
|
|
162
161
|
}
|
|
163
|
-
function getOrmMcpTools(tables, customOperations) {
|
|
164
|
-
const tools = [];
|
|
165
|
-
for (const table of tables) {
|
|
166
|
-
const { singularName } = (0, utils_1.getTableNames)(table);
|
|
167
|
-
const pk = (0, utils_1.getPrimaryKeyInfo)(table)[0];
|
|
168
|
-
const scalarFields = (0, utils_1.getScalarFields)(table);
|
|
169
|
-
const editableFields = (0, docs_utils_1.getEditableFields)(table);
|
|
170
|
-
tools.push({
|
|
171
|
-
name: `orm_${(0, utils_1.lcFirst)(singularName)}_findMany`,
|
|
172
|
-
description: table.description || `List all ${table.name} records via ORM`,
|
|
173
|
-
inputSchema: {
|
|
174
|
-
type: 'object',
|
|
175
|
-
properties: {
|
|
176
|
-
first: {
|
|
177
|
-
type: 'integer',
|
|
178
|
-
description: 'Limit number of results',
|
|
179
|
-
},
|
|
180
|
-
offset: {
|
|
181
|
-
type: 'integer',
|
|
182
|
-
description: 'Offset for pagination',
|
|
183
|
-
},
|
|
184
|
-
},
|
|
185
|
-
},
|
|
186
|
-
});
|
|
187
|
-
tools.push({
|
|
188
|
-
name: `orm_${(0, utils_1.lcFirst)(singularName)}_findOne`,
|
|
189
|
-
description: table.description || `Get a single ${table.name} record by ${pk.name}`,
|
|
190
|
-
inputSchema: {
|
|
191
|
-
type: 'object',
|
|
192
|
-
properties: {
|
|
193
|
-
[pk.name]: {
|
|
194
|
-
type: (0, docs_utils_1.gqlTypeToJsonSchemaType)(pk.gqlType),
|
|
195
|
-
description: `${table.name} ${pk.name}`,
|
|
196
|
-
},
|
|
197
|
-
},
|
|
198
|
-
required: [pk.name],
|
|
199
|
-
},
|
|
200
|
-
});
|
|
201
|
-
const createProps = {};
|
|
202
|
-
for (const f of editableFields) {
|
|
203
|
-
createProps[f.name] = {
|
|
204
|
-
type: (0, docs_utils_1.gqlTypeToJsonSchemaType)(f.type.gqlType),
|
|
205
|
-
description: `${table.name} ${f.name}`,
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
tools.push({
|
|
209
|
-
name: `orm_${(0, utils_1.lcFirst)(singularName)}_create`,
|
|
210
|
-
description: table.description || `Create a new ${table.name} record`,
|
|
211
|
-
inputSchema: {
|
|
212
|
-
type: 'object',
|
|
213
|
-
properties: createProps,
|
|
214
|
-
required: editableFields.map((f) => f.name),
|
|
215
|
-
},
|
|
216
|
-
});
|
|
217
|
-
const updateProps = {
|
|
218
|
-
[pk.name]: {
|
|
219
|
-
type: (0, docs_utils_1.gqlTypeToJsonSchemaType)(pk.gqlType),
|
|
220
|
-
description: `${table.name} ${pk.name}`,
|
|
221
|
-
},
|
|
222
|
-
};
|
|
223
|
-
for (const f of editableFields) {
|
|
224
|
-
updateProps[f.name] = {
|
|
225
|
-
type: (0, docs_utils_1.gqlTypeToJsonSchemaType)(f.type.gqlType),
|
|
226
|
-
description: `${table.name} ${f.name}`,
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
tools.push({
|
|
230
|
-
name: `orm_${(0, utils_1.lcFirst)(singularName)}_update`,
|
|
231
|
-
description: table.description || `Update an existing ${table.name} record`,
|
|
232
|
-
inputSchema: {
|
|
233
|
-
type: 'object',
|
|
234
|
-
properties: updateProps,
|
|
235
|
-
required: [pk.name],
|
|
236
|
-
},
|
|
237
|
-
});
|
|
238
|
-
tools.push({
|
|
239
|
-
name: `orm_${(0, utils_1.lcFirst)(singularName)}_delete`,
|
|
240
|
-
description: table.description || `Delete a ${table.name} record by ${pk.name}`,
|
|
241
|
-
inputSchema: {
|
|
242
|
-
type: 'object',
|
|
243
|
-
properties: {
|
|
244
|
-
[pk.name]: {
|
|
245
|
-
type: (0, docs_utils_1.gqlTypeToJsonSchemaType)(pk.gqlType),
|
|
246
|
-
description: `${table.name} ${pk.name}`,
|
|
247
|
-
},
|
|
248
|
-
},
|
|
249
|
-
required: [pk.name],
|
|
250
|
-
},
|
|
251
|
-
_meta: {
|
|
252
|
-
fields: scalarFields.map((f) => ({
|
|
253
|
-
name: f.name,
|
|
254
|
-
type: f.type.gqlType,
|
|
255
|
-
editable: editableFields.some((ef) => ef.name === f.name),
|
|
256
|
-
primaryKey: f.name === pk.name,
|
|
257
|
-
})),
|
|
258
|
-
},
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
for (const op of customOperations) {
|
|
262
|
-
const accessor = op.kind === 'query' ? 'query' : 'mutation';
|
|
263
|
-
const props = {};
|
|
264
|
-
const required = [];
|
|
265
|
-
for (const arg of op.args) {
|
|
266
|
-
const isRequired = arg.type.kind === 'NON_NULL';
|
|
267
|
-
const baseType = isRequired && arg.type.ofType ? arg.type.ofType : arg.type;
|
|
268
|
-
props[arg.name] = {
|
|
269
|
-
type: (0, docs_utils_1.gqlTypeToJsonSchemaType)(baseType.name ?? 'String'),
|
|
270
|
-
description: arg.description || arg.name,
|
|
271
|
-
};
|
|
272
|
-
if (isRequired) {
|
|
273
|
-
required.push(arg.name);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
tools.push({
|
|
277
|
-
name: `orm_${accessor}_${op.name}`,
|
|
278
|
-
description: op.description || `Execute ${op.name} ${op.kind}`,
|
|
279
|
-
inputSchema: {
|
|
280
|
-
type: 'object',
|
|
281
|
-
properties: props,
|
|
282
|
-
...(required.length > 0 ? { required } : {}),
|
|
283
|
-
},
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
return tools;
|
|
287
|
-
}
|
|
288
162
|
function generateOrmSkills(tables, customOperations, targetName, registry) {
|
|
289
163
|
const files = [];
|
|
290
164
|
const skillName = `orm-${targetName}`;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { GraphQLSDKConfigTarget } from '../../types/config';
|
|
2
|
-
import type { GeneratedDocFile
|
|
2
|
+
import type { GeneratedDocFile } from './docs-utils';
|
|
3
3
|
export interface TargetReadmeOptions {
|
|
4
4
|
hasOrm: boolean;
|
|
5
5
|
hasHooks: boolean;
|
|
@@ -10,7 +10,6 @@ export interface TargetReadmeOptions {
|
|
|
10
10
|
config: GraphQLSDKConfigTarget;
|
|
11
11
|
}
|
|
12
12
|
export declare function generateTargetReadme(options: TargetReadmeOptions): GeneratedDocFile;
|
|
13
|
-
export declare function generateCombinedMcpConfig(tools: McpTool[], name: string): GeneratedDocFile;
|
|
14
13
|
export interface RootRootReadmeTarget {
|
|
15
14
|
name: string;
|
|
16
15
|
output: string;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateTargetReadme = generateTargetReadme;
|
|
4
|
-
exports.generateCombinedMcpConfig = generateCombinedMcpConfig;
|
|
5
4
|
exports.generateRootRootReadme = generateRootRootReadme;
|
|
6
5
|
const docs_utils_1 = require("./docs-utils");
|
|
7
6
|
function generateTargetReadme(options) {
|
|
@@ -77,18 +76,6 @@ function generateTargetReadme(options) {
|
|
|
77
76
|
content: lines.join('\n'),
|
|
78
77
|
};
|
|
79
78
|
}
|
|
80
|
-
function generateCombinedMcpConfig(tools, name) {
|
|
81
|
-
const mcpConfig = {
|
|
82
|
-
name,
|
|
83
|
-
version: '1.0.0',
|
|
84
|
-
description: `MCP tool definitions for ${name} SDK (auto-generated from GraphQL schema)`,
|
|
85
|
-
tools,
|
|
86
|
-
};
|
|
87
|
-
return {
|
|
88
|
-
fileName: 'mcp.json',
|
|
89
|
-
content: JSON.stringify(mcpConfig, null, 2) + '\n',
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
79
|
function generateRootRootReadme(targets) {
|
|
93
80
|
const lines = [];
|
|
94
81
|
lines.push(...(0, docs_utils_1.getReadmeHeader)('GraphQL SDK'));
|