@constructive-io/graphql-codegen 4.16.1 → 4.17.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.js +10 -10
- package/core/codegen/docs-utils.d.ts +23 -1
- package/core/codegen/docs-utils.js +52 -2
- package/core/codegen/hooks-docs-generator.d.ts +3 -3
- package/core/codegen/hooks-docs-generator.js +7 -7
- package/core/codegen/orm/docs-generator.d.ts +3 -3
- package/core/codegen/orm/docs-generator.js +16 -16
- package/core/codegen/schema-types-generator.js +54 -0
- package/core/generate.js +4 -4
- package/esm/core/codegen/cli/docs-generator.js +10 -10
- package/esm/core/codegen/docs-utils.d.ts +23 -1
- package/esm/core/codegen/docs-utils.js +49 -2
- package/esm/core/codegen/hooks-docs-generator.d.ts +3 -3
- package/esm/core/codegen/hooks-docs-generator.js +8 -8
- package/esm/core/codegen/orm/docs-generator.d.ts +3 -3
- package/esm/core/codegen/orm/docs-generator.js +17 -17
- package/esm/core/codegen/schema-types-generator.js +54 -0
- package/esm/core/generate.js +4 -4
- package/esm/types/schema.d.ts +2 -0
- package/package.json +4 -4
- package/types/schema.d.ts +2 -0
|
@@ -544,8 +544,8 @@ function generateSkills(tables, customOperations, toolName, targetName, registry
|
|
|
544
544
|
const editableFields = (0, docs_utils_1.getEditableFields)(table, registry);
|
|
545
545
|
const defaultFields = (0, table_command_generator_1.getFieldsWithDefaults)(table, registry);
|
|
546
546
|
const createFlags = [
|
|
547
|
-
...editableFields.filter((f) => !defaultFields.has(f.name)).map((f) => `--${f.name}
|
|
548
|
-
...editableFields.filter((f) => defaultFields.has(f.name)).map((f) => `[--${f.name}
|
|
547
|
+
...editableFields.filter((f) => !defaultFields.has(f.name)).map((f) => `--${f.name} <${(0, docs_utils_1.cleanTypeName)(f.type.gqlType)}>`),
|
|
548
|
+
...editableFields.filter((f) => defaultFields.has(f.name)).map((f) => `[--${f.name} <${(0, docs_utils_1.cleanTypeName)(f.type.gqlType)}>]`),
|
|
549
549
|
].join(' ');
|
|
550
550
|
referenceNames.push(kebab);
|
|
551
551
|
const skillSpecialGroups = (0, docs_utils_1.categorizeSpecialFields)(table, registry);
|
|
@@ -560,10 +560,10 @@ function generateSkills(tables, customOperations, toolName, targetName, registry
|
|
|
560
560
|
description: skillSpecialDesc,
|
|
561
561
|
usage: [
|
|
562
562
|
`${toolName} ${kebab} list`,
|
|
563
|
-
`${toolName} ${kebab} get --${pk.name}
|
|
563
|
+
`${toolName} ${kebab} get --${pk.name} <${(0, docs_utils_1.cleanTypeName)(pk.gqlType)}>`,
|
|
564
564
|
`${toolName} ${kebab} create ${createFlags}`,
|
|
565
|
-
`${toolName} ${kebab} update --${pk.name}
|
|
566
|
-
`${toolName} ${kebab} delete --${pk.name}
|
|
565
|
+
`${toolName} ${kebab} update --${pk.name} <${(0, docs_utils_1.cleanTypeName)(pk.gqlType)}> ${editableFields.map((f) => `[--${f.name} <${(0, docs_utils_1.cleanTypeName)(f.type.gqlType)}>]`).join(' ')}`,
|
|
566
|
+
`${toolName} ${kebab} delete --${pk.name} <${(0, docs_utils_1.cleanTypeName)(pk.gqlType)}>`,
|
|
567
567
|
],
|
|
568
568
|
examples: [
|
|
569
569
|
{
|
|
@@ -1345,8 +1345,8 @@ function generateMultiTargetSkills(input) {
|
|
|
1345
1345
|
const editableFields = (0, docs_utils_1.getEditableFields)(table, registry);
|
|
1346
1346
|
const defaultFields = (0, table_command_generator_1.getFieldsWithDefaults)(table, registry);
|
|
1347
1347
|
const createFlags = [
|
|
1348
|
-
...editableFields.filter((f) => !defaultFields.has(f.name)).map((f) => `--${f.name}
|
|
1349
|
-
...editableFields.filter((f) => defaultFields.has(f.name)).map((f) => `[--${f.name}
|
|
1348
|
+
...editableFields.filter((f) => !defaultFields.has(f.name)).map((f) => `--${f.name} <${(0, docs_utils_1.cleanTypeName)(f.type.gqlType)}>`),
|
|
1349
|
+
...editableFields.filter((f) => defaultFields.has(f.name)).map((f) => `[--${f.name} <${(0, docs_utils_1.cleanTypeName)(f.type.gqlType)}>]`),
|
|
1350
1350
|
].join(' ');
|
|
1351
1351
|
const cmd = `${tgt.name}:${kebab}`;
|
|
1352
1352
|
tgtReferenceNames.push(kebab);
|
|
@@ -1362,10 +1362,10 @@ function generateMultiTargetSkills(input) {
|
|
|
1362
1362
|
description: mtSkillSpecialDesc,
|
|
1363
1363
|
usage: [
|
|
1364
1364
|
`${toolName} ${cmd} list`,
|
|
1365
|
-
`${toolName} ${cmd} get --${pk.name}
|
|
1365
|
+
`${toolName} ${cmd} get --${pk.name} <${(0, docs_utils_1.cleanTypeName)(pk.gqlType)}>`,
|
|
1366
1366
|
`${toolName} ${cmd} create ${createFlags}`,
|
|
1367
|
-
`${toolName} ${cmd} update --${pk.name}
|
|
1368
|
-
`${toolName} ${cmd} delete --${pk.name}
|
|
1367
|
+
`${toolName} ${cmd} update --${pk.name} <${(0, docs_utils_1.cleanTypeName)(pk.gqlType)}> ${editableFields.map((f) => `[--${f.name} <${(0, docs_utils_1.cleanTypeName)(f.type.gqlType)}>]`).join(' ')}`,
|
|
1368
|
+
`${toolName} ${cmd} delete --${pk.name} <${(0, docs_utils_1.cleanTypeName)(pk.gqlType)}>`,
|
|
1369
1369
|
],
|
|
1370
1370
|
examples: [
|
|
1371
1371
|
{
|
|
@@ -93,9 +93,31 @@ export declare function cleanTypeName(name: string): string;
|
|
|
93
93
|
export declare function flattenArgs(args: CleanArgument[], registry?: TypeRegistry): FlattenedArg[];
|
|
94
94
|
/**
|
|
95
95
|
* Build CLI flags string from flattened args.
|
|
96
|
-
* e.g. '--input.email <
|
|
96
|
+
* e.g. '--input.email <String> --input.password <String>'
|
|
97
97
|
*/
|
|
98
98
|
export declare function flattenedArgsToFlags(flatArgs: FlattenedArg[]): string;
|
|
99
|
+
/**
|
|
100
|
+
* Generate a type-aware placeholder for a table field value in code examples.
|
|
101
|
+
* Returns a quoted placeholder string, e.g. `'<UUID>'`, `'<String>'`, `'<Int>'`.
|
|
102
|
+
*/
|
|
103
|
+
export declare function fieldPlaceholder(field: CleanField): string;
|
|
104
|
+
/**
|
|
105
|
+
* Generate a type-aware placeholder for a primary key value in code examples.
|
|
106
|
+
* PrimaryKeyField has `gqlType` directly (not nested under `.type`).
|
|
107
|
+
*/
|
|
108
|
+
export declare function pkPlaceholder(pk: {
|
|
109
|
+
gqlType: string;
|
|
110
|
+
}): string;
|
|
111
|
+
/**
|
|
112
|
+
* Generate a type-aware placeholder for an operation argument value.
|
|
113
|
+
*
|
|
114
|
+
* - Scalar args: `'<String>'`
|
|
115
|
+
* - INPUT_OBJECT with resolvable fields (up to a limit): `{ email: '<String>', password: '<String>' }`
|
|
116
|
+
* - INPUT_OBJECT without resolvable fields: `'<TypeName>'`
|
|
117
|
+
*
|
|
118
|
+
* The result is a ready-to-embed JS expression (quotes included for scalars).
|
|
119
|
+
*/
|
|
120
|
+
export declare function argPlaceholder(arg: CleanArgument, registry?: TypeRegistry): string;
|
|
99
121
|
export declare function gqlTypeToJsonSchemaType(gqlType: string): string;
|
|
100
122
|
export declare function buildSkillFile(skill: SkillDefinition, referenceNames?: string[]): string;
|
|
101
123
|
export declare function buildSkillReference(ref: SkillReferenceDefinition): string;
|
|
@@ -13,6 +13,9 @@ exports.buildSpecialFieldsPlain = buildSpecialFieldsPlain;
|
|
|
13
13
|
exports.cleanTypeName = cleanTypeName;
|
|
14
14
|
exports.flattenArgs = flattenArgs;
|
|
15
15
|
exports.flattenedArgsToFlags = flattenedArgsToFlags;
|
|
16
|
+
exports.fieldPlaceholder = fieldPlaceholder;
|
|
17
|
+
exports.pkPlaceholder = pkPlaceholder;
|
|
18
|
+
exports.argPlaceholder = argPlaceholder;
|
|
16
19
|
exports.gqlTypeToJsonSchemaType = gqlTypeToJsonSchemaType;
|
|
17
20
|
exports.buildSkillFile = buildSkillFile;
|
|
18
21
|
exports.buildSkillReference = buildSkillReference;
|
|
@@ -343,10 +346,57 @@ function flattenArgs(args, registry) {
|
|
|
343
346
|
}
|
|
344
347
|
/**
|
|
345
348
|
* Build CLI flags string from flattened args.
|
|
346
|
-
* e.g. '--input.email <
|
|
349
|
+
* e.g. '--input.email <String> --input.password <String>'
|
|
347
350
|
*/
|
|
348
351
|
function flattenedArgsToFlags(flatArgs) {
|
|
349
|
-
return flatArgs.map((a) => `--${a.flag}
|
|
352
|
+
return flatArgs.map((a) => `--${a.flag} <${a.type}>`).join(' ');
|
|
353
|
+
}
|
|
354
|
+
// ---------------------------------------------------------------------------
|
|
355
|
+
// Type-aware placeholder helpers for code examples
|
|
356
|
+
// ---------------------------------------------------------------------------
|
|
357
|
+
/**
|
|
358
|
+
* Generate a type-aware placeholder for a table field value in code examples.
|
|
359
|
+
* Returns a quoted placeholder string, e.g. `'<UUID>'`, `'<String>'`, `'<Int>'`.
|
|
360
|
+
*/
|
|
361
|
+
function fieldPlaceholder(field) {
|
|
362
|
+
return `'<${cleanTypeName(field.type.gqlType)}>'`;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Generate a type-aware placeholder for a primary key value in code examples.
|
|
366
|
+
* PrimaryKeyField has `gqlType` directly (not nested under `.type`).
|
|
367
|
+
*/
|
|
368
|
+
function pkPlaceholder(pk) {
|
|
369
|
+
return `'<${cleanTypeName(pk.gqlType)}>'`;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Generate a type-aware placeholder for an operation argument value.
|
|
373
|
+
*
|
|
374
|
+
* - Scalar args: `'<String>'`
|
|
375
|
+
* - INPUT_OBJECT with resolvable fields (up to a limit): `{ email: '<String>', password: '<String>' }`
|
|
376
|
+
* - INPUT_OBJECT without resolvable fields: `'<TypeName>'`
|
|
377
|
+
*
|
|
378
|
+
* The result is a ready-to-embed JS expression (quotes included for scalars).
|
|
379
|
+
*/
|
|
380
|
+
function argPlaceholder(arg, registry) {
|
|
381
|
+
const { inner } = unwrapNonNull(arg.type);
|
|
382
|
+
if (inner.kind === 'INPUT_OBJECT') {
|
|
383
|
+
const fields = resolveInputFields(inner, registry);
|
|
384
|
+
if (fields && fields.length > 0) {
|
|
385
|
+
const meaningful = fields.filter((f) => f.name !== 'clientMutationId');
|
|
386
|
+
if (meaningful.length > 0 && meaningful.length <= 5) {
|
|
387
|
+
const parts = meaningful.map((f) => {
|
|
388
|
+
const typeName = cleanTypeName(getScalarTypeName(f.type));
|
|
389
|
+
return `${f.name}: '<${typeName}>'`;
|
|
390
|
+
});
|
|
391
|
+
return '{ ' + parts.join(', ') + ' }';
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
if (inner.name) {
|
|
395
|
+
return `'<${cleanTypeName(inner.name)}>'`;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
const typeName = cleanTypeName(getScalarTypeName(arg.type));
|
|
399
|
+
return `'<${typeName}>'`;
|
|
350
400
|
}
|
|
351
401
|
function gqlTypeToJsonSchemaType(gqlType) {
|
|
352
402
|
switch (gqlType) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { CleanOperation, CleanTable } from '../../types/schema';
|
|
1
|
+
import type { CleanOperation, CleanTable, TypeRegistry } from '../../types/schema';
|
|
2
2
|
import type { GeneratedDocFile, McpTool } from './docs-utils';
|
|
3
|
-
export declare function generateHooksReadme(tables: CleanTable[], customOperations: CleanOperation[]): GeneratedDocFile;
|
|
3
|
+
export declare function generateHooksReadme(tables: CleanTable[], customOperations: CleanOperation[], registry?: TypeRegistry): GeneratedDocFile;
|
|
4
4
|
export declare function generateHooksAgentsDocs(tables: CleanTable[], customOperations: CleanOperation[]): GeneratedDocFile;
|
|
5
5
|
export declare function getHooksMcpTools(tables: CleanTable[], customOperations: CleanOperation[]): McpTool[];
|
|
6
|
-
export declare function generateHooksSkills(tables: CleanTable[], customOperations: CleanOperation[], targetName: string): GeneratedDocFile[];
|
|
6
|
+
export declare function generateHooksSkills(tables: CleanTable[], customOperations: CleanOperation[], targetName: string, registry?: TypeRegistry): GeneratedDocFile[];
|
|
@@ -13,7 +13,7 @@ function getCustomHookName(op) {
|
|
|
13
13
|
}
|
|
14
14
|
return `use${(0, utils_1.ucFirst)(op.name)}Mutation`;
|
|
15
15
|
}
|
|
16
|
-
function generateHooksReadme(tables, customOperations) {
|
|
16
|
+
function generateHooksReadme(tables, customOperations, registry) {
|
|
17
17
|
const lines = [];
|
|
18
18
|
lines.push(...(0, docs_utils_1.getReadmeHeader)('React Query Hooks'));
|
|
19
19
|
lines.push('## Setup');
|
|
@@ -76,7 +76,7 @@ function generateHooksReadme(tables, customOperations) {
|
|
|
76
76
|
if ((0, utils_1.hasValidPrimaryKey)(table)) {
|
|
77
77
|
lines.push(`// Get one ${singularName}`);
|
|
78
78
|
lines.push(`const { data: item } = ${(0, utils_1.getSingleQueryHookName)(table)}({`);
|
|
79
|
-
lines.push(` ${pk.name}:
|
|
79
|
+
lines.push(` ${pk.name}: ${(0, docs_utils_1.pkPlaceholder)(pk)},`);
|
|
80
80
|
lines.push(` selection: { fields: { ${scalarFields.map((f) => `${f.name}: true`).join(', ')} } },`);
|
|
81
81
|
lines.push('});');
|
|
82
82
|
lines.push('');
|
|
@@ -85,7 +85,7 @@ function generateHooksReadme(tables, customOperations) {
|
|
|
85
85
|
lines.push(`const { mutate: create } = ${(0, utils_1.getCreateMutationHookName)(table)}({`);
|
|
86
86
|
lines.push(` selection: { fields: { ${pk.name}: true } },`);
|
|
87
87
|
lines.push('});');
|
|
88
|
-
lines.push(`create({ ${scalarFields.filter((f) => f.name !== pk.name && f.name !== 'nodeId' && f.name !== 'createdAt' && f.name !== 'updatedAt').map((f) => `${f.name}:
|
|
88
|
+
lines.push(`create({ ${scalarFields.filter((f) => f.name !== pk.name && f.name !== 'nodeId' && f.name !== 'createdAt' && f.name !== 'updatedAt').map((f) => `${f.name}: ${(0, docs_utils_1.fieldPlaceholder)(f)}`).join(', ')} });`);
|
|
89
89
|
lines.push('```');
|
|
90
90
|
lines.push('');
|
|
91
91
|
}
|
|
@@ -279,7 +279,7 @@ function getHooksMcpTools(tables, customOperations) {
|
|
|
279
279
|
}
|
|
280
280
|
return tools;
|
|
281
281
|
}
|
|
282
|
-
function generateHooksSkills(tables, customOperations, targetName) {
|
|
282
|
+
function generateHooksSkills(tables, customOperations, targetName, registry) {
|
|
283
283
|
const files = [];
|
|
284
284
|
const skillName = `hooks-${targetName}`;
|
|
285
285
|
const referenceNames = [];
|
|
@@ -303,7 +303,7 @@ function generateHooksSkills(tables, customOperations, targetName) {
|
|
|
303
303
|
`${(0, utils_1.getListQueryHookName)(table)}({ selection: { fields: { ${selectFields} } } })`,
|
|
304
304
|
...((0, utils_1.hasValidPrimaryKey)(table)
|
|
305
305
|
? [
|
|
306
|
-
`${(0, utils_1.getSingleQueryHookName)(table)}({ ${pk.name}:
|
|
306
|
+
`${(0, utils_1.getSingleQueryHookName)(table)}({ ${pk.name}: ${(0, docs_utils_1.pkPlaceholder)(pk)}, selection: { fields: { ${selectFields} } } })`,
|
|
307
307
|
]
|
|
308
308
|
: []),
|
|
309
309
|
`${(0, utils_1.getCreateMutationHookName)(table)}({ selection: { fields: { ${pk.name}: true } } })`,
|
|
@@ -329,7 +329,7 @@ function generateHooksSkills(tables, customOperations, targetName) {
|
|
|
329
329
|
`const { mutate } = ${(0, utils_1.getCreateMutationHookName)(table)}({`,
|
|
330
330
|
` selection: { fields: { ${pk.name}: true } },`,
|
|
331
331
|
'});',
|
|
332
|
-
`mutate({ ${scalarFields.filter((f) => f.name !== pk.name && f.name !== 'nodeId' && f.name !== 'createdAt' && f.name !== 'updatedAt').map((f) => `${f.name}:
|
|
332
|
+
`mutate({ ${scalarFields.filter((f) => f.name !== pk.name && f.name !== 'nodeId' && f.name !== 'createdAt' && f.name !== 'updatedAt').map((f) => `${f.name}: ${(0, docs_utils_1.fieldPlaceholder)(f)}`).join(', ')} });`,
|
|
333
333
|
],
|
|
334
334
|
},
|
|
335
335
|
],
|
|
@@ -340,7 +340,7 @@ function generateHooksSkills(tables, customOperations, targetName) {
|
|
|
340
340
|
for (const op of customOperations) {
|
|
341
341
|
const hookName = getCustomHookName(op);
|
|
342
342
|
const callArgs = op.args.length > 0
|
|
343
|
-
? `{ ${op.args.map((a) => `${a.name}:
|
|
343
|
+
? `{ ${op.args.map((a) => `${a.name}: ${(0, docs_utils_1.argPlaceholder)(a, registry)}`).join(', ')} }`
|
|
344
344
|
: '';
|
|
345
345
|
const refName = (0, komoji_1.toKebabCase)(op.name);
|
|
346
346
|
referenceNames.push(refName);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { CleanOperation, CleanTable } from '../../../types/schema';
|
|
1
|
+
import type { CleanOperation, CleanTable, TypeRegistry } from '../../../types/schema';
|
|
2
2
|
import type { GeneratedDocFile, McpTool } from '../docs-utils';
|
|
3
|
-
export declare function generateOrmReadme(tables: CleanTable[], customOperations: CleanOperation[]): GeneratedDocFile;
|
|
3
|
+
export declare function generateOrmReadme(tables: CleanTable[], customOperations: CleanOperation[], registry?: TypeRegistry): GeneratedDocFile;
|
|
4
4
|
export declare function generateOrmAgentsDocs(tables: CleanTable[], customOperations: CleanOperation[]): GeneratedDocFile;
|
|
5
5
|
export declare function getOrmMcpTools(tables: CleanTable[], customOperations: CleanOperation[]): McpTool[];
|
|
6
|
-
export declare function generateOrmSkills(tables: CleanTable[], customOperations: CleanOperation[], targetName: string): GeneratedDocFile[];
|
|
6
|
+
export declare function generateOrmSkills(tables: CleanTable[], customOperations: CleanOperation[], targetName: string, registry?: TypeRegistry): GeneratedDocFile[];
|
|
@@ -7,7 +7,7 @@ exports.generateOrmSkills = generateOrmSkills;
|
|
|
7
7
|
const komoji_1 = require("komoji");
|
|
8
8
|
const docs_utils_1 = require("../docs-utils");
|
|
9
9
|
const utils_1 = require("../utils");
|
|
10
|
-
function generateOrmReadme(tables, customOperations) {
|
|
10
|
+
function generateOrmReadme(tables, customOperations, registry) {
|
|
11
11
|
const lines = [];
|
|
12
12
|
lines.push(...(0, docs_utils_1.getReadmeHeader)('ORM Client'));
|
|
13
13
|
lines.push('## Setup');
|
|
@@ -58,16 +58,16 @@ function generateOrmReadme(tables, customOperations) {
|
|
|
58
58
|
lines.push(`const items = await db.${singularName}.findMany({ select: { ${scalarFields.map((f) => `${f.name}: true`).join(', ')} } }).execute();`);
|
|
59
59
|
lines.push('');
|
|
60
60
|
lines.push(`// Get one by ${pk.name}`);
|
|
61
|
-
lines.push(`const item = await db.${singularName}.findOne({ ${pk.name}:
|
|
61
|
+
lines.push(`const item = await db.${singularName}.findOne({ ${pk.name}: ${(0, docs_utils_1.pkPlaceholder)(pk)}, select: { ${scalarFields.map((f) => `${f.name}: true`).join(', ')} } }).execute();`);
|
|
62
62
|
lines.push('');
|
|
63
63
|
lines.push(`// Create`);
|
|
64
|
-
lines.push(`const created = await db.${singularName}.create({ data: { ${editableFields.map((f) => `${f.name}:
|
|
64
|
+
lines.push(`const created = await db.${singularName}.create({ data: { ${editableFields.map((f) => `${f.name}: ${(0, docs_utils_1.fieldPlaceholder)(f)}`).join(', ')} }, select: { ${pk.name}: true } }).execute();`);
|
|
65
65
|
lines.push('');
|
|
66
66
|
lines.push(`// Update`);
|
|
67
|
-
lines.push(`const updated = await db.${singularName}.update({ where: { ${pk.name}:
|
|
67
|
+
lines.push(`const updated = await db.${singularName}.update({ where: { ${pk.name}: ${(0, docs_utils_1.pkPlaceholder)(pk)} }, data: { ${editableFields[0]?.name || 'field'}: ${editableFields[0] ? (0, docs_utils_1.fieldPlaceholder)(editableFields[0]) : "'<String>'"} }, select: { ${pk.name}: true } }).execute();`);
|
|
68
68
|
lines.push('');
|
|
69
69
|
lines.push(`// Delete`);
|
|
70
|
-
lines.push(`const deleted = await db.${singularName}.delete({ where: { ${pk.name}:
|
|
70
|
+
lines.push(`const deleted = await db.${singularName}.delete({ where: { ${pk.name}: ${(0, docs_utils_1.pkPlaceholder)(pk)} } }).execute();`);
|
|
71
71
|
lines.push('```');
|
|
72
72
|
lines.push('');
|
|
73
73
|
const ormSpecialGroups = (0, docs_utils_1.categorizeSpecialFields)(table);
|
|
@@ -94,7 +94,7 @@ function generateOrmReadme(tables, customOperations) {
|
|
|
94
94
|
}
|
|
95
95
|
lines.push('');
|
|
96
96
|
lines.push('```typescript');
|
|
97
|
-
lines.push(`const result = await db.${accessor}.${op.name}({ ${op.args.map((a) => `${a.name}:
|
|
97
|
+
lines.push(`const result = await db.${accessor}.${op.name}({ ${op.args.map((a) => `${a.name}: ${(0, docs_utils_1.argPlaceholder)(a, registry)}`).join(', ')} }).execute();`);
|
|
98
98
|
lines.push('```');
|
|
99
99
|
}
|
|
100
100
|
else {
|
|
@@ -285,7 +285,7 @@ function getOrmMcpTools(tables, customOperations) {
|
|
|
285
285
|
}
|
|
286
286
|
return tools;
|
|
287
287
|
}
|
|
288
|
-
function generateOrmSkills(tables, customOperations, targetName) {
|
|
288
|
+
function generateOrmSkills(tables, customOperations, targetName, registry) {
|
|
289
289
|
const files = [];
|
|
290
290
|
const skillName = `orm-${targetName}`;
|
|
291
291
|
const referenceNames = [];
|
|
@@ -311,10 +311,10 @@ function generateOrmSkills(tables, customOperations, targetName) {
|
|
|
311
311
|
language: 'typescript',
|
|
312
312
|
usage: [
|
|
313
313
|
`db.${modelName}.findMany({ select: { id: true } }).execute()`,
|
|
314
|
-
`db.${modelName}.findOne({ ${pk.name}:
|
|
315
|
-
`db.${modelName}.create({ data: { ${editableFields.map((f) => `${f.name}:
|
|
316
|
-
`db.${modelName}.update({ where: { ${pk.name}:
|
|
317
|
-
`db.${modelName}.delete({ where: { ${pk.name}:
|
|
314
|
+
`db.${modelName}.findOne({ ${pk.name}: ${(0, docs_utils_1.pkPlaceholder)(pk)}, select: { id: true } }).execute()`,
|
|
315
|
+
`db.${modelName}.create({ data: { ${editableFields.map((f) => `${f.name}: ${(0, docs_utils_1.fieldPlaceholder)(f)}`).join(', ')} }, select: { id: true } }).execute()`,
|
|
316
|
+
`db.${modelName}.update({ where: { ${pk.name}: ${(0, docs_utils_1.pkPlaceholder)(pk)} }, data: { ${editableFields[0]?.name || 'field'}: ${editableFields[0] ? (0, docs_utils_1.fieldPlaceholder)(editableFields[0]) : "'<String>'"} }, select: { id: true } }).execute()`,
|
|
317
|
+
`db.${modelName}.delete({ where: { ${pk.name}: ${(0, docs_utils_1.pkPlaceholder)(pk)} } }).execute()`,
|
|
318
318
|
],
|
|
319
319
|
examples: [
|
|
320
320
|
{
|
|
@@ -329,7 +329,7 @@ function generateOrmSkills(tables, customOperations, targetName) {
|
|
|
329
329
|
description: `Create a ${singularName}`,
|
|
330
330
|
code: [
|
|
331
331
|
`const item = await db.${modelName}.create({`,
|
|
332
|
-
` data: { ${editableFields.map((f) => `${f.name}:
|
|
332
|
+
` data: { ${editableFields.map((f) => `${f.name}: ${(0, docs_utils_1.fieldPlaceholder)(f)}`).join(', ')} },`,
|
|
333
333
|
` select: { ${pk.name}: true }`,
|
|
334
334
|
'}).execute();',
|
|
335
335
|
],
|
|
@@ -342,7 +342,7 @@ function generateOrmSkills(tables, customOperations, targetName) {
|
|
|
342
342
|
for (const op of customOperations) {
|
|
343
343
|
const accessor = op.kind === 'query' ? 'query' : 'mutation';
|
|
344
344
|
const callArgs = op.args.length > 0
|
|
345
|
-
? `{ ${op.args.map((a) => `${a.name}:
|
|
345
|
+
? `{ ${op.args.map((a) => `${a.name}: ${(0, docs_utils_1.argPlaceholder)(a, registry)}`).join(', ')} }`
|
|
346
346
|
: '';
|
|
347
347
|
const refName = (0, komoji_1.toKebabCase)(op.name);
|
|
348
348
|
referenceNames.push(refName);
|
|
@@ -376,10 +376,10 @@ function generateOrmSkills(tables, customOperations, targetName) {
|
|
|
376
376
|
'',
|
|
377
377
|
`// Available models: ${tableNames.slice(0, 8).join(', ')}${tableNames.length > 8 ? ', ...' : ''}`,
|
|
378
378
|
`db.<model>.findMany({ select: { id: true } }).execute()`,
|
|
379
|
-
`db.<model>.findOne({ id: '<
|
|
379
|
+
`db.<model>.findOne({ id: '<UUID>', select: { id: true } }).execute()`,
|
|
380
380
|
`db.<model>.create({ data: { ... }, select: { id: true } }).execute()`,
|
|
381
|
-
`db.<model>.update({ where: { id: '<
|
|
382
|
-
`db.<model>.delete({ where: { id: '<
|
|
381
|
+
`db.<model>.update({ where: { id: '<UUID>' }, data: { ... }, select: { id: true } }).execute()`,
|
|
382
|
+
`db.<model>.delete({ where: { id: '<UUID>' } }).execute()`,
|
|
383
383
|
],
|
|
384
384
|
examples: [
|
|
385
385
|
{
|
|
@@ -137,6 +137,55 @@ function generateEnumTypes(typeRegistry, tableTypeNames, comments = true) {
|
|
|
137
137
|
}
|
|
138
138
|
return { statements, generatedTypes };
|
|
139
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Generate a discriminated union type for a @oneOf INPUT_OBJECT.
|
|
142
|
+
*
|
|
143
|
+
* For a @oneOf input like:
|
|
144
|
+
* input BlueprintNodeInput @oneOf {
|
|
145
|
+
* shorthand: String
|
|
146
|
+
* DataId: DataIdParams
|
|
147
|
+
* DataTimestamps: DataTimestampsParams
|
|
148
|
+
* }
|
|
149
|
+
*
|
|
150
|
+
* Generates:
|
|
151
|
+
* type BlueprintNodeInput =
|
|
152
|
+
* | { shorthand: string }
|
|
153
|
+
* | { DataId: DataIdParams }
|
|
154
|
+
* | { DataTimestamps: DataTimestampsParams }
|
|
155
|
+
*/
|
|
156
|
+
function generateOneOfUnionType(typeName, typeInfo, typeRegistry, tableTypeNames, generatedTypes, typesToGenerate, comments) {
|
|
157
|
+
const unionMembers = [];
|
|
158
|
+
if (typeInfo.inputFields && typeInfo.inputFields.length > 0) {
|
|
159
|
+
for (const field of typeInfo.inputFields) {
|
|
160
|
+
const tsType = typeRefToTs(field.type);
|
|
161
|
+
// Each @oneOf field becomes a single-property object type in the union
|
|
162
|
+
const prop = t.tsPropertySignature(t.identifier(field.name), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(tsType))));
|
|
163
|
+
prop.optional = false; // In @oneOf, the chosen field is required
|
|
164
|
+
const memberType = t.tsTypeLiteral([prop]);
|
|
165
|
+
unionMembers.push(memberType);
|
|
166
|
+
// Track nested types for generation
|
|
167
|
+
const baseType = (0, type_resolver_1.getTypeBaseName)(field.type);
|
|
168
|
+
if (baseType &&
|
|
169
|
+
!generatedTypes.has(baseType) &&
|
|
170
|
+
!shouldSkipType(baseType, tableTypeNames)) {
|
|
171
|
+
const nestedType = typeRegistry.get(baseType);
|
|
172
|
+
if (nestedType?.kind === 'INPUT_OBJECT') {
|
|
173
|
+
typesToGenerate.add(baseType);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const unionType = unionMembers.length > 0
|
|
179
|
+
? t.tsUnionType(unionMembers)
|
|
180
|
+
: t.tsNeverKeyword();
|
|
181
|
+
const typeAlias = t.tsTypeAliasDeclaration(t.identifier(typeName), null, unionType);
|
|
182
|
+
const exportDecl = t.exportNamedDeclaration(typeAlias);
|
|
183
|
+
const inputDescription = (0, utils_1.stripSmartComments)(typeInfo.description, comments);
|
|
184
|
+
if (inputDescription) {
|
|
185
|
+
(0, babel_ast_1.addJSDocComment)(exportDecl, inputDescription.split('\n'));
|
|
186
|
+
}
|
|
187
|
+
return exportDecl;
|
|
188
|
+
}
|
|
140
189
|
function generateInputObjectTypes(typeRegistry, tableTypeNames, alreadyGenerated, comments = true) {
|
|
141
190
|
const statements = [];
|
|
142
191
|
const generatedTypes = new Set(alreadyGenerated);
|
|
@@ -162,6 +211,11 @@ function generateInputObjectTypes(typeRegistry, tableTypeNames, alreadyGenerated
|
|
|
162
211
|
if (!typeInfo || typeInfo.kind !== 'INPUT_OBJECT')
|
|
163
212
|
continue;
|
|
164
213
|
generatedTypes.add(typeName);
|
|
214
|
+
// @oneOf types become discriminated unions instead of interfaces
|
|
215
|
+
if (typeInfo.isOneOf) {
|
|
216
|
+
statements.push(generateOneOfUnionType(typeName, typeInfo, typeRegistry, tableTypeNames, generatedTypes, typesToGenerate, comments));
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
165
219
|
const properties = [];
|
|
166
220
|
if (typeInfo.inputFields && typeInfo.inputFields.length > 0) {
|
|
167
221
|
for (const field of typeInfo.inputFields) {
|
package/core/generate.js
CHANGED
|
@@ -279,7 +279,7 @@ async function generate(options = {}, internalOptions) {
|
|
|
279
279
|
const skillsToWrite = [];
|
|
280
280
|
if (runOrm) {
|
|
281
281
|
if (docsConfig.readme) {
|
|
282
|
-
const readme = (0, docs_generator_2.generateOrmReadme)(tables, allCustomOps);
|
|
282
|
+
const readme = (0, docs_generator_2.generateOrmReadme)(tables, allCustomOps, customOperations.typeRegistry);
|
|
283
283
|
filesToWrite.push({ path: node_path_1.default.posix.join('orm', readme.fileName), content: readme.content });
|
|
284
284
|
}
|
|
285
285
|
if (docsConfig.agents) {
|
|
@@ -290,14 +290,14 @@ async function generate(options = {}, internalOptions) {
|
|
|
290
290
|
allMcpTools.push(...(0, docs_generator_2.getOrmMcpTools)(tables, allCustomOps));
|
|
291
291
|
}
|
|
292
292
|
if (docsConfig.skills) {
|
|
293
|
-
for (const skill of (0, docs_generator_2.generateOrmSkills)(tables, allCustomOps, targetName)) {
|
|
293
|
+
for (const skill of (0, docs_generator_2.generateOrmSkills)(tables, allCustomOps, targetName, customOperations.typeRegistry)) {
|
|
294
294
|
skillsToWrite.push({ path: skill.fileName, content: skill.content });
|
|
295
295
|
}
|
|
296
296
|
}
|
|
297
297
|
}
|
|
298
298
|
if (runReactQuery) {
|
|
299
299
|
if (docsConfig.readme) {
|
|
300
|
-
const readme = (0, hooks_docs_generator_1.generateHooksReadme)(tables, allCustomOps);
|
|
300
|
+
const readme = (0, hooks_docs_generator_1.generateHooksReadme)(tables, allCustomOps, customOperations.typeRegistry);
|
|
301
301
|
filesToWrite.push({ path: node_path_1.default.posix.join('hooks', readme.fileName), content: readme.content });
|
|
302
302
|
}
|
|
303
303
|
if (docsConfig.agents) {
|
|
@@ -308,7 +308,7 @@ async function generate(options = {}, internalOptions) {
|
|
|
308
308
|
allMcpTools.push(...(0, hooks_docs_generator_1.getHooksMcpTools)(tables, allCustomOps));
|
|
309
309
|
}
|
|
310
310
|
if (docsConfig.skills) {
|
|
311
|
-
for (const skill of (0, hooks_docs_generator_1.generateHooksSkills)(tables, allCustomOps, targetName)) {
|
|
311
|
+
for (const skill of (0, hooks_docs_generator_1.generateHooksSkills)(tables, allCustomOps, targetName, customOperations.typeRegistry)) {
|
|
312
312
|
skillsToWrite.push({ path: skill.fileName, content: skill.content });
|
|
313
313
|
}
|
|
314
314
|
}
|
|
@@ -532,8 +532,8 @@ export function generateSkills(tables, customOperations, toolName, targetName, r
|
|
|
532
532
|
const editableFields = getEditableFields(table, registry);
|
|
533
533
|
const defaultFields = getFieldsWithDefaults(table, registry);
|
|
534
534
|
const createFlags = [
|
|
535
|
-
...editableFields.filter((f) => !defaultFields.has(f.name)).map((f) => `--${f.name}
|
|
536
|
-
...editableFields.filter((f) => defaultFields.has(f.name)).map((f) => `[--${f.name}
|
|
535
|
+
...editableFields.filter((f) => !defaultFields.has(f.name)).map((f) => `--${f.name} <${cleanTypeName(f.type.gqlType)}>`),
|
|
536
|
+
...editableFields.filter((f) => defaultFields.has(f.name)).map((f) => `[--${f.name} <${cleanTypeName(f.type.gqlType)}>]`),
|
|
537
537
|
].join(' ');
|
|
538
538
|
referenceNames.push(kebab);
|
|
539
539
|
const skillSpecialGroups = categorizeSpecialFields(table, registry);
|
|
@@ -548,10 +548,10 @@ export function generateSkills(tables, customOperations, toolName, targetName, r
|
|
|
548
548
|
description: skillSpecialDesc,
|
|
549
549
|
usage: [
|
|
550
550
|
`${toolName} ${kebab} list`,
|
|
551
|
-
`${toolName} ${kebab} get --${pk.name}
|
|
551
|
+
`${toolName} ${kebab} get --${pk.name} <${cleanTypeName(pk.gqlType)}>`,
|
|
552
552
|
`${toolName} ${kebab} create ${createFlags}`,
|
|
553
|
-
`${toolName} ${kebab} update --${pk.name}
|
|
554
|
-
`${toolName} ${kebab} delete --${pk.name}
|
|
553
|
+
`${toolName} ${kebab} update --${pk.name} <${cleanTypeName(pk.gqlType)}> ${editableFields.map((f) => `[--${f.name} <${cleanTypeName(f.type.gqlType)}>]`).join(' ')}`,
|
|
554
|
+
`${toolName} ${kebab} delete --${pk.name} <${cleanTypeName(pk.gqlType)}>`,
|
|
555
555
|
],
|
|
556
556
|
examples: [
|
|
557
557
|
{
|
|
@@ -1333,8 +1333,8 @@ export function generateMultiTargetSkills(input) {
|
|
|
1333
1333
|
const editableFields = getEditableFields(table, registry);
|
|
1334
1334
|
const defaultFields = getFieldsWithDefaults(table, registry);
|
|
1335
1335
|
const createFlags = [
|
|
1336
|
-
...editableFields.filter((f) => !defaultFields.has(f.name)).map((f) => `--${f.name}
|
|
1337
|
-
...editableFields.filter((f) => defaultFields.has(f.name)).map((f) => `[--${f.name}
|
|
1336
|
+
...editableFields.filter((f) => !defaultFields.has(f.name)).map((f) => `--${f.name} <${cleanTypeName(f.type.gqlType)}>`),
|
|
1337
|
+
...editableFields.filter((f) => defaultFields.has(f.name)).map((f) => `[--${f.name} <${cleanTypeName(f.type.gqlType)}>]`),
|
|
1338
1338
|
].join(' ');
|
|
1339
1339
|
const cmd = `${tgt.name}:${kebab}`;
|
|
1340
1340
|
tgtReferenceNames.push(kebab);
|
|
@@ -1350,10 +1350,10 @@ export function generateMultiTargetSkills(input) {
|
|
|
1350
1350
|
description: mtSkillSpecialDesc,
|
|
1351
1351
|
usage: [
|
|
1352
1352
|
`${toolName} ${cmd} list`,
|
|
1353
|
-
`${toolName} ${cmd} get --${pk.name}
|
|
1353
|
+
`${toolName} ${cmd} get --${pk.name} <${cleanTypeName(pk.gqlType)}>`,
|
|
1354
1354
|
`${toolName} ${cmd} create ${createFlags}`,
|
|
1355
|
-
`${toolName} ${cmd} update --${pk.name}
|
|
1356
|
-
`${toolName} ${cmd} delete --${pk.name}
|
|
1355
|
+
`${toolName} ${cmd} update --${pk.name} <${cleanTypeName(pk.gqlType)}> ${editableFields.map((f) => `[--${f.name} <${cleanTypeName(f.type.gqlType)}>]`).join(' ')}`,
|
|
1356
|
+
`${toolName} ${cmd} delete --${pk.name} <${cleanTypeName(pk.gqlType)}>`,
|
|
1357
1357
|
],
|
|
1358
1358
|
examples: [
|
|
1359
1359
|
{
|
|
@@ -93,9 +93,31 @@ export declare function cleanTypeName(name: string): string;
|
|
|
93
93
|
export declare function flattenArgs(args: CleanArgument[], registry?: TypeRegistry): FlattenedArg[];
|
|
94
94
|
/**
|
|
95
95
|
* Build CLI flags string from flattened args.
|
|
96
|
-
* e.g. '--input.email <
|
|
96
|
+
* e.g. '--input.email <String> --input.password <String>'
|
|
97
97
|
*/
|
|
98
98
|
export declare function flattenedArgsToFlags(flatArgs: FlattenedArg[]): string;
|
|
99
|
+
/**
|
|
100
|
+
* Generate a type-aware placeholder for a table field value in code examples.
|
|
101
|
+
* Returns a quoted placeholder string, e.g. `'<UUID>'`, `'<String>'`, `'<Int>'`.
|
|
102
|
+
*/
|
|
103
|
+
export declare function fieldPlaceholder(field: CleanField): string;
|
|
104
|
+
/**
|
|
105
|
+
* Generate a type-aware placeholder for a primary key value in code examples.
|
|
106
|
+
* PrimaryKeyField has `gqlType` directly (not nested under `.type`).
|
|
107
|
+
*/
|
|
108
|
+
export declare function pkPlaceholder(pk: {
|
|
109
|
+
gqlType: string;
|
|
110
|
+
}): string;
|
|
111
|
+
/**
|
|
112
|
+
* Generate a type-aware placeholder for an operation argument value.
|
|
113
|
+
*
|
|
114
|
+
* - Scalar args: `'<String>'`
|
|
115
|
+
* - INPUT_OBJECT with resolvable fields (up to a limit): `{ email: '<String>', password: '<String>' }`
|
|
116
|
+
* - INPUT_OBJECT without resolvable fields: `'<TypeName>'`
|
|
117
|
+
*
|
|
118
|
+
* The result is a ready-to-embed JS expression (quotes included for scalars).
|
|
119
|
+
*/
|
|
120
|
+
export declare function argPlaceholder(arg: CleanArgument, registry?: TypeRegistry): string;
|
|
99
121
|
export declare function gqlTypeToJsonSchemaType(gqlType: string): string;
|
|
100
122
|
export declare function buildSkillFile(skill: SkillDefinition, referenceNames?: string[]): string;
|
|
101
123
|
export declare function buildSkillReference(ref: SkillReferenceDefinition): string;
|
|
@@ -325,10 +325,57 @@ export function flattenArgs(args, registry) {
|
|
|
325
325
|
}
|
|
326
326
|
/**
|
|
327
327
|
* Build CLI flags string from flattened args.
|
|
328
|
-
* e.g. '--input.email <
|
|
328
|
+
* e.g. '--input.email <String> --input.password <String>'
|
|
329
329
|
*/
|
|
330
330
|
export function flattenedArgsToFlags(flatArgs) {
|
|
331
|
-
return flatArgs.map((a) => `--${a.flag}
|
|
331
|
+
return flatArgs.map((a) => `--${a.flag} <${a.type}>`).join(' ');
|
|
332
|
+
}
|
|
333
|
+
// ---------------------------------------------------------------------------
|
|
334
|
+
// Type-aware placeholder helpers for code examples
|
|
335
|
+
// ---------------------------------------------------------------------------
|
|
336
|
+
/**
|
|
337
|
+
* Generate a type-aware placeholder for a table field value in code examples.
|
|
338
|
+
* Returns a quoted placeholder string, e.g. `'<UUID>'`, `'<String>'`, `'<Int>'`.
|
|
339
|
+
*/
|
|
340
|
+
export function fieldPlaceholder(field) {
|
|
341
|
+
return `'<${cleanTypeName(field.type.gqlType)}>'`;
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Generate a type-aware placeholder for a primary key value in code examples.
|
|
345
|
+
* PrimaryKeyField has `gqlType` directly (not nested under `.type`).
|
|
346
|
+
*/
|
|
347
|
+
export function pkPlaceholder(pk) {
|
|
348
|
+
return `'<${cleanTypeName(pk.gqlType)}>'`;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Generate a type-aware placeholder for an operation argument value.
|
|
352
|
+
*
|
|
353
|
+
* - Scalar args: `'<String>'`
|
|
354
|
+
* - INPUT_OBJECT with resolvable fields (up to a limit): `{ email: '<String>', password: '<String>' }`
|
|
355
|
+
* - INPUT_OBJECT without resolvable fields: `'<TypeName>'`
|
|
356
|
+
*
|
|
357
|
+
* The result is a ready-to-embed JS expression (quotes included for scalars).
|
|
358
|
+
*/
|
|
359
|
+
export function argPlaceholder(arg, registry) {
|
|
360
|
+
const { inner } = unwrapNonNull(arg.type);
|
|
361
|
+
if (inner.kind === 'INPUT_OBJECT') {
|
|
362
|
+
const fields = resolveInputFields(inner, registry);
|
|
363
|
+
if (fields && fields.length > 0) {
|
|
364
|
+
const meaningful = fields.filter((f) => f.name !== 'clientMutationId');
|
|
365
|
+
if (meaningful.length > 0 && meaningful.length <= 5) {
|
|
366
|
+
const parts = meaningful.map((f) => {
|
|
367
|
+
const typeName = cleanTypeName(getScalarTypeName(f.type));
|
|
368
|
+
return `${f.name}: '<${typeName}>'`;
|
|
369
|
+
});
|
|
370
|
+
return '{ ' + parts.join(', ') + ' }';
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
if (inner.name) {
|
|
374
|
+
return `'<${cleanTypeName(inner.name)}>'`;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
const typeName = cleanTypeName(getScalarTypeName(arg.type));
|
|
378
|
+
return `'<${typeName}>'`;
|
|
332
379
|
}
|
|
333
380
|
export function gqlTypeToJsonSchemaType(gqlType) {
|
|
334
381
|
switch (gqlType) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { CleanOperation, CleanTable } from '../../types/schema';
|
|
1
|
+
import type { CleanOperation, CleanTable, TypeRegistry } from '../../types/schema';
|
|
2
2
|
import type { GeneratedDocFile, McpTool } from './docs-utils';
|
|
3
|
-
export declare function generateHooksReadme(tables: CleanTable[], customOperations: CleanOperation[]): GeneratedDocFile;
|
|
3
|
+
export declare function generateHooksReadme(tables: CleanTable[], customOperations: CleanOperation[], registry?: TypeRegistry): GeneratedDocFile;
|
|
4
4
|
export declare function generateHooksAgentsDocs(tables: CleanTable[], customOperations: CleanOperation[]): GeneratedDocFile;
|
|
5
5
|
export declare function getHooksMcpTools(tables: CleanTable[], customOperations: CleanOperation[]): McpTool[];
|
|
6
|
-
export declare function generateHooksSkills(tables: CleanTable[], customOperations: CleanOperation[], targetName: string): GeneratedDocFile[];
|
|
6
|
+
export declare function generateHooksSkills(tables: CleanTable[], customOperations: CleanOperation[], targetName: string, registry?: TypeRegistry): GeneratedDocFile[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { toKebabCase } from 'komoji';
|
|
2
|
-
import { buildSkillFile, buildSkillReference, formatArgType, getReadmeHeader, getReadmeFooter, gqlTypeToJsonSchemaType, } from './docs-utils';
|
|
2
|
+
import { buildSkillFile, buildSkillReference, formatArgType, fieldPlaceholder, pkPlaceholder, argPlaceholder, getReadmeHeader, getReadmeFooter, gqlTypeToJsonSchemaType, } from './docs-utils';
|
|
3
3
|
import { getTableNames, getScalarFields, getPrimaryKeyInfo, getListQueryHookName, getSingleQueryHookName, getCreateMutationHookName, getUpdateMutationHookName, getDeleteMutationHookName, hasValidPrimaryKey, ucFirst, lcFirst, } from './utils';
|
|
4
4
|
function getCustomHookName(op) {
|
|
5
5
|
if (op.kind === 'query') {
|
|
@@ -7,7 +7,7 @@ function getCustomHookName(op) {
|
|
|
7
7
|
}
|
|
8
8
|
return `use${ucFirst(op.name)}Mutation`;
|
|
9
9
|
}
|
|
10
|
-
export function generateHooksReadme(tables, customOperations) {
|
|
10
|
+
export function generateHooksReadme(tables, customOperations, registry) {
|
|
11
11
|
const lines = [];
|
|
12
12
|
lines.push(...getReadmeHeader('React Query Hooks'));
|
|
13
13
|
lines.push('## Setup');
|
|
@@ -70,7 +70,7 @@ export function generateHooksReadme(tables, customOperations) {
|
|
|
70
70
|
if (hasValidPrimaryKey(table)) {
|
|
71
71
|
lines.push(`// Get one ${singularName}`);
|
|
72
72
|
lines.push(`const { data: item } = ${getSingleQueryHookName(table)}({`);
|
|
73
|
-
lines.push(` ${pk.name}:
|
|
73
|
+
lines.push(` ${pk.name}: ${pkPlaceholder(pk)},`);
|
|
74
74
|
lines.push(` selection: { fields: { ${scalarFields.map((f) => `${f.name}: true`).join(', ')} } },`);
|
|
75
75
|
lines.push('});');
|
|
76
76
|
lines.push('');
|
|
@@ -79,7 +79,7 @@ export function generateHooksReadme(tables, customOperations) {
|
|
|
79
79
|
lines.push(`const { mutate: create } = ${getCreateMutationHookName(table)}({`);
|
|
80
80
|
lines.push(` selection: { fields: { ${pk.name}: true } },`);
|
|
81
81
|
lines.push('});');
|
|
82
|
-
lines.push(`create({ ${scalarFields.filter((f) => f.name !== pk.name && f.name !== 'nodeId' && f.name !== 'createdAt' && f.name !== 'updatedAt').map((f) => `${f.name}:
|
|
82
|
+
lines.push(`create({ ${scalarFields.filter((f) => f.name !== pk.name && f.name !== 'nodeId' && f.name !== 'createdAt' && f.name !== 'updatedAt').map((f) => `${f.name}: ${fieldPlaceholder(f)}`).join(', ')} });`);
|
|
83
83
|
lines.push('```');
|
|
84
84
|
lines.push('');
|
|
85
85
|
}
|
|
@@ -273,7 +273,7 @@ export function getHooksMcpTools(tables, customOperations) {
|
|
|
273
273
|
}
|
|
274
274
|
return tools;
|
|
275
275
|
}
|
|
276
|
-
export function generateHooksSkills(tables, customOperations, targetName) {
|
|
276
|
+
export function generateHooksSkills(tables, customOperations, targetName, registry) {
|
|
277
277
|
const files = [];
|
|
278
278
|
const skillName = `hooks-${targetName}`;
|
|
279
279
|
const referenceNames = [];
|
|
@@ -297,7 +297,7 @@ export function generateHooksSkills(tables, customOperations, targetName) {
|
|
|
297
297
|
`${getListQueryHookName(table)}({ selection: { fields: { ${selectFields} } } })`,
|
|
298
298
|
...(hasValidPrimaryKey(table)
|
|
299
299
|
? [
|
|
300
|
-
`${getSingleQueryHookName(table)}({ ${pk.name}:
|
|
300
|
+
`${getSingleQueryHookName(table)}({ ${pk.name}: ${pkPlaceholder(pk)}, selection: { fields: { ${selectFields} } } })`,
|
|
301
301
|
]
|
|
302
302
|
: []),
|
|
303
303
|
`${getCreateMutationHookName(table)}({ selection: { fields: { ${pk.name}: true } } })`,
|
|
@@ -323,7 +323,7 @@ export function generateHooksSkills(tables, customOperations, targetName) {
|
|
|
323
323
|
`const { mutate } = ${getCreateMutationHookName(table)}({`,
|
|
324
324
|
` selection: { fields: { ${pk.name}: true } },`,
|
|
325
325
|
'});',
|
|
326
|
-
`mutate({ ${scalarFields.filter((f) => f.name !== pk.name && f.name !== 'nodeId' && f.name !== 'createdAt' && f.name !== 'updatedAt').map((f) => `${f.name}:
|
|
326
|
+
`mutate({ ${scalarFields.filter((f) => f.name !== pk.name && f.name !== 'nodeId' && f.name !== 'createdAt' && f.name !== 'updatedAt').map((f) => `${f.name}: ${fieldPlaceholder(f)}`).join(', ')} });`,
|
|
327
327
|
],
|
|
328
328
|
},
|
|
329
329
|
],
|
|
@@ -334,7 +334,7 @@ export function generateHooksSkills(tables, customOperations, targetName) {
|
|
|
334
334
|
for (const op of customOperations) {
|
|
335
335
|
const hookName = getCustomHookName(op);
|
|
336
336
|
const callArgs = op.args.length > 0
|
|
337
|
-
? `{ ${op.args.map((a) => `${a.name}:
|
|
337
|
+
? `{ ${op.args.map((a) => `${a.name}: ${argPlaceholder(a, registry)}`).join(', ')} }`
|
|
338
338
|
: '';
|
|
339
339
|
const refName = toKebabCase(op.name);
|
|
340
340
|
referenceNames.push(refName);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { CleanOperation, CleanTable } from '../../../types/schema';
|
|
1
|
+
import type { CleanOperation, CleanTable, TypeRegistry } from '../../../types/schema';
|
|
2
2
|
import type { GeneratedDocFile, McpTool } from '../docs-utils';
|
|
3
|
-
export declare function generateOrmReadme(tables: CleanTable[], customOperations: CleanOperation[]): GeneratedDocFile;
|
|
3
|
+
export declare function generateOrmReadme(tables: CleanTable[], customOperations: CleanOperation[], registry?: TypeRegistry): GeneratedDocFile;
|
|
4
4
|
export declare function generateOrmAgentsDocs(tables: CleanTable[], customOperations: CleanOperation[]): GeneratedDocFile;
|
|
5
5
|
export declare function getOrmMcpTools(tables: CleanTable[], customOperations: CleanOperation[]): McpTool[];
|
|
6
|
-
export declare function generateOrmSkills(tables: CleanTable[], customOperations: CleanOperation[], targetName: string): GeneratedDocFile[];
|
|
6
|
+
export declare function generateOrmSkills(tables: CleanTable[], customOperations: CleanOperation[], targetName: string, registry?: TypeRegistry): GeneratedDocFile[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { toKebabCase } from 'komoji';
|
|
2
|
-
import { buildSkillFile, buildSkillReference, formatArgType, getEditableFields, categorizeSpecialFields, buildSpecialFieldsMarkdown, getReadmeHeader, getReadmeFooter, gqlTypeToJsonSchemaType, } from '../docs-utils';
|
|
2
|
+
import { buildSkillFile, buildSkillReference, formatArgType, fieldPlaceholder, pkPlaceholder, argPlaceholder, getEditableFields, categorizeSpecialFields, buildSpecialFieldsMarkdown, getReadmeHeader, getReadmeFooter, gqlTypeToJsonSchemaType, } from '../docs-utils';
|
|
3
3
|
import { getScalarFields, getTableNames, getPrimaryKeyInfo, lcFirst, } from '../utils';
|
|
4
|
-
export function generateOrmReadme(tables, customOperations) {
|
|
4
|
+
export function generateOrmReadme(tables, customOperations, registry) {
|
|
5
5
|
const lines = [];
|
|
6
6
|
lines.push(...getReadmeHeader('ORM Client'));
|
|
7
7
|
lines.push('## Setup');
|
|
@@ -52,16 +52,16 @@ export function generateOrmReadme(tables, customOperations) {
|
|
|
52
52
|
lines.push(`const items = await db.${singularName}.findMany({ select: { ${scalarFields.map((f) => `${f.name}: true`).join(', ')} } }).execute();`);
|
|
53
53
|
lines.push('');
|
|
54
54
|
lines.push(`// Get one by ${pk.name}`);
|
|
55
|
-
lines.push(`const item = await db.${singularName}.findOne({ ${pk.name}:
|
|
55
|
+
lines.push(`const item = await db.${singularName}.findOne({ ${pk.name}: ${pkPlaceholder(pk)}, select: { ${scalarFields.map((f) => `${f.name}: true`).join(', ')} } }).execute();`);
|
|
56
56
|
lines.push('');
|
|
57
57
|
lines.push(`// Create`);
|
|
58
|
-
lines.push(`const created = await db.${singularName}.create({ data: { ${editableFields.map((f) => `${f.name}:
|
|
58
|
+
lines.push(`const created = await db.${singularName}.create({ data: { ${editableFields.map((f) => `${f.name}: ${fieldPlaceholder(f)}`).join(', ')} }, select: { ${pk.name}: true } }).execute();`);
|
|
59
59
|
lines.push('');
|
|
60
60
|
lines.push(`// Update`);
|
|
61
|
-
lines.push(`const updated = await db.${singularName}.update({ where: { ${pk.name}:
|
|
61
|
+
lines.push(`const updated = await db.${singularName}.update({ where: { ${pk.name}: ${pkPlaceholder(pk)} }, data: { ${editableFields[0]?.name || 'field'}: ${editableFields[0] ? fieldPlaceholder(editableFields[0]) : "'<String>'"} }, select: { ${pk.name}: true } }).execute();`);
|
|
62
62
|
lines.push('');
|
|
63
63
|
lines.push(`// Delete`);
|
|
64
|
-
lines.push(`const deleted = await db.${singularName}.delete({ where: { ${pk.name}:
|
|
64
|
+
lines.push(`const deleted = await db.${singularName}.delete({ where: { ${pk.name}: ${pkPlaceholder(pk)} } }).execute();`);
|
|
65
65
|
lines.push('```');
|
|
66
66
|
lines.push('');
|
|
67
67
|
const ormSpecialGroups = categorizeSpecialFields(table);
|
|
@@ -88,7 +88,7 @@ export function generateOrmReadme(tables, customOperations) {
|
|
|
88
88
|
}
|
|
89
89
|
lines.push('');
|
|
90
90
|
lines.push('```typescript');
|
|
91
|
-
lines.push(`const result = await db.${accessor}.${op.name}({ ${op.args.map((a) => `${a.name}:
|
|
91
|
+
lines.push(`const result = await db.${accessor}.${op.name}({ ${op.args.map((a) => `${a.name}: ${argPlaceholder(a, registry)}`).join(', ')} }).execute();`);
|
|
92
92
|
lines.push('```');
|
|
93
93
|
}
|
|
94
94
|
else {
|
|
@@ -279,7 +279,7 @@ export function getOrmMcpTools(tables, customOperations) {
|
|
|
279
279
|
}
|
|
280
280
|
return tools;
|
|
281
281
|
}
|
|
282
|
-
export function generateOrmSkills(tables, customOperations, targetName) {
|
|
282
|
+
export function generateOrmSkills(tables, customOperations, targetName, registry) {
|
|
283
283
|
const files = [];
|
|
284
284
|
const skillName = `orm-${targetName}`;
|
|
285
285
|
const referenceNames = [];
|
|
@@ -305,10 +305,10 @@ export function generateOrmSkills(tables, customOperations, targetName) {
|
|
|
305
305
|
language: 'typescript',
|
|
306
306
|
usage: [
|
|
307
307
|
`db.${modelName}.findMany({ select: { id: true } }).execute()`,
|
|
308
|
-
`db.${modelName}.findOne({ ${pk.name}:
|
|
309
|
-
`db.${modelName}.create({ data: { ${editableFields.map((f) => `${f.name}:
|
|
310
|
-
`db.${modelName}.update({ where: { ${pk.name}:
|
|
311
|
-
`db.${modelName}.delete({ where: { ${pk.name}:
|
|
308
|
+
`db.${modelName}.findOne({ ${pk.name}: ${pkPlaceholder(pk)}, select: { id: true } }).execute()`,
|
|
309
|
+
`db.${modelName}.create({ data: { ${editableFields.map((f) => `${f.name}: ${fieldPlaceholder(f)}`).join(', ')} }, select: { id: true } }).execute()`,
|
|
310
|
+
`db.${modelName}.update({ where: { ${pk.name}: ${pkPlaceholder(pk)} }, data: { ${editableFields[0]?.name || 'field'}: ${editableFields[0] ? fieldPlaceholder(editableFields[0]) : "'<String>'"} }, select: { id: true } }).execute()`,
|
|
311
|
+
`db.${modelName}.delete({ where: { ${pk.name}: ${pkPlaceholder(pk)} } }).execute()`,
|
|
312
312
|
],
|
|
313
313
|
examples: [
|
|
314
314
|
{
|
|
@@ -323,7 +323,7 @@ export function generateOrmSkills(tables, customOperations, targetName) {
|
|
|
323
323
|
description: `Create a ${singularName}`,
|
|
324
324
|
code: [
|
|
325
325
|
`const item = await db.${modelName}.create({`,
|
|
326
|
-
` data: { ${editableFields.map((f) => `${f.name}:
|
|
326
|
+
` data: { ${editableFields.map((f) => `${f.name}: ${fieldPlaceholder(f)}`).join(', ')} },`,
|
|
327
327
|
` select: { ${pk.name}: true }`,
|
|
328
328
|
'}).execute();',
|
|
329
329
|
],
|
|
@@ -336,7 +336,7 @@ export function generateOrmSkills(tables, customOperations, targetName) {
|
|
|
336
336
|
for (const op of customOperations) {
|
|
337
337
|
const accessor = op.kind === 'query' ? 'query' : 'mutation';
|
|
338
338
|
const callArgs = op.args.length > 0
|
|
339
|
-
? `{ ${op.args.map((a) => `${a.name}:
|
|
339
|
+
? `{ ${op.args.map((a) => `${a.name}: ${argPlaceholder(a, registry)}`).join(', ')} }`
|
|
340
340
|
: '';
|
|
341
341
|
const refName = toKebabCase(op.name);
|
|
342
342
|
referenceNames.push(refName);
|
|
@@ -370,10 +370,10 @@ export function generateOrmSkills(tables, customOperations, targetName) {
|
|
|
370
370
|
'',
|
|
371
371
|
`// Available models: ${tableNames.slice(0, 8).join(', ')}${tableNames.length > 8 ? ', ...' : ''}`,
|
|
372
372
|
`db.<model>.findMany({ select: { id: true } }).execute()`,
|
|
373
|
-
`db.<model>.findOne({ id: '<
|
|
373
|
+
`db.<model>.findOne({ id: '<UUID>', select: { id: true } }).execute()`,
|
|
374
374
|
`db.<model>.create({ data: { ... }, select: { id: true } }).execute()`,
|
|
375
|
-
`db.<model>.update({ where: { id: '<
|
|
376
|
-
`db.<model>.delete({ where: { id: '<
|
|
375
|
+
`db.<model>.update({ where: { id: '<UUID>' }, data: { ... }, select: { id: true } }).execute()`,
|
|
376
|
+
`db.<model>.delete({ where: { id: '<UUID>' } }).execute()`,
|
|
377
377
|
],
|
|
378
378
|
examples: [
|
|
379
379
|
{
|
|
@@ -101,6 +101,55 @@ function generateEnumTypes(typeRegistry, tableTypeNames, comments = true) {
|
|
|
101
101
|
}
|
|
102
102
|
return { statements, generatedTypes };
|
|
103
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Generate a discriminated union type for a @oneOf INPUT_OBJECT.
|
|
106
|
+
*
|
|
107
|
+
* For a @oneOf input like:
|
|
108
|
+
* input BlueprintNodeInput @oneOf {
|
|
109
|
+
* shorthand: String
|
|
110
|
+
* DataId: DataIdParams
|
|
111
|
+
* DataTimestamps: DataTimestampsParams
|
|
112
|
+
* }
|
|
113
|
+
*
|
|
114
|
+
* Generates:
|
|
115
|
+
* type BlueprintNodeInput =
|
|
116
|
+
* | { shorthand: string }
|
|
117
|
+
* | { DataId: DataIdParams }
|
|
118
|
+
* | { DataTimestamps: DataTimestampsParams }
|
|
119
|
+
*/
|
|
120
|
+
function generateOneOfUnionType(typeName, typeInfo, typeRegistry, tableTypeNames, generatedTypes, typesToGenerate, comments) {
|
|
121
|
+
const unionMembers = [];
|
|
122
|
+
if (typeInfo.inputFields && typeInfo.inputFields.length > 0) {
|
|
123
|
+
for (const field of typeInfo.inputFields) {
|
|
124
|
+
const tsType = typeRefToTs(field.type);
|
|
125
|
+
// Each @oneOf field becomes a single-property object type in the union
|
|
126
|
+
const prop = t.tsPropertySignature(t.identifier(field.name), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(tsType))));
|
|
127
|
+
prop.optional = false; // In @oneOf, the chosen field is required
|
|
128
|
+
const memberType = t.tsTypeLiteral([prop]);
|
|
129
|
+
unionMembers.push(memberType);
|
|
130
|
+
// Track nested types for generation
|
|
131
|
+
const baseType = getTypeBaseName(field.type);
|
|
132
|
+
if (baseType &&
|
|
133
|
+
!generatedTypes.has(baseType) &&
|
|
134
|
+
!shouldSkipType(baseType, tableTypeNames)) {
|
|
135
|
+
const nestedType = typeRegistry.get(baseType);
|
|
136
|
+
if (nestedType?.kind === 'INPUT_OBJECT') {
|
|
137
|
+
typesToGenerate.add(baseType);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const unionType = unionMembers.length > 0
|
|
143
|
+
? t.tsUnionType(unionMembers)
|
|
144
|
+
: t.tsNeverKeyword();
|
|
145
|
+
const typeAlias = t.tsTypeAliasDeclaration(t.identifier(typeName), null, unionType);
|
|
146
|
+
const exportDecl = t.exportNamedDeclaration(typeAlias);
|
|
147
|
+
const inputDescription = stripSmartComments(typeInfo.description, comments);
|
|
148
|
+
if (inputDescription) {
|
|
149
|
+
addJSDocComment(exportDecl, inputDescription.split('\n'));
|
|
150
|
+
}
|
|
151
|
+
return exportDecl;
|
|
152
|
+
}
|
|
104
153
|
function generateInputObjectTypes(typeRegistry, tableTypeNames, alreadyGenerated, comments = true) {
|
|
105
154
|
const statements = [];
|
|
106
155
|
const generatedTypes = new Set(alreadyGenerated);
|
|
@@ -126,6 +175,11 @@ function generateInputObjectTypes(typeRegistry, tableTypeNames, alreadyGenerated
|
|
|
126
175
|
if (!typeInfo || typeInfo.kind !== 'INPUT_OBJECT')
|
|
127
176
|
continue;
|
|
128
177
|
generatedTypes.add(typeName);
|
|
178
|
+
// @oneOf types become discriminated unions instead of interfaces
|
|
179
|
+
if (typeInfo.isOneOf) {
|
|
180
|
+
statements.push(generateOneOfUnionType(typeName, typeInfo, typeRegistry, tableTypeNames, generatedTypes, typesToGenerate, comments));
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
129
183
|
const properties = [];
|
|
130
184
|
if (typeInfo.inputFields && typeInfo.inputFields.length > 0) {
|
|
131
185
|
for (const field of typeInfo.inputFields) {
|
package/esm/core/generate.js
CHANGED
|
@@ -237,7 +237,7 @@ export async function generate(options = {}, internalOptions) {
|
|
|
237
237
|
const skillsToWrite = [];
|
|
238
238
|
if (runOrm) {
|
|
239
239
|
if (docsConfig.readme) {
|
|
240
|
-
const readme = generateOrmReadme(tables, allCustomOps);
|
|
240
|
+
const readme = generateOrmReadme(tables, allCustomOps, customOperations.typeRegistry);
|
|
241
241
|
filesToWrite.push({ path: path.posix.join('orm', readme.fileName), content: readme.content });
|
|
242
242
|
}
|
|
243
243
|
if (docsConfig.agents) {
|
|
@@ -248,14 +248,14 @@ export async function generate(options = {}, internalOptions) {
|
|
|
248
248
|
allMcpTools.push(...getOrmMcpTools(tables, allCustomOps));
|
|
249
249
|
}
|
|
250
250
|
if (docsConfig.skills) {
|
|
251
|
-
for (const skill of generateOrmSkills(tables, allCustomOps, targetName)) {
|
|
251
|
+
for (const skill of generateOrmSkills(tables, allCustomOps, targetName, customOperations.typeRegistry)) {
|
|
252
252
|
skillsToWrite.push({ path: skill.fileName, content: skill.content });
|
|
253
253
|
}
|
|
254
254
|
}
|
|
255
255
|
}
|
|
256
256
|
if (runReactQuery) {
|
|
257
257
|
if (docsConfig.readme) {
|
|
258
|
-
const readme = generateHooksReadme(tables, allCustomOps);
|
|
258
|
+
const readme = generateHooksReadme(tables, allCustomOps, customOperations.typeRegistry);
|
|
259
259
|
filesToWrite.push({ path: path.posix.join('hooks', readme.fileName), content: readme.content });
|
|
260
260
|
}
|
|
261
261
|
if (docsConfig.agents) {
|
|
@@ -266,7 +266,7 @@ export async function generate(options = {}, internalOptions) {
|
|
|
266
266
|
allMcpTools.push(...getHooksMcpTools(tables, allCustomOps));
|
|
267
267
|
}
|
|
268
268
|
if (docsConfig.skills) {
|
|
269
|
-
for (const skill of generateHooksSkills(tables, allCustomOps, targetName)) {
|
|
269
|
+
for (const skill of generateHooksSkills(tables, allCustomOps, targetName, customOperations.typeRegistry)) {
|
|
270
270
|
skillsToWrite.push({ path: skill.fileName, content: skill.content });
|
|
271
271
|
}
|
|
272
272
|
}
|
package/esm/types/schema.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@constructive-io/graphql-codegen",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.17.0",
|
|
4
4
|
"description": "GraphQL SDK generator for Constructive databases with React Query hooks",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"graphql",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"@0no-co/graphql.web": "^1.1.2",
|
|
57
57
|
"@babel/generator": "^7.29.1",
|
|
58
58
|
"@babel/types": "^7.29.0",
|
|
59
|
-
"@constructive-io/graphql-query": "^3.
|
|
59
|
+
"@constructive-io/graphql-query": "^3.7.0",
|
|
60
60
|
"@constructive-io/graphql-types": "^3.3.4",
|
|
61
61
|
"@inquirerer/utils": "^3.3.4",
|
|
62
62
|
"@pgpmjs/core": "^6.8.0",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"deepmerge": "^4.3.1",
|
|
65
65
|
"find-and-require-package-json": "^0.9.1",
|
|
66
66
|
"gql-ast": "^3.3.3",
|
|
67
|
-
"graphile-schema": "^1.
|
|
67
|
+
"graphile-schema": "^1.7.0",
|
|
68
68
|
"graphql": "16.13.0",
|
|
69
69
|
"inflekt": "^0.3.3",
|
|
70
70
|
"inquirerer": "^4.7.0",
|
|
@@ -101,5 +101,5 @@
|
|
|
101
101
|
"tsx": "^4.21.0",
|
|
102
102
|
"typescript": "^5.9.3"
|
|
103
103
|
},
|
|
104
|
-
"gitHead": "
|
|
104
|
+
"gitHead": "d7ad4d8a95a9ab73c9eee919e0cdfcc2334845af"
|
|
105
105
|
}
|
package/types/schema.d.ts
CHANGED