From 93414a3b6b008f1de2cc65711451c8fff7a3d7d1 Mon Sep 17 00:00:00 2001 From: Gefei Hou Date: Wed, 20 May 2026 04:31:16 -0700 Subject: [PATCH] Fix codegen minor issues --- .../client-generator.test.ts.snap | 4 +- .../codegen/input-types-generator.test.ts | 66 +++++++++++++++++++ .../src/core/codegen/orm/client-generator.ts | 6 +- .../core/codegen/orm/input-types-generator.ts | 36 ++++++++++ 4 files changed, 109 insertions(+), 3 deletions(-) diff --git a/graphql/codegen/src/__tests__/codegen/__snapshots__/client-generator.test.ts.snap b/graphql/codegen/src/__tests__/codegen/__snapshots__/client-generator.test.ts.snap index fe2967709d..f062f5c697 100644 --- a/graphql/codegen/src/__tests__/codegen/__snapshots__/client-generator.test.ts.snap +++ b/graphql/codegen/src/__tests__/codegen/__snapshots__/client-generator.test.ts.snap @@ -11,7 +11,7 @@ import type { OrmClientConfig } from "./client"; import { UserModel } from "./models/user"; import { PostModel } from "./models/post"; export type { OrmClientConfig, QueryResult, GraphQLError, GraphQLAdapter } from "./client"; -export { GraphQLRequestError } from "./client"; +export { GraphQLRequestError, FetchAdapter } from "./client"; export { QueryBuilder } from "./query-builder"; export * from "./select-types"; export * from "./models"; @@ -59,7 +59,7 @@ import { UserModel } from "./models/user"; import { createQueryOperations } from "./query"; import { createMutationOperations } from "./mutation"; export type { OrmClientConfig, QueryResult, GraphQLError, GraphQLAdapter } from "./client"; -export { GraphQLRequestError } from "./client"; +export { GraphQLRequestError, FetchAdapter } from "./client"; export { QueryBuilder } from "./query-builder"; export * from "./select-types"; export * from "./models"; diff --git a/graphql/codegen/src/__tests__/codegen/input-types-generator.test.ts b/graphql/codegen/src/__tests__/codegen/input-types-generator.test.ts index 63f18029dd..cc76ad38a9 100644 --- a/graphql/codegen/src/__tests__/codegen/input-types-generator.test.ts +++ b/graphql/codegen/src/__tests__/codegen/input-types-generator.test.ts @@ -1003,3 +1003,69 @@ describe('edge cases', () => { ); }); }); + +// ============================================================================ +// Tests - Table Field Argument Input Types (Bucket-style computed fields) +// ============================================================================ + +describe('table field argument input types', () => { + it('emits Input types referenced only by table-field args', () => { + // Bucket-style computed field: requestBulkUploadUrls(files: [FooBulkUploadFileInput!]!) + const bucketTable = createTable({ + name: 'FooBucket', + fields: [ + { name: 'id', type: fieldTypes.uuid }, + { + name: 'requestBulkUploadUrls', + type: { gqlType: 'String', isArray: true } as FieldType, + args: [ + { + name: 'files', + type: createNonNull( + createList( + createNonNull( + createTypeRef('INPUT_OBJECT', 'FooBulkUploadFileInput'), + ), + ), + ), + isRequired: true, + }, + ], + }, + ], + }); + + const registry = createTypeRegistry({ + FooBulkUploadFileInput: { + kind: 'INPUT_OBJECT', + name: 'FooBulkUploadFileInput', + inputFields: [ + { + name: 'fileName', + type: createNonNull(createTypeRef('SCALAR', 'String')), + }, + { + name: 'contentType', + type: createTypeRef('SCALAR', 'String'), + }, + { + name: 'sizeBytes', + type: createNonNull(createTypeRef('SCALAR', 'Int')), + }, + ], + }, + }); + + // No custom operations — input type is referenced only via the + // computed field's `args`. Without the field-arg seeding fix, this + // type would be inlined into FooBucketSelect but never declared. + const result = generateInputTypesFile(registry, new Set(), [bucketTable]); + + expect(result.content).toContain( + 'export interface FooBulkUploadFileInput {', + ); + expect(result.content).toContain('fileName: string;'); + expect(result.content).toContain('contentType?: string;'); + expect(result.content).toContain('sizeBytes: number;'); + }); +}); diff --git a/graphql/codegen/src/core/codegen/orm/client-generator.ts b/graphql/codegen/src/core/codegen/orm/client-generator.ts index 3920ec5b38..9f0751c2d7 100644 --- a/graphql/codegen/src/core/codegen/orm/client-generator.ts +++ b/graphql/codegen/src/core/codegen/orm/client-generator.ts @@ -196,7 +196,7 @@ export function generateCreateClientFile( typeExportDecl.exportKind = 'type'; statements.push(typeExportDecl); - // export { GraphQLRequestError } from './client'; + // export { GraphQLRequestError, FetchAdapter } from './client'; statements.push( t.exportNamedDeclaration( null, @@ -205,6 +205,10 @@ export function generateCreateClientFile( t.identifier('GraphQLRequestError'), t.identifier('GraphQLRequestError'), ), + t.exportSpecifier( + t.identifier('FetchAdapter'), + t.identifier('FetchAdapter'), + ), ], t.stringLiteral('./client'), ), diff --git a/graphql/codegen/src/core/codegen/orm/input-types-generator.ts b/graphql/codegen/src/core/codegen/orm/input-types-generator.ts index 37c94f3168..de628737cb 100644 --- a/graphql/codegen/src/core/codegen/orm/input-types-generator.ts +++ b/graphql/codegen/src/core/codegen/orm/input-types-generator.ts @@ -1993,6 +1993,33 @@ function collectFilterExtraInputTypes( return extraTypes; } +/** + * Collect input type names referenced by table field arguments. + * + * Computed fields (e.g., `requestBulkUploadUrls(files: [FooBulkUploadFileInput!]!)` + * on bucket tables) reference custom Input types in their args. These are inlined + * into the generated `*Select` types via `typeRefToTs`, but were never registered + * for generation, leaving the referenced Input interfaces undefined. Seed them + * here so `generateCustomInputTypes` emits them (transitively, via its nested + * field-type follow logic). + */ +function collectFieldArgInputTypes(tables: Table[]): Set { + const out = new Set(); + for (const table of tables) { + for (const field of table.fields) { + if (!field.args || field.args.length === 0) continue; + for (const arg of field.args) { + const baseName = getTypeBaseName(arg.type); + if (!baseName) continue; + if (baseName.endsWith('Input') || baseName.endsWith('Filter')) { + out.add(baseName); + } + } + } + } + return out; +} + // ============================================================================ // Main Generator (AST-based) // ============================================================================ @@ -2066,6 +2093,15 @@ export function generateInputTypesFile( for (const typeName of filterExtraTypes) { mergedUsedInputTypes.add(typeName); } + // Seed input types referenced by table-field args (e.g., + // `requestBulkUploadUrls(files: [DataRoomBucketsBulkUploadFileInput!]!)` + // on bucket tables). These are inlined into *Select types via typeRefToTs + // but are not part of any operation's args, so they would otherwise never + // be registered for generation. + const fieldArgTypes = collectFieldArgInputTypes(tablesList); + for (const typeName of fieldArgTypes) { + mergedUsedInputTypes.add(typeName); + } } const tableCrudTypes = tables ? buildTableCrudTypeNames(tables) : undefined; // Pass customScalarTypes + enumTypes as already-generated to avoid duplicate declarations