@constructive-io/graphql-codegen 4.9.0 → 4.12.2
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/arg-mapper.d.ts +1 -1
- package/core/codegen/cli/arg-mapper.js +15 -11
- package/core/codegen/cli/custom-command-generator.js +4 -3
- package/core/codegen/cli/docs-generator.d.ts +6 -5
- package/core/codegen/cli/docs-generator.js +167 -64
- package/core/codegen/cli/table-command-generator.d.ts +15 -0
- package/core/codegen/cli/table-command-generator.js +20 -1
- package/core/codegen/docs-utils.d.ts +26 -1
- package/core/codegen/docs-utils.js +105 -0
- package/core/codegen/orm/input-types-generator.js +112 -14
- package/core/codegen/orm/model-generator.js +8 -0
- package/core/codegen/orm/select-types.d.ts +4 -2
- package/core/codegen/scalars.js +8 -0
- package/core/codegen/templates/cli-entry.ts +2 -2
- package/core/codegen/templates/cli-utils.ts +28 -0
- package/core/codegen/templates/query-builder.ts +28 -5
- package/core/codegen/templates/select-types.ts +4 -2
- package/core/generate.js +14 -4
- package/esm/core/codegen/cli/arg-mapper.d.ts +1 -1
- package/esm/core/codegen/cli/arg-mapper.js +15 -11
- package/esm/core/codegen/cli/custom-command-generator.js +4 -3
- package/esm/core/codegen/cli/docs-generator.d.ts +6 -5
- package/esm/core/codegen/cli/docs-generator.js +168 -65
- package/esm/core/codegen/cli/table-command-generator.d.ts +15 -0
- package/esm/core/codegen/cli/table-command-generator.js +20 -3
- package/esm/core/codegen/docs-utils.d.ts +26 -1
- package/esm/core/codegen/docs-utils.js +102 -0
- package/esm/core/codegen/orm/input-types-generator.js +112 -14
- package/esm/core/codegen/orm/model-generator.js +8 -0
- package/esm/core/codegen/orm/select-types.d.ts +4 -2
- package/esm/core/codegen/scalars.js +8 -0
- package/esm/core/generate.js +14 -4
- package/package.json +11 -11
package/core/generate.js
CHANGED
|
@@ -316,18 +316,18 @@ async function generate(options = {}, internalOptions) {
|
|
|
316
316
|
? config.cli.toolName
|
|
317
317
|
: 'app';
|
|
318
318
|
if (docsConfig.readme) {
|
|
319
|
-
const readme = (0, docs_generator_1.generateReadme)(tables, allCustomOps, toolName);
|
|
319
|
+
const readme = (0, docs_generator_1.generateReadme)(tables, allCustomOps, toolName, customOperations.typeRegistry);
|
|
320
320
|
filesToWrite.push({ path: node_path_1.default.posix.join('cli', readme.fileName), content: readme.content });
|
|
321
321
|
}
|
|
322
322
|
if (docsConfig.agents) {
|
|
323
|
-
const agents = (0, docs_generator_1.generateAgentsDocs)(tables, allCustomOps, toolName);
|
|
323
|
+
const agents = (0, docs_generator_1.generateAgentsDocs)(tables, allCustomOps, toolName, customOperations.typeRegistry);
|
|
324
324
|
filesToWrite.push({ path: node_path_1.default.posix.join('cli', agents.fileName), content: agents.content });
|
|
325
325
|
}
|
|
326
326
|
if (docsConfig.mcp) {
|
|
327
|
-
allMcpTools.push(...(0, docs_generator_1.getCliMcpTools)(tables, allCustomOps, toolName));
|
|
327
|
+
allMcpTools.push(...(0, docs_generator_1.getCliMcpTools)(tables, allCustomOps, toolName, customOperations.typeRegistry));
|
|
328
328
|
}
|
|
329
329
|
if (docsConfig.skills) {
|
|
330
|
-
for (const skill of (0, docs_generator_1.generateSkills)(tables, allCustomOps, toolName, targetName)) {
|
|
330
|
+
for (const skill of (0, docs_generator_1.generateSkills)(tables, allCustomOps, toolName, targetName, customOperations.typeRegistry)) {
|
|
331
331
|
skillsToWrite.push({ path: skill.fileName, content: skill.content });
|
|
332
332
|
}
|
|
333
333
|
}
|
|
@@ -616,9 +616,19 @@ async function generateMulti(options) {
|
|
|
616
616
|
const docsConfig = (0, docs_utils_1.resolveDocsConfig)(firstTargetDocsConfig);
|
|
617
617
|
const { resolveBuiltinNames } = await Promise.resolve().then(() => __importStar(require('./codegen/cli')));
|
|
618
618
|
const builtinNames = resolveBuiltinNames(cliTargets.map((t) => t.name), cliConfig.builtinNames);
|
|
619
|
+
// Merge all target type registries into a combined registry for docs generation
|
|
620
|
+
const combinedRegistry = new Map();
|
|
621
|
+
for (const t of cliTargets) {
|
|
622
|
+
if (t.typeRegistry) {
|
|
623
|
+
for (const [key, value] of t.typeRegistry) {
|
|
624
|
+
combinedRegistry.set(key, value);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
619
628
|
const docsInput = {
|
|
620
629
|
toolName,
|
|
621
630
|
builtinNames,
|
|
631
|
+
registry: combinedRegistry.size > 0 ? combinedRegistry : undefined,
|
|
622
632
|
targets: cliTargets.map((t) => ({
|
|
623
633
|
name: t.name,
|
|
624
634
|
endpoint: t.endpoint,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import * as t from '@babel/types';
|
|
2
2
|
import type { CleanArgument } from '../../../types/schema';
|
|
3
|
-
export declare function buildQuestionObject(arg: CleanArgument): t.ObjectExpression;
|
|
3
|
+
export declare function buildQuestionObject(arg: CleanArgument, namePrefix?: string): t.ObjectExpression;
|
|
4
4
|
export declare function buildQuestionsArray(args: CleanArgument[]): t.ArrayExpression;
|
|
@@ -11,35 +11,37 @@ function resolveBaseType(typeRef) {
|
|
|
11
11
|
}
|
|
12
12
|
return typeRef;
|
|
13
13
|
}
|
|
14
|
-
export function buildQuestionObject(arg) {
|
|
14
|
+
export function buildQuestionObject(arg, namePrefix) {
|
|
15
15
|
const { inner, required } = unwrapNonNull(arg.type);
|
|
16
16
|
const base = resolveBaseType(arg.type);
|
|
17
17
|
const props = [];
|
|
18
|
+
const questionName = namePrefix ? `${namePrefix}.${arg.name}` : arg.name;
|
|
18
19
|
if (base.kind === 'ENUM' && base.enumValues && base.enumValues.length > 0) {
|
|
19
20
|
props.push(t.objectProperty(t.identifier('type'), t.stringLiteral('autocomplete')));
|
|
20
|
-
props.push(t.objectProperty(t.identifier('name'), t.stringLiteral(
|
|
21
|
-
props.push(t.objectProperty(t.identifier('message'), t.stringLiteral(arg.description ||
|
|
21
|
+
props.push(t.objectProperty(t.identifier('name'), t.stringLiteral(questionName)));
|
|
22
|
+
props.push(t.objectProperty(t.identifier('message'), t.stringLiteral(arg.description || questionName)));
|
|
22
23
|
props.push(t.objectProperty(t.identifier('options'), t.arrayExpression(base.enumValues.map((v) => t.stringLiteral(v)))));
|
|
23
24
|
}
|
|
24
25
|
else if (base.kind === 'SCALAR' && base.name === 'Boolean') {
|
|
25
26
|
props.push(t.objectProperty(t.identifier('type'), t.stringLiteral('confirm')));
|
|
26
|
-
props.push(t.objectProperty(t.identifier('name'), t.stringLiteral(
|
|
27
|
-
props.push(t.objectProperty(t.identifier('message'), t.stringLiteral(arg.description ||
|
|
27
|
+
props.push(t.objectProperty(t.identifier('name'), t.stringLiteral(questionName)));
|
|
28
|
+
props.push(t.objectProperty(t.identifier('message'), t.stringLiteral(arg.description || questionName)));
|
|
28
29
|
props.push(t.objectProperty(t.identifier('default'), t.booleanLiteral(false)));
|
|
29
30
|
}
|
|
30
31
|
else if (base.kind === 'SCALAR' &&
|
|
31
32
|
(base.name === 'Int' || base.name === 'Float')) {
|
|
32
33
|
props.push(t.objectProperty(t.identifier('type'), t.stringLiteral('text')));
|
|
33
|
-
props.push(t.objectProperty(t.identifier('name'), t.stringLiteral(
|
|
34
|
-
props.push(t.objectProperty(t.identifier('message'), t.stringLiteral(arg.description || `${
|
|
34
|
+
props.push(t.objectProperty(t.identifier('name'), t.stringLiteral(questionName)));
|
|
35
|
+
props.push(t.objectProperty(t.identifier('message'), t.stringLiteral(arg.description || `${questionName} (number)`)));
|
|
35
36
|
}
|
|
36
37
|
else if (inner.kind === 'INPUT_OBJECT' && inner.inputFields) {
|
|
38
|
+
// INPUT_OBJECT fields are flattened in buildQuestionsArray with dot-notation
|
|
37
39
|
return buildInputObjectQuestion(arg.name, inner, required);
|
|
38
40
|
}
|
|
39
41
|
else {
|
|
40
42
|
props.push(t.objectProperty(t.identifier('type'), t.stringLiteral('text')));
|
|
41
|
-
props.push(t.objectProperty(t.identifier('name'), t.stringLiteral(
|
|
42
|
-
props.push(t.objectProperty(t.identifier('message'), t.stringLiteral(arg.description ||
|
|
43
|
+
props.push(t.objectProperty(t.identifier('name'), t.stringLiteral(questionName)));
|
|
44
|
+
props.push(t.objectProperty(t.identifier('message'), t.stringLiteral(arg.description || questionName)));
|
|
43
45
|
}
|
|
44
46
|
if (required) {
|
|
45
47
|
props.push(t.objectProperty(t.identifier('required'), t.booleanLiteral(true)));
|
|
@@ -63,13 +65,15 @@ export function buildQuestionsArray(args) {
|
|
|
63
65
|
const base = resolveBaseType(arg.type);
|
|
64
66
|
const { inner } = unwrapNonNull(arg.type);
|
|
65
67
|
if (inner.kind === 'INPUT_OBJECT' && inner.inputFields) {
|
|
68
|
+
// Flatten INPUT_OBJECT fields with dot-notation: e.g. input.email, input.password
|
|
66
69
|
for (const field of inner.inputFields) {
|
|
67
|
-
questions.push(buildQuestionObject(field));
|
|
70
|
+
questions.push(buildQuestionObject(field, arg.name));
|
|
68
71
|
}
|
|
69
72
|
}
|
|
70
73
|
else if (base.kind === 'INPUT_OBJECT' && base.inputFields) {
|
|
74
|
+
// Same for NON_NULL-wrapped INPUT_OBJECT
|
|
71
75
|
for (const field of base.inputFields) {
|
|
72
|
-
questions.push(buildQuestionObject(field));
|
|
76
|
+
questions.push(buildQuestionObject(field, arg.name));
|
|
73
77
|
}
|
|
74
78
|
}
|
|
75
79
|
else {
|
|
@@ -119,7 +119,7 @@ export function generateCustomCommand(op, options) {
|
|
|
119
119
|
// Build the list of utils imports needed
|
|
120
120
|
const utilsImports = [];
|
|
121
121
|
if (hasInputObjectArg) {
|
|
122
|
-
utilsImports.push('
|
|
122
|
+
utilsImports.push('unflattenDotNotation');
|
|
123
123
|
}
|
|
124
124
|
if (isObjectReturn) {
|
|
125
125
|
utilsImports.push('buildSelectFromPaths');
|
|
@@ -168,10 +168,11 @@ export function generateCustomCommand(op, options) {
|
|
|
168
168
|
t.variableDeclarator(t.identifier('client'), t.callExpression(t.identifier('getClient'), getClientArgs)),
|
|
169
169
|
]));
|
|
170
170
|
// For mutations with INPUT_OBJECT args (like `input: SignUpInput`),
|
|
171
|
-
//
|
|
171
|
+
// reconstruct nested objects from dot-notation CLI answers.
|
|
172
|
+
// e.g. { 'input.email': 'foo', 'input.password': 'bar' } → { input: { email: 'foo', password: 'bar' } }
|
|
172
173
|
if (hasInputObjectArg && op.args.length > 0) {
|
|
173
174
|
bodyStatements.push(t.variableDeclaration('const', [
|
|
174
|
-
t.variableDeclarator(t.identifier('parsedAnswers'), t.callExpression(t.identifier('
|
|
175
|
+
t.variableDeclarator(t.identifier('parsedAnswers'), t.callExpression(t.identifier('unflattenDotNotation'), [
|
|
175
176
|
t.identifier('answers'),
|
|
176
177
|
])),
|
|
177
178
|
]));
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import type { CleanTable, CleanOperation } from '../../../types/schema';
|
|
1
|
+
import type { CleanTable, CleanOperation, TypeRegistry } from '../../../types/schema';
|
|
2
2
|
import type { GeneratedDocFile, McpTool } from '../docs-utils';
|
|
3
3
|
export { resolveDocsConfig } from '../docs-utils';
|
|
4
4
|
export type { GeneratedDocFile, McpTool } from '../docs-utils';
|
|
5
|
-
export declare function generateReadme(tables: CleanTable[], customOperations: CleanOperation[], toolName: string): GeneratedDocFile;
|
|
6
|
-
export declare function generateAgentsDocs(tables: CleanTable[], customOperations: CleanOperation[], toolName: string): GeneratedDocFile;
|
|
7
|
-
export declare function getCliMcpTools(tables: CleanTable[], customOperations: CleanOperation[], toolName: string): McpTool[];
|
|
8
|
-
export declare function generateSkills(tables: CleanTable[], customOperations: CleanOperation[], toolName: string, targetName: string): GeneratedDocFile[];
|
|
5
|
+
export declare function generateReadme(tables: CleanTable[], customOperations: CleanOperation[], toolName: string, registry?: TypeRegistry): GeneratedDocFile;
|
|
6
|
+
export declare function generateAgentsDocs(tables: CleanTable[], customOperations: CleanOperation[], toolName: string, registry?: TypeRegistry): GeneratedDocFile;
|
|
7
|
+
export declare function getCliMcpTools(tables: CleanTable[], customOperations: CleanOperation[], toolName: string, registry?: TypeRegistry): McpTool[];
|
|
8
|
+
export declare function generateSkills(tables: CleanTable[], customOperations: CleanOperation[], toolName: string, targetName: string, registry?: TypeRegistry): GeneratedDocFile[];
|
|
9
9
|
export interface MultiTargetDocsInput {
|
|
10
10
|
toolName: string;
|
|
11
11
|
builtinNames: {
|
|
12
12
|
auth: string;
|
|
13
13
|
context: string;
|
|
14
14
|
};
|
|
15
|
+
registry?: TypeRegistry;
|
|
15
16
|
targets: Array<{
|
|
16
17
|
name: string;
|
|
17
18
|
endpoint: string;
|