Skip to content

Commit

Permalink
refactor: import and export statements in BaseResolversVisitor and ma… (
Browse files Browse the repository at this point in the history
#9845)

* refactor: import and export statements in BaseResolversVisitor and mappers.ts

* run prettier

* Refactor mapper functions to use includes() instead of startsWith() and replace()

* yarn changeset

* feat: add test

* Remove unused query.ts file

* Add RoleStatus enum and import it in result.d.ts and schema.graphql
  • Loading branch information
productdevbook committed Feb 20, 2024
1 parent 4acf545 commit 53f270a
Show file tree
Hide file tree
Showing 6 changed files with 227 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/serious-ladybugs-pull.md
@@ -0,0 +1,5 @@
---
'@graphql-codegen/visitor-plugin-common': major
---

path starts with "#"
11 changes: 11 additions & 0 deletions dev-test/codegen.ts
Expand Up @@ -232,6 +232,17 @@ const config: CodegenConfig = {
mergeFragmentTypes: true,
},
},
'./dev-test/subpath-import/result.d.ts': {
schema: './dev-test/subpath-import/schema.graphql',
plugins: ['typescript', 'typescript-resolvers'],
config: {
contextType: '\\#test-null-value/context#TestContext',
fieldContextTypes: ['mutation.createUser#\\#test/root#FiedContextType'],
enumValues: {
RoleStatus: '\\#changeName/server/drizzle/schema#RoleStatus',
},
},
},
},
};

Expand Down
167 changes: 167 additions & 0 deletions dev-test/subpath-import/result.d.ts
@@ -0,0 +1,167 @@
import { RoleStatus } from '#changeName/server/drizzle/schema';
import { GraphQLResolveInfo } from 'graphql';
import { TestContext } from '#test-null-value/context';
import { FiedContextType } from '#test/root';
export type Maybe<T> = T | null;
export type InputMaybe<T> = Maybe<T>;
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 };
export type EnumResolverSignature<T, AllowedValues = any> = { [key in keyof T]?: AllowedValues };
export type RequireFields<T, K extends keyof T> = Omit<T, K> & { [P in K]-?: NonNullable<T[P]> };
/** 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 };
};

export { RoleStatus };

export type User = {
__typename?: 'User';
createdAt: Scalars['String']['output'];
email: Scalars['String']['output'];
id: Scalars['ID']['output'];
name: Scalars['String']['output'];
password: Scalars['String']['output'];
updatedAt: Scalars['String']['output'];
};

export type Mutation = {
__typename?: 'mutation';
createUser: User;
};

export type MutationCreateUserArgs = {
email: Scalars['String']['input'];
name: Scalars['String']['input'];
password: Scalars['String']['input'];
};

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 = {}, TContext = {}, TArgs = {}> =
| 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 = {}, TContext = {}, TArgs = {}> =
| ((...args: any[]) => SubscriptionObject<TResult, TKey, TParent, TContext, TArgs>)
| SubscriptionObject<TResult, TKey, TParent, TContext, TArgs>;

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

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

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

export type DirectiveResolverFn<TResult = {}, TParent = {}, TContext = {}, TArgs = {}> = (
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 = {
Boolean: ResolverTypeWrapper<Scalars['Boolean']['output']>;
ID: ResolverTypeWrapper<Scalars['ID']['output']>;
RoleStatus: RoleStatus;
String: ResolverTypeWrapper<Scalars['String']['output']>;
User: ResolverTypeWrapper<User>;
mutation: ResolverTypeWrapper<Mutation>;
};

/** Mapping between all available schema types and the resolvers parents */
export type ResolversParentTypes = {
Boolean: Scalars['Boolean']['output'];
ID: Scalars['ID']['output'];
String: Scalars['String']['output'];
User: User;
mutation: Mutation;
};

export type RoleStatusResolvers = EnumResolverSignature<{ ADMIN?: any; USER?: any }, ResolversTypes['RoleStatus']>;

export type UserResolvers<
ContextType = TestContext,
ParentType extends ResolversParentTypes['User'] = ResolversParentTypes['User']
> = {
createdAt?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
email?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
id?: Resolver<ResolversTypes['ID'], ParentType, ContextType>;
name?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
password?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
updatedAt?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
};

export type MutationResolvers<
ContextType = TestContext,
ParentType extends ResolversParentTypes['mutation'] = ResolversParentTypes['mutation']
> = {
createUser?: Resolver<
ResolversTypes['User'],
ParentType,
FiedContextType,
RequireFields<MutationCreateUserArgs, 'email' | 'name' | 'password'>
>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
};

export type Resolvers<ContextType = TestContext> = {
RoleStatus?: RoleStatusResolvers;
User?: UserResolvers<ContextType>;
mutation?: MutationResolvers<ContextType>;
};
17 changes: 17 additions & 0 deletions dev-test/subpath-import/schema.graphql
@@ -0,0 +1,17 @@
type User {
id: ID!
name: String!
email: String!
password: String!
createdAt: String!
updatedAt: String!
}

enum RoleStatus {
ADMIN
USER
}

type mutation {
createUser(name: String!, email: String!, password: String!): User!
}
Expand Up @@ -1075,21 +1075,31 @@ export class BaseResolversVisitor<

protected createFieldContextTypeMap(): FieldContextTypeMap {
return this.config.fieldContextTypes.reduce<FieldContextTypeMap>((prev, fieldContextType) => {
const isScoped = fieldContextType.includes('\\#');
if (fieldContextType.includes('\\#')) {
fieldContextType = fieldContextType.replace('\\#', '');
}
const items = fieldContextType.split('#');
if (items.length === 3) {
const [path, source, contextTypeName] = items;
return { ...prev, [path]: parseMapper(`${source}#${contextTypeName}`) };
const sourceStr = isScoped ? `\\#${source}` : source;
return { ...prev, [path]: parseMapper(`${sourceStr}#${contextTypeName}`) };
}
const [path, contextType] = items;
return { ...prev, [path]: parseMapper(contextType) };
}, {});
}
protected createDirectivedContextType(): FieldContextTypeMap {
return this.config.directiveContextTypes.reduce<FieldContextTypeMap>((prev, fieldContextType) => {
const isScoped = fieldContextType.includes('\\#');
if (fieldContextType.includes('\\#')) {
fieldContextType = fieldContextType.replace('\\#', '');
}
const items = fieldContextType.split('#');
if (items.length === 3) {
const [path, source, contextTypeName] = items;
return { ...prev, [path]: parseMapper(`${source}#${contextTypeName}`) };
const sourceStr = isScoped ? `\\#${source}` : source;
return { ...prev, [path]: parseMapper(`${sourceStr}#${contextTypeName}`) };
}
const [path, contextType] = items;
return { ...prev, [path]: parseMapper(contextType) };
Expand Down
16 changes: 15 additions & 1 deletion packages/plugins/other/visitor-plugin-common/src/mappers.ts
Expand Up @@ -33,10 +33,16 @@ interface Helpers {
}

function prepareLegacy(mapper: string): Helpers {
const isScoped = mapper.includes('\\#');
if (mapper.includes('\\#')) {
mapper = mapper.replace('\\#', '');
}
const items = mapper.split('#');
const isNamespace = items.length === 3;
const isDefault = items[1].trim() === 'default' || items[1].startsWith('default ');
const hasAlias = items[1].includes(' as ');
const source = isScoped ? `#${items[0]}` : items[0];
items[0] = source;

return {
items,
Expand All @@ -47,10 +53,15 @@ function prepareLegacy(mapper: string): Helpers {
}

function prepare(mapper: string): Helpers {
const [source, path] = mapper.split('#');
const isScoped = mapper.includes('\\#');
if (mapper.includes('\\#')) {
mapper = mapper.replace('\\#', '');
}
let [source, path] = mapper.split('#');
const isNamespace = path.includes('.');
const isDefault = path.trim() === 'default' || path.startsWith('default ');
const hasAlias = path.includes(' as ');
source = isScoped ? `#${source}` : source;

return {
items: isNamespace ? [source, ...path.split('.')] : [source, path],
Expand All @@ -61,6 +72,9 @@ function prepare(mapper: string): Helpers {
}

function isLegacyMode(mapper: string) {
if (mapper.includes('\\#')) {
mapper = mapper.replace('\\#', '');
}
return mapper.split('#').length === 3;
}

Expand Down

0 comments on commit 53f270a

Please sign in to comment.