@constructive-io/graphql-codegen 4.8.1 → 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.
Files changed (33) hide show
  1. package/core/codegen/cli/arg-mapper.d.ts +1 -1
  2. package/core/codegen/cli/arg-mapper.js +15 -11
  3. package/core/codegen/cli/custom-command-generator.js +4 -3
  4. package/core/codegen/cli/docs-generator.d.ts +6 -5
  5. package/core/codegen/cli/docs-generator.js +167 -64
  6. package/core/codegen/cli/table-command-generator.d.ts +15 -0
  7. package/core/codegen/cli/table-command-generator.js +29 -3
  8. package/core/codegen/docs-utils.d.ts +26 -1
  9. package/core/codegen/docs-utils.js +105 -0
  10. package/core/codegen/orm/input-types-generator.js +112 -14
  11. package/core/codegen/orm/model-generator.js +8 -0
  12. package/core/codegen/orm/select-types.d.ts +4 -2
  13. package/core/codegen/scalars.js +8 -0
  14. package/core/codegen/templates/cli-entry.ts +2 -2
  15. package/core/codegen/templates/cli-utils.ts +28 -0
  16. package/core/codegen/templates/query-builder.ts +28 -5
  17. package/core/codegen/templates/select-types.ts +4 -2
  18. package/core/generate.js +14 -4
  19. package/esm/core/codegen/cli/arg-mapper.d.ts +1 -1
  20. package/esm/core/codegen/cli/arg-mapper.js +15 -11
  21. package/esm/core/codegen/cli/custom-command-generator.js +4 -3
  22. package/esm/core/codegen/cli/docs-generator.d.ts +6 -5
  23. package/esm/core/codegen/cli/docs-generator.js +168 -65
  24. package/esm/core/codegen/cli/table-command-generator.d.ts +15 -0
  25. package/esm/core/codegen/cli/table-command-generator.js +29 -5
  26. package/esm/core/codegen/docs-utils.d.ts +26 -1
  27. package/esm/core/codegen/docs-utils.js +102 -0
  28. package/esm/core/codegen/orm/input-types-generator.js +112 -14
  29. package/esm/core/codegen/orm/model-generator.js +8 -0
  30. package/esm/core/codegen/orm/select-types.d.ts +4 -2
  31. package/esm/core/codegen/scalars.js +8 -0
  32. package/esm/core/generate.js +14 -4
  33. package/package.json +11 -11
@@ -21,9 +21,10 @@ export interface PageInfo {
21
21
  endCursor?: string | null;
22
22
  }
23
23
 
24
- export interface FindManyArgs<TSelect, TWhere, TOrderBy> {
24
+ export interface FindManyArgs<TSelect, TWhere, TCondition, TOrderBy> {
25
25
  select?: TSelect;
26
26
  where?: TWhere;
27
+ condition?: TCondition;
27
28
  orderBy?: TOrderBy[];
28
29
  first?: number;
29
30
  last?: number;
@@ -32,9 +33,10 @@ export interface FindManyArgs<TSelect, TWhere, TOrderBy> {
32
33
  offset?: number;
33
34
  }
34
35
 
35
- export interface FindFirstArgs<TSelect, TWhere> {
36
+ export interface FindFirstArgs<TSelect, TWhere, TCondition> {
36
37
  select?: TSelect;
37
38
  where?: TWhere;
39
+ condition?: TCondition;
38
40
  }
39
41
 
40
42
  export interface CreateArgs<TSelect, TData> {
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(arg.name)));
21
- props.push(t.objectProperty(t.identifier('message'), t.stringLiteral(arg.description || arg.name)));
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(arg.name)));
27
- props.push(t.objectProperty(t.identifier('message'), t.stringLiteral(arg.description || arg.name)));
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(arg.name)));
34
- props.push(t.objectProperty(t.identifier('message'), t.stringLiteral(arg.description || `${arg.name} (number)`)));
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(arg.name)));
42
- props.push(t.objectProperty(t.identifier('message'), t.stringLiteral(arg.description || arg.name)));
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('parseMutationInput');
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
- // parse JSON strings from CLI into proper objects
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('parseMutationInput'), [
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;