Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .changeset/tender-papayas-stare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
'@graphql-codegen/visitor-plugin-common': patch
---

Handle schema extension nodes correctly

When a schema doesn't have an operation type defined but has `schema extension` definitions with directives like below,
schema extensions are not converted to schema definitions by GraphQL Tools.
So the visitor should handle schema extension nodes correctly.

Follow-up to https://github.com/ardatan/graphql-tools/pull/7679

```graphql
extend schema @link(url: "https://specs.apollo.dev/federation/v2.0", import: ["@key"])

type Foo {
id: ID! @key
name: String
}
```
13 changes: 13 additions & 0 deletions dev-test/codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,19 @@ const config: CodegenConfig = {
},
},
},
'./dev-test/test-federation/generated/types.ts': {
schema: './dev-test/test-federation/schema.gql',
plugins: ['typescript', 'typescript-resolvers'],
config: {
mapperTypeSuffix: 'Mapper',
enumsAsTypes: true,
useIndexSignature: true,
maybeValue: 'T | null | undefined',
scalars: {
CarKey: 'string',
},
},
},
},
};

Expand Down
145 changes: 145 additions & 0 deletions dev-test/test-federation/generated/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import { GraphQLResolveInfo, GraphQLScalarType, GraphQLScalarTypeConfig } from 'graphql';
export type Maybe<T> = T | null | undefined;
export type InputMaybe<T> = T | null | undefined;
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
export type MakeEmpty<T extends { [key: string]: unknown }, K extends keyof T> = { [_ in K]?: never };
export type Incremental<T> = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never };
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
ID: { input: string; output: string };
String: { input: string; output: string };
Boolean: { input: boolean; output: boolean };
Int: { input: number; output: number };
Float: { input: number; output: number };
/** Represents a car */
CarKey: { input: string; output: string };
};

export type Car = {
__typename?: 'Car';
carKey: Scalars['CarKey']['output'];
/** Extend Car with a simple "dummy" field */
dummy?: Maybe<Scalars['String']['output']>;
};

export type WithIndex<TObject> = TObject & Record<string, any>;
export type ResolversObject<TObject> = WithIndex<TObject>;

export type ResolverTypeWrapper<T> = Promise<T> | T;

export type ResolverWithResolve<TResult, TParent, TContext, TArgs> = {
resolve: ResolverFn<TResult, TParent, TContext, TArgs>;
};
export type Resolver<
TResult,
TParent = Record<PropertyKey, never>,
TContext = Record<PropertyKey, never>,
TArgs = Record<PropertyKey, never>
> = ResolverFn<TResult, TParent, TContext, TArgs> | ResolverWithResolve<TResult, TParent, TContext, TArgs>;

export type ResolverFn<TResult, TParent, TContext, TArgs> = (
parent: TParent,
args: TArgs,
context: TContext,
info: GraphQLResolveInfo
) => Promise<TResult> | TResult;

export type SubscriptionSubscribeFn<TResult, TParent, TContext, TArgs> = (
parent: TParent,
args: TArgs,
context: TContext,
info: GraphQLResolveInfo
) => AsyncIterable<TResult> | Promise<AsyncIterable<TResult>>;

export type SubscriptionResolveFn<TResult, TParent, TContext, TArgs> = (
parent: TParent,
args: TArgs,
context: TContext,
info: GraphQLResolveInfo
) => TResult | Promise<TResult>;

export interface SubscriptionSubscriberObject<TResult, TKey extends string, TParent, TContext, TArgs> {
subscribe: SubscriptionSubscribeFn<{ [key in TKey]: TResult }, TParent, TContext, TArgs>;
resolve?: SubscriptionResolveFn<TResult, { [key in TKey]: TResult }, TContext, TArgs>;
}

export interface SubscriptionResolverObject<TResult, TParent, TContext, TArgs> {
subscribe: SubscriptionSubscribeFn<any, TParent, TContext, TArgs>;
resolve: SubscriptionResolveFn<TResult, any, TContext, TArgs>;
}

export type SubscriptionObject<TResult, TKey extends string, TParent, TContext, TArgs> =
| SubscriptionSubscriberObject<TResult, TKey, TParent, TContext, TArgs>
| SubscriptionResolverObject<TResult, TParent, TContext, TArgs>;

export type SubscriptionResolver<
TResult,
TKey extends string,
TParent = Record<PropertyKey, never>,
TContext = Record<PropertyKey, never>,
TArgs = Record<PropertyKey, never>
> =
| ((...args: any[]) => SubscriptionObject<TResult, TKey, TParent, TContext, TArgs>)
| SubscriptionObject<TResult, TKey, TParent, TContext, TArgs>;

export type TypeResolveFn<TTypes, TParent = Record<PropertyKey, never>, TContext = Record<PropertyKey, never>> = (
parent: TParent,
context: TContext,
info: GraphQLResolveInfo
) => Maybe<TTypes> | Promise<Maybe<TTypes>>;

export type IsTypeOfResolverFn<T = Record<PropertyKey, never>, TContext = Record<PropertyKey, never>> = (
obj: T,
context: TContext,
info: GraphQLResolveInfo
) => boolean | Promise<boolean>;

export type NextResolverFn<T> = () => Promise<T>;

export type DirectiveResolverFn<
TResult = Record<PropertyKey, never>,
TParent = Record<PropertyKey, never>,
TContext = Record<PropertyKey, never>,
TArgs = Record<PropertyKey, never>
> = (
next: NextResolverFn<TResult>,
parent: TParent,
args: TArgs,
context: TContext,
info: GraphQLResolveInfo
) => TResult | Promise<TResult>;

/** Mapping between all available schema types and the resolvers types */
export type ResolversTypes = ResolversObject<{
Boolean: ResolverTypeWrapper<Scalars['Boolean']['output']>;
Car: ResolverTypeWrapper<Car>;
CarKey: ResolverTypeWrapper<Scalars['CarKey']['output']>;
String: ResolverTypeWrapper<Scalars['String']['output']>;
}>;

/** Mapping between all available schema types and the resolvers parents */
export type ResolversParentTypes = ResolversObject<{
Boolean: Scalars['Boolean']['output'];
Car: Car;
CarKey: Scalars['CarKey']['output'];
String: Scalars['String']['output'];
}>;

export type CarResolvers<
ContextType = any,
ParentType extends ResolversParentTypes['Car'] = ResolversParentTypes['Car']
> = ResolversObject<{
carKey?: Resolver<ResolversTypes['CarKey'], ParentType, ContextType>;
dummy?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
}>;

export interface CarKeyScalarConfig extends GraphQLScalarTypeConfig<ResolversTypes['CarKey'], any> {
name: 'CarKey';
}

export type Resolvers<ContextType = any> = ResolversObject<{
Car?: CarResolvers<ContextType>;
CarKey?: GraphQLScalarType;
}>;
16 changes: 16 additions & 0 deletions dev-test/test-federation/schema.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
extend schema
@link(url: "https://specs.apollo.dev/link/v1.0")
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@key", "@extends"])

type Car @extends @key(fields: "carKey") {
carKey: CarKey!
"""
Extend Car with a simple "dummy" field
"""
dummy: String
}

"""
Represents a car
"""
scalar CarKey
Original file line number Diff line number Diff line change
Expand Up @@ -2067,6 +2067,10 @@ export class BaseResolversVisitor<
return null;
}

SchemaExtension() {
return null;
}

private getRelevantFieldsToOmit({
schemaType,
shouldInclude,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1046,6 +1046,10 @@ export class BaseTypesVisitor<
return null;
}

SchemaExtension() {
return null;
}

getNodeComment(node: FieldDefinitionNode | EnumValueDefinitionNode | InputValueDefinitionNode): string {
let commentText = node.description?.value;
const deprecationDirective = node.directives.find(v => v.name.value === 'deprecated');
Expand Down
18 changes: 9 additions & 9 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2998,9 +2998,9 @@
ws "^8.17.1"

"@graphql-tools/utils@^10.0.0", "@graphql-tools/utils@^10.0.13", "@graphql-tools/utils@^10.10.0", "@graphql-tools/utils@^10.10.1", "@graphql-tools/utils@^10.3.2", "@graphql-tools/utils@^10.5.4", "@graphql-tools/utils@^10.8.6":
version "10.10.1"
resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-10.10.1.tgz#eeec3bdc5f5521b8b11c5148cdf0c8affb4f9aed"
integrity sha512-9iOZ7x6tuIpp/dviNmTCSH1cDDNLIcrj6T3WKH9lU4nRWx5Pr0e7Faj7T/HmP2Njrjik63dJWuDVRxfQSTOc4g==
version "10.10.2"
resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-10.10.2.tgz#2edeb1672dfb0183a23145453ea73c89d1a013c6"
integrity sha512-aVPIAsZ8PMomO2UODO+uG8YCwYOfPthHO2b8pXqixlXx01L0B01qGkrQ0KYJDI/gozNNFXiZ3TfoFMXSGnPiow==
dependencies:
"@graphql-typed-document-node/core" "^3.1.1"
"@whatwg-node/promise-helpers" "^1.0.0"
Expand Down Expand Up @@ -4890,16 +4890,16 @@
resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756"
integrity sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==

"@types/unist@*", "@types/unist@^2", "@types/unist@^2.0.0", "@types/unist@^2.0.2":
version "2.0.11"
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.11.tgz#11af57b127e32487774841f7a4e54eab166d03c4"
integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==

"@types/unist@^3.0.0":
"@types/unist@*", "@types/unist@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.0.tgz#988ae8af1e5239e89f9fbb1ade4c935f4eeedf9a"
integrity sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==

"@types/unist@^2", "@types/unist@^2.0.0", "@types/unist@^2.0.2":
version "2.0.11"
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.11.tgz#11af57b127e32487774841f7a4e54eab166d03c4"
integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==

"@types/ws@^8.0.0":
version "8.5.4"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.4.tgz#bb10e36116d6e570dd943735f86c933c1587b8a5"
Expand Down
Loading