diff --git a/packages/graphql-api/codegen.yml b/packages/graphql-api/codegen.yml index 6f447611b..7baab3ec6 100644 --- a/packages/graphql-api/codegen.yml +++ b/packages/graphql-api/codegen.yml @@ -7,6 +7,6 @@ generates: noNamespaces: true plugins: - add: /* tslint:disable */ - - typescript-common - - typescript-server + - typescript - typescript-resolvers + - typescript-operations \ No newline at end of file diff --git a/packages/graphql-api/package.json b/packages/graphql-api/package.json index 1f50dd394..ae7b5bd60 100644 --- a/packages/graphql-api/package.json +++ b/packages/graphql-api/package.json @@ -33,16 +33,17 @@ "@accounts/types": "^0.19.0", "@gql2ts/from-schema": "1.10.1", "@gql2ts/types": "1.9.0", + "@graphql-codegen/add": "^1.6.1", + "@graphql-codegen/cli": "^1.6.1", + "@graphql-codegen/typescript": "^1.6.1", + "@graphql-codegen/typescript-operations": "^1.6.1", + "@graphql-codegen/typescript-resolvers": "^1.6.1", + "@graphql-codegen/typescript-type-graphql": "^1.6.1", "@graphql-modules/core": "0.7.10", "@types/jest": "24.0.18", "@types/request-ip": "0.0.34", "concurrently": "4.1.2", "graphql": "14.5.3", - "graphql-code-generator": "0.18.2", - "graphql-codegen-add": "0.18.2", - "graphql-codegen-typescript-common": "0.18.2", - "graphql-codegen-typescript-resolvers": "0.18.2", - "graphql-codegen-typescript-server": "0.18.2", "graphql-tools": "4.0.5", "jest": "24.9.0", "lodash": "4.17.15", diff --git a/packages/graphql-api/src/models.ts b/packages/graphql-api/src/models.ts index 33934612c..c7255a8f3 100644 --- a/packages/graphql-api/src/models.ts +++ b/packages/graphql-api/src/models.ts @@ -1,611 +1,447 @@ /* tslint:disable */ +import { GraphQLResolveInfo } from 'graphql'; export type Maybe = T | null; - -export interface CreateUserInput { - username?: Maybe; - - email?: Maybe; - - password?: Maybe; -} - -export interface TwoFactorSecretKeyInput { - ascii?: Maybe; - - base32?: Maybe; - - hex?: Maybe; - - qr_code_ascii?: Maybe; - - qr_code_hex?: Maybe; - - qr_code_base32?: Maybe; - - google_auth_qr?: Maybe; - - otpauth_url?: Maybe; -} - -export interface AuthenticateParamsInput { - access_token?: Maybe; - - access_token_secret?: Maybe; - - provider?: Maybe; - - password?: Maybe; - +export type RequireFields = { [X in Exclude]?: T[X] } & + { [P in K]-?: NonNullable }; +/** All built-in and custom scalars, mapped to their actual values */ +export type Scalars = { + ID: string; + String: string; + Boolean: boolean; + Int: number; + Float: number; +}; + +export type AuthenticateParamsInput = { + access_token?: Maybe; + access_token_secret?: Maybe; + provider?: Maybe; + password?: Maybe; user?: Maybe; + code?: Maybe; +}; + +export type CreateUserInput = { + username?: Maybe; + email?: Maybe; + password?: Maybe; +}; + +export type EmailRecord = { + __typename?: 'EmailRecord'; + address?: Maybe; + verified?: Maybe; +}; + +export type ImpersonateReturn = { + __typename?: 'ImpersonateReturn'; + authorized?: Maybe; + tokens?: Maybe; + user?: Maybe; +}; - code?: Maybe; -} - -export interface UserInput { - id?: Maybe; - - email?: Maybe; - - username?: Maybe; -} - -// ==================================================== -// Types -// ==================================================== - -export interface Query { - twoFactorSecret?: Maybe; - - getUser?: Maybe; -} - -export interface TwoFactorSecretKey { - ascii?: Maybe; - - base32?: Maybe; - - hex?: Maybe; - - qr_code_ascii?: Maybe; - - qr_code_hex?: Maybe; - - qr_code_base32?: Maybe; - - google_auth_qr?: Maybe; - - otpauth_url?: Maybe; -} - -export interface User { - id: string; - - emails?: Maybe; - - username?: Maybe; -} - -export interface EmailRecord { - address?: Maybe; - - verified?: Maybe; -} - -export interface Mutation { - createUser?: Maybe; - - verifyEmail?: Maybe; +export type LoginResult = { + __typename?: 'LoginResult'; + sessionId?: Maybe; + tokens?: Maybe; +}; +export type Mutation = { + __typename?: 'Mutation'; + createUser?: Maybe; + verifyEmail?: Maybe; resetPassword?: Maybe; - - sendVerificationEmail?: Maybe; - - sendResetPasswordEmail?: Maybe; - - changePassword?: Maybe; - - twoFactorSet?: Maybe; - - twoFactorUnset?: Maybe; - + sendVerificationEmail?: Maybe; + sendResetPasswordEmail?: Maybe; + changePassword?: Maybe; + twoFactorSet?: Maybe; + twoFactorUnset?: Maybe; impersonate?: Maybe; - refreshTokens?: Maybe; - - logout?: Maybe; - + logout?: Maybe; authenticate?: Maybe; -} +}; -export interface LoginResult { - sessionId?: Maybe; - - tokens?: Maybe; -} - -export interface Tokens { - refreshToken?: Maybe; - - accessToken?: Maybe; -} - -export interface ImpersonateReturn { - authorized?: Maybe; +export type MutationCreateUserArgs = { + user: CreateUserInput; +}; - tokens?: Maybe; +export type MutationVerifyEmailArgs = { + token: Scalars['String']; +}; - user?: Maybe; -} +export type MutationResetPasswordArgs = { + token: Scalars['String']; + newPassword: Scalars['String']; +}; -// ==================================================== -// Arguments -// ==================================================== +export type MutationSendVerificationEmailArgs = { + email: Scalars['String']; +}; -export interface CreateUserMutationArgs { - user: CreateUserInput; -} -export interface VerifyEmailMutationArgs { - token: string; -} -export interface ResetPasswordMutationArgs { - token: string; +export type MutationSendResetPasswordEmailArgs = { + email: Scalars['String']; +}; - newPassword: string; -} -export interface SendVerificationEmailMutationArgs { - email: string; -} -export interface SendResetPasswordEmailMutationArgs { - email: string; -} -export interface ChangePasswordMutationArgs { - oldPassword: string; +export type MutationChangePasswordArgs = { + oldPassword: Scalars['String']; + newPassword: Scalars['String']; +}; - newPassword: string; -} -export interface TwoFactorSetMutationArgs { +export type MutationTwoFactorSetArgs = { secret: TwoFactorSecretKeyInput; + code: Scalars['String']; +}; - code: string; -} -export interface TwoFactorUnsetMutationArgs { - code: string; -} -export interface ImpersonateMutationArgs { - accessToken: string; +export type MutationTwoFactorUnsetArgs = { + code: Scalars['String']; +}; - username: string; -} -export interface RefreshTokensMutationArgs { - accessToken: string; +export type MutationImpersonateArgs = { + accessToken: Scalars['String']; + username: Scalars['String']; +}; - refreshToken: string; -} -export interface AuthenticateMutationArgs { - serviceName: string; +export type MutationRefreshTokensArgs = { + accessToken: Scalars['String']; + refreshToken: Scalars['String']; +}; +export type MutationAuthenticateArgs = { + serviceName: Scalars['String']; params: AuthenticateParamsInput; -} - -import { GraphQLResolveInfo } from 'graphql'; +}; -export type Resolver = ( - parent: Parent, - args: Args, +export type Query = { + __typename?: 'Query'; + twoFactorSecret?: Maybe; + getUser?: Maybe; +}; + +export type Tokens = { + __typename?: 'Tokens'; + refreshToken?: Maybe; + accessToken?: Maybe; +}; + +export type TwoFactorSecretKey = { + __typename?: 'TwoFactorSecretKey'; + ascii?: Maybe; + base32?: Maybe; + hex?: Maybe; + qr_code_ascii?: Maybe; + qr_code_hex?: Maybe; + qr_code_base32?: Maybe; + google_auth_qr?: Maybe; + otpauth_url?: Maybe; +}; + +export type TwoFactorSecretKeyInput = { + ascii?: Maybe; + base32?: Maybe; + hex?: Maybe; + qr_code_ascii?: Maybe; + qr_code_hex?: Maybe; + qr_code_base32?: Maybe; + google_auth_qr?: Maybe; + otpauth_url?: Maybe; +}; + +export type User = { + __typename?: 'User'; + id: Scalars['ID']; + emails?: Maybe>; + username?: Maybe; +}; + +export type UserInput = { + id?: Maybe; + email?: Maybe; + username?: Maybe; +}; + +export type ResolverTypeWrapper = Promise | T; + +export type ResolverFn = ( + parent: TParent, + args: TArgs, context: TContext, info: GraphQLResolveInfo -) => Promise | Result; - -export interface ISubscriptionResolverObject { - subscribe( - parent: P, - args: Args, - context: TContext, - info: GraphQLResolveInfo - ): AsyncIterator | Promise>; - resolve?( - parent: P, - args: Args, - context: TContext, - info: GraphQLResolveInfo - ): R | Result | Promise; -} +) => Promise | TResult; + +export type StitchingResolver = { + fragment: string; + resolve: ResolverFn; +}; -export type SubscriptionResolver = - | ((...args: any[]) => ISubscriptionResolverObject) - | ISubscriptionResolverObject; +export type Resolver = + | ResolverFn + | StitchingResolver; -export type TypeResolveFn = ( - parent: Parent, +export type SubscriptionSubscribeFn = ( + parent: TParent, + args: TArgs, context: TContext, info: GraphQLResolveInfo -) => Maybe; +) => AsyncIterator | Promise>; -export type NextResolverFn = () => Promise; - -export type DirectiveResolverFn = ( - next: NextResolverFn, - source: any, +export type SubscriptionResolveFn = ( + parent: TParent, args: TArgs, context: TContext, info: GraphQLResolveInfo ) => TResult | Promise; -export interface QueryResolvers { - twoFactorSecret?: QueryTwoFactorSecretResolver, TypeParent, TContext>; - - getUser?: QueryGetUserResolver, TypeParent, TContext>; -} - -export type QueryTwoFactorSecretResolver< - R = Maybe, - Parent = {}, - TContext = {} -> = Resolver; -export type QueryGetUserResolver, Parent = {}, TContext = {}> = Resolver< - R, - Parent, - TContext ->; - -export interface TwoFactorSecretKeyResolvers { - ascii?: TwoFactorSecretKeyAsciiResolver, TypeParent, TContext>; - - base32?: TwoFactorSecretKeyBase32Resolver, TypeParent, TContext>; - - hex?: TwoFactorSecretKeyHexResolver, TypeParent, TContext>; - - qr_code_ascii?: TwoFactorSecretKeyQrCodeAsciiResolver, TypeParent, TContext>; - - qr_code_hex?: TwoFactorSecretKeyQrCodeHexResolver, TypeParent, TContext>; - - qr_code_base32?: TwoFactorSecretKeyQrCodeBase32Resolver, TypeParent, TContext>; - - google_auth_qr?: TwoFactorSecretKeyGoogleAuthQrResolver, TypeParent, TContext>; - - otpauth_url?: TwoFactorSecretKeyOtpauthUrlResolver, TypeParent, TContext>; -} - -export type TwoFactorSecretKeyAsciiResolver< - R = Maybe, - Parent = TwoFactorSecretKey, - TContext = {} -> = Resolver; -export type TwoFactorSecretKeyBase32Resolver< - R = Maybe, - Parent = TwoFactorSecretKey, - TContext = {} -> = Resolver; -export type TwoFactorSecretKeyHexResolver< - R = Maybe, - Parent = TwoFactorSecretKey, - TContext = {} -> = Resolver; -export type TwoFactorSecretKeyQrCodeAsciiResolver< - R = Maybe, - Parent = TwoFactorSecretKey, - TContext = {} -> = Resolver; -export type TwoFactorSecretKeyQrCodeHexResolver< - R = Maybe, - Parent = TwoFactorSecretKey, - TContext = {} -> = Resolver; -export type TwoFactorSecretKeyQrCodeBase32Resolver< - R = Maybe, - Parent = TwoFactorSecretKey, - TContext = {} -> = Resolver; -export type TwoFactorSecretKeyGoogleAuthQrResolver< - R = Maybe, - Parent = TwoFactorSecretKey, - TContext = {} -> = Resolver; -export type TwoFactorSecretKeyOtpauthUrlResolver< - R = Maybe, - Parent = TwoFactorSecretKey, - TContext = {} -> = Resolver; - -export interface UserResolvers { - id?: UserIdResolver; - - emails?: UserEmailsResolver, TypeParent, TContext>; - - username?: UserUsernameResolver, TypeParent, TContext>; -} - -export type UserIdResolver = Resolver< - R, - Parent, - TContext ->; -export type UserEmailsResolver, Parent = User, TContext = {}> = Resolver< - R, - Parent, - TContext ->; -export type UserUsernameResolver, Parent = User, TContext = {}> = Resolver< - R, - Parent, - TContext ->; - -export interface EmailRecordResolvers { - address?: EmailRecordAddressResolver, TypeParent, TContext>; - - verified?: EmailRecordVerifiedResolver, TypeParent, TContext>; -} - -export type EmailRecordAddressResolver< - R = Maybe, - Parent = EmailRecord, - TContext = {} -> = Resolver; -export type EmailRecordVerifiedResolver< - R = Maybe, - Parent = EmailRecord, - TContext = {} -> = Resolver; - -export interface MutationResolvers { - createUser?: MutationCreateUserResolver, TypeParent, TContext>; - - verifyEmail?: MutationVerifyEmailResolver, TypeParent, TContext>; - - resetPassword?: MutationResetPasswordResolver, TypeParent, TContext>; - - sendVerificationEmail?: MutationSendVerificationEmailResolver< - Maybe, - TypeParent, - TContext - >; - - sendResetPasswordEmail?: MutationSendResetPasswordEmailResolver< - Maybe, - TypeParent, - TContext - >; - - changePassword?: MutationChangePasswordResolver, TypeParent, TContext>; - - twoFactorSet?: MutationTwoFactorSetResolver, TypeParent, TContext>; - - twoFactorUnset?: MutationTwoFactorUnsetResolver, TypeParent, TContext>; - - impersonate?: MutationImpersonateResolver, TypeParent, TContext>; - - refreshTokens?: MutationRefreshTokensResolver, TypeParent, TContext>; - - logout?: MutationLogoutResolver, TypeParent, TContext>; - - authenticate?: MutationAuthenticateResolver, TypeParent, TContext>; -} - -export type MutationCreateUserResolver, Parent = {}, TContext = {}> = Resolver< - R, - Parent, - TContext, - MutationCreateUserArgs ->; -export interface MutationCreateUserArgs { - user: CreateUserInput; -} - -export type MutationVerifyEmailResolver, Parent = {}, TContext = {}> = Resolver< - R, - Parent, - TContext, - MutationVerifyEmailArgs ->; -export interface MutationVerifyEmailArgs { - token: string; -} - -export type MutationResetPasswordResolver< - R = Maybe, - Parent = {}, - TContext = {} -> = Resolver; -export interface MutationResetPasswordArgs { - token: string; - - newPassword: string; -} - -export type MutationSendVerificationEmailResolver< - R = Maybe, - Parent = {}, - TContext = {} -> = Resolver; -export interface MutationSendVerificationEmailArgs { - email: string; -} - -export type MutationSendResetPasswordEmailResolver< - R = Maybe, - Parent = {}, - TContext = {} -> = Resolver; -export interface MutationSendResetPasswordEmailArgs { - email: string; -} - -export type MutationChangePasswordResolver< - R = Maybe, - Parent = {}, - TContext = {} -> = Resolver; -export interface MutationChangePasswordArgs { - oldPassword: string; - - newPassword: string; -} - -export type MutationTwoFactorSetResolver, Parent = {}, TContext = {}> = Resolver< - R, - Parent, +export interface SubscriptionSubscriberObject< + TResult, + TKey extends string, + TParent, TContext, - MutationTwoFactorSetArgs ->; -export interface MutationTwoFactorSetArgs { - secret: TwoFactorSecretKeyInput; - - code: string; + TArgs +> { + subscribe: SubscriptionSubscribeFn<{ [key in TKey]: TResult }, TParent, TContext, TArgs>; + resolve?: SubscriptionResolveFn; } -export type MutationTwoFactorUnsetResolver< - R = Maybe, - Parent = {}, - TContext = {} -> = Resolver; -export interface MutationTwoFactorUnsetArgs { - code: string; +export interface SubscriptionResolverObject { + subscribe: SubscriptionSubscribeFn; + resolve: SubscriptionResolveFn; } -export type MutationImpersonateResolver< - R = Maybe, - Parent = {}, - TContext = {} -> = Resolver; -export interface MutationImpersonateArgs { - accessToken: string; - - username: string; -} +export type SubscriptionObject = + | SubscriptionSubscriberObject + | SubscriptionResolverObject; -export type MutationRefreshTokensResolver< - R = Maybe, - Parent = {}, - TContext = {} -> = Resolver; -export interface MutationRefreshTokensArgs { - accessToken: string; +export type SubscriptionResolver< + TResult, + TKey extends string, + TParent = {}, + TContext = {}, + TArgs = {} +> = + | ((...args: any[]) => SubscriptionObject) + | SubscriptionObject; - refreshToken: string; -} - -export type MutationLogoutResolver, Parent = {}, TContext = {}> = Resolver< - R, - Parent, - TContext ->; -export type MutationAuthenticateResolver< - R = Maybe, - Parent = {}, - TContext = {} -> = Resolver; -export interface MutationAuthenticateArgs { - serviceName: string; - - params: AuthenticateParamsInput; -} - -export interface LoginResultResolvers { - sessionId?: LoginResultSessionIdResolver, TypeParent, TContext>; - - tokens?: LoginResultTokensResolver, TypeParent, TContext>; -} - -export type LoginResultSessionIdResolver< - R = Maybe, - Parent = LoginResult, - TContext = {} -> = Resolver; -export type LoginResultTokensResolver< - R = Maybe, - Parent = LoginResult, - TContext = {} -> = Resolver; - -export interface TokensResolvers { - refreshToken?: TokensRefreshTokenResolver, TypeParent, TContext>; - - accessToken?: TokensAccessTokenResolver, TypeParent, TContext>; -} - -export type TokensRefreshTokenResolver< - R = Maybe, - Parent = Tokens, - TContext = {} -> = Resolver; -export type TokensAccessTokenResolver, Parent = Tokens, TContext = {}> = Resolver< - R, - Parent, - TContext ->; - -export interface ImpersonateReturnResolvers { - authorized?: ImpersonateReturnAuthorizedResolver, TypeParent, TContext>; - - tokens?: ImpersonateReturnTokensResolver, TypeParent, TContext>; - - user?: ImpersonateReturnUserResolver, TypeParent, TContext>; -} +export type TypeResolveFn = ( + parent: TParent, + context: TContext, + info: GraphQLResolveInfo +) => Maybe; -export type ImpersonateReturnAuthorizedResolver< - R = Maybe, - Parent = ImpersonateReturn, - TContext = {} -> = Resolver; -export type ImpersonateReturnTokensResolver< - R = Maybe, - Parent = ImpersonateReturn, - TContext = {} -> = Resolver; -export type ImpersonateReturnUserResolver< - R = Maybe, - Parent = ImpersonateReturn, - TContext = {} -> = Resolver; - -export type AuthDirectiveResolver = DirectiveResolverFn< - Result, - {}, - {} ->; /** Directs the executor to skip this field or fragment when the `if` argument is true. */ -export type SkipDirectiveResolver = DirectiveResolverFn; -export interface SkipDirectiveArgs { - /** Skipped when true. */ - if: boolean; -} +export type NextResolverFn = () => Promise; -/** Directs the executor to include this field or fragment only when the `if` argument is true. */ -export type IncludeDirectiveResolver = DirectiveResolverFn< - Result, - IncludeDirectiveArgs, - {} ->; -export interface IncludeDirectiveArgs { - /** Included when true. */ - if: boolean; -} +export type DirectiveResolverFn = ( + next: NextResolverFn, + parent: TParent, + args: TArgs, + context: TContext, + info: GraphQLResolveInfo +) => TResult | Promise; -/** Marks an element of a GraphQL schema as no longer supported. */ -export type DeprecatedDirectiveResolver = DirectiveResolverFn< +/** Mapping between all available schema types and the resolvers types */ +export type ResolversTypes = { + Query: ResolverTypeWrapper<{}>; + TwoFactorSecretKey: ResolverTypeWrapper; + String: ResolverTypeWrapper; + User: ResolverTypeWrapper; + ID: ResolverTypeWrapper; + EmailRecord: ResolverTypeWrapper; + Boolean: ResolverTypeWrapper; + Mutation: ResolverTypeWrapper<{}>; + CreateUserInput: CreateUserInput; + LoginResult: ResolverTypeWrapper; + Tokens: ResolverTypeWrapper; + TwoFactorSecretKeyInput: TwoFactorSecretKeyInput; + ImpersonateReturn: ResolverTypeWrapper; + AuthenticateParamsInput: AuthenticateParamsInput; + UserInput: UserInput; +}; + +/** Mapping between all available schema types and the resolvers parents */ +export type ResolversParentTypes = { + Query: {}; + TwoFactorSecretKey: TwoFactorSecretKey; + String: Scalars['String']; + User: User; + ID: Scalars['ID']; + EmailRecord: EmailRecord; + Boolean: Scalars['Boolean']; + Mutation: {}; + CreateUserInput: CreateUserInput; + LoginResult: LoginResult; + Tokens: Tokens; + TwoFactorSecretKeyInput: TwoFactorSecretKeyInput; + ImpersonateReturn: ImpersonateReturn; + AuthenticateParamsInput: AuthenticateParamsInput; + UserInput: UserInput; +}; + +export type AuthDirectiveResolver< Result, - DeprecatedDirectiveArgs, - {} ->; -export interface DeprecatedDirectiveArgs { - /** Explains why this element was deprecated, usually also including a suggestion for how to access supported similar data. Formatted using the Markdown syntax (as specified by [CommonMark](https://commonmark.org/). */ - reason?: string; -} - -export type IResolvers = { - Query?: QueryResolvers; - TwoFactorSecretKey?: TwoFactorSecretKeyResolvers; - User?: UserResolvers; - EmailRecord?: EmailRecordResolvers; - Mutation?: MutationResolvers; - LoginResult?: LoginResultResolvers; - Tokens?: TokensResolvers; - ImpersonateReturn?: ImpersonateReturnResolvers; -} & { [typeName: string]: never }; - -export type IDirectiveResolvers = { - auth?: AuthDirectiveResolver; - skip?: SkipDirectiveResolver; - include?: IncludeDirectiveResolver; - deprecated?: DeprecatedDirectiveResolver; -} & { [directiveName: string]: never }; + Parent, + ContextType = any, + Args = {} +> = DirectiveResolverFn; + +export type EmailRecordResolvers< + ContextType = any, + ParentType extends ResolversParentTypes['EmailRecord'] = ResolversParentTypes['EmailRecord'] +> = { + address?: Resolver, ParentType, ContextType>; + verified?: Resolver, ParentType, ContextType>; +}; + +export type ImpersonateReturnResolvers< + ContextType = any, + ParentType extends ResolversParentTypes['ImpersonateReturn'] = ResolversParentTypes['ImpersonateReturn'] +> = { + authorized?: Resolver, ParentType, ContextType>; + tokens?: Resolver, ParentType, ContextType>; + user?: Resolver, ParentType, ContextType>; +}; + +export type LoginResultResolvers< + ContextType = any, + ParentType extends ResolversParentTypes['LoginResult'] = ResolversParentTypes['LoginResult'] +> = { + sessionId?: Resolver, ParentType, ContextType>; + tokens?: Resolver, ParentType, ContextType>; +}; + +export type MutationResolvers< + ContextType = any, + ParentType extends ResolversParentTypes['Mutation'] = ResolversParentTypes['Mutation'] +> = { + createUser?: Resolver< + Maybe, + ParentType, + ContextType, + RequireFields + >; + verifyEmail?: Resolver< + Maybe, + ParentType, + ContextType, + RequireFields + >; + resetPassword?: Resolver< + Maybe, + ParentType, + ContextType, + RequireFields + >; + sendVerificationEmail?: Resolver< + Maybe, + ParentType, + ContextType, + RequireFields + >; + sendResetPasswordEmail?: Resolver< + Maybe, + ParentType, + ContextType, + RequireFields + >; + changePassword?: Resolver< + Maybe, + ParentType, + ContextType, + RequireFields + >; + twoFactorSet?: Resolver< + Maybe, + ParentType, + ContextType, + RequireFields + >; + twoFactorUnset?: Resolver< + Maybe, + ParentType, + ContextType, + RequireFields + >; + impersonate?: Resolver< + Maybe, + ParentType, + ContextType, + RequireFields + >; + refreshTokens?: Resolver< + Maybe, + ParentType, + ContextType, + RequireFields + >; + logout?: Resolver, ParentType, ContextType>; + authenticate?: Resolver< + Maybe, + ParentType, + ContextType, + RequireFields + >; +}; + +export type QueryResolvers< + ContextType = any, + ParentType extends ResolversParentTypes['Query'] = ResolversParentTypes['Query'] +> = { + twoFactorSecret?: Resolver, ParentType, ContextType>; + getUser?: Resolver, ParentType, ContextType>; +}; + +export type TokensResolvers< + ContextType = any, + ParentType extends ResolversParentTypes['Tokens'] = ResolversParentTypes['Tokens'] +> = { + refreshToken?: Resolver, ParentType, ContextType>; + accessToken?: Resolver, ParentType, ContextType>; +}; + +export type TwoFactorSecretKeyResolvers< + ContextType = any, + ParentType extends ResolversParentTypes['TwoFactorSecretKey'] = ResolversParentTypes['TwoFactorSecretKey'] +> = { + ascii?: Resolver, ParentType, ContextType>; + base32?: Resolver, ParentType, ContextType>; + hex?: Resolver, ParentType, ContextType>; + qr_code_ascii?: Resolver, ParentType, ContextType>; + qr_code_hex?: Resolver, ParentType, ContextType>; + qr_code_base32?: Resolver, ParentType, ContextType>; + google_auth_qr?: Resolver, ParentType, ContextType>; + otpauth_url?: Resolver, ParentType, ContextType>; +}; + +export type UserResolvers< + ContextType = any, + ParentType extends ResolversParentTypes['User'] = ResolversParentTypes['User'] +> = { + id?: Resolver; + emails?: Resolver>, ParentType, ContextType>; + username?: Resolver, ParentType, ContextType>; +}; + +export type Resolvers = { + EmailRecord?: EmailRecordResolvers; + ImpersonateReturn?: ImpersonateReturnResolvers; + LoginResult?: LoginResultResolvers; + Mutation?: MutationResolvers; + Query?: QueryResolvers; + Tokens?: TokensResolvers; + TwoFactorSecretKey?: TwoFactorSecretKeyResolvers; + User?: UserResolvers; +}; + +/** + * @deprecated + * Use "Resolvers" root object instead. If you wish to get "IResolvers", add "typesPrefix: I" to your config. + */ +export type IResolvers = Resolvers; +export type DirectiveResolvers = { + auth?: AuthDirectiveResolver; +}; + +/** + * @deprecated + * Use "DirectiveResolvers" root object instead. If you wish to get "IDirectiveResolvers", add "typesPrefix: I" to your config. + */ +export type IDirectiveResolvers = DirectiveResolvers; diff --git a/packages/type-graphql/.npmignore b/packages/type-graphql/.npmignore new file mode 100755 index 000000000..e65c31dc0 --- /dev/null +++ b/packages/type-graphql/.npmignore @@ -0,0 +1,6 @@ +src/ +coverage/ +node_modules +yarn.lock +tsconfig.json +.npmignore \ No newline at end of file diff --git a/packages/type-graphql/README.md b/packages/type-graphql/README.md new file mode 100755 index 000000000..1670afa2d --- /dev/null +++ b/packages/type-graphql/README.md @@ -0,0 +1,199 @@ +# @accounts/graphql-api + +_Schema, Resolvers and Utils for GraphQL server with JSAccounts_ + +[![npm](https://img.shields.io/npm/v/@accounts/graphql-api.svg?maxAge=2592000)](https://www.npmjs.com/package/@accounts/graphql-api) +![MIT License](https://img.shields.io/badge/license-MIT-blue.svg) + +> This package does not requires any network interface / express in order to combine with your GraphQL - it's just a collection of GraphQL schema, resolvers and utils! + +## How to use this package? + +This package exports GraphQL schema and GraphQL resolvers, which you can extend with your existing GraphQL schema server. + +Start by installing it from NPM / Yarn: + +```bash +// Npm +npm install --save @accounts/server @accounts/graphql-api @graphql-modules/core + +// Yarn +yarn add @accounts/server @accounts/graphql-api @graphql-modules/core +``` + +> This package does not create a transport or anything else, only schema and string and resolvers as object. + +Start by configuring your `AccountsServer` as you wish. For example, using MongoDB: + +```js +import mongoose from 'mongoose' +import AccountsServer from '@accounts/server' +import AccountsPassword from '@accounts/password' +import MongoDBInterface from '@accounts/mongo' + +const db = mongoose.connection + +const password = new AccountsPassword() + +const accountsServer = new AccountsServer({ + { + db: new MongoDBInterface(db), + tokenSecret: 'SECRET', + }, + { + password, + } +}); +``` + +Next, import `AccountsModule` from this package, and run it with your `AccountsServer`: + +```js +import { AccountsModule } from '@accounts/graphql-api'; + +const accountsGraphQL = AccountsModule.forRoot({ + accountsServer, +}); +``` + +Now, add `accountsGraphQL.typeDefs` to your schema definition (just before using it with `makeExecutableSchema`), and merge your resolvers object with `accountsGraphQL.resolvers` by using `@graphql-tools/epoxy`, for example: + +```js +import { makeExecutableSchema } from 'graphql-tools'; +import { mergeGraphQLSchemas, mergeResolvers } from '@graphql-tools/epoxy'; + +const typeDefs = [ + ` + type Query { + myQuery: String + } + + type Mutation { + myMutation: String + } + + schema { + query: Query, + mutation: Mutation + } + `, + accountsGraphQL.typeDefs, +]; + +let myResolvers = { + Query: { + myQuery: () => 'Hello', + }, + Mutation: { + myMutation: () => 'Hello', + }, +}; + +const schema = makeExecutableSchema({ + resolvers: mergeResolvers([accountsGraphQL.resolvers, myResolvers]), + typeDefs: mergeGraphQLSchemas([typeDefs]), +}); +``` + +The last step is to extend your `graphqlExpress` with a context middleware, that extracts the authentication token from the HTTP request, so AccountsServer will automatically validate it: + +```js +app.use( + GRAPHQL_ROUTE, + bodyParser.json(), + graphqlExpress(request => { + return { + context: { + ...accountsGraphQL(request), + // your context + }, + schema, + }; + }) +); +``` + +## Authenticating Resolvers + +You can authenticate your own resolvers with `JSAccounts` authentication flow, by using `authenticated` method from this package. + +This method composer also extends `context` with the current authenticated user! + +This is an example for a protected mutation: + +```js +import AccountsServer from '@accounts/server'; +import { authenticated } from '@accounts/graphql-api'; + +export const resolver = { + Mutation: { + updateUserProfile: authenticated(AccountsServer, (rootValue, args, context) => { + // Write your resolver here + // context.user - the current authenticated user! + }), + }, +}; +``` + +## Customization + +This package allow you to customize the GraphQL schema and it's resolvers. + +For example, some application main query called `MyQuery` or `RootQuery` instead of query, so you can customize the name, without modifying you application's schema. + +These are the available customizations: + +- `rootQueryName` (string) - The name of the root query, default: `Query`. +- `rootMutationName` (string) - The name of the root mutation, default: `Mutation`. +- `extend` (boolean) - whether to add `extend` before the root type declaration, default: `true`. +- `withSchemaDefinition` (boolean): whether to add `schema { ... }` declaration to the generation schema, default: `false`. + +Pass a second object to `createAccountsGraphQL`, for example: + +Another possible customization is to modify the name of the authentication header, use it with `accountsContext` (the default is `Authorization`): + +```js +const myCustomGraphQLAccounts = AccountsModule.forRoot({ + accountsServer, + rootQueryName: 'RootQuery', + rootMutationName: 'RootMutation', + headerName: 'MyCustomHeader', +}); +``` + +## Extending `User` + +To extend `User` object with custom fields and logic, add your own GraphQL type definition of `User` with the prefix of `extend`, and add your fields: + +```graphql +extend type User { + firstName: String + lastName: String +} +``` + +And also implement a regular resolver, for the fields you added: + +```js +const UserResolver = { + firstName: () => 'Dotan', + lastName: () => 'Simha', +}; +``` + +## Extending `User` during password creation + +To extend the user object during the user creation you need to extend the `CreateUserInput` type and add your fields: + +```graphql +extend input CreateUserInput { + profile: CreateUserProfileInput! +} + +input CreateUserProfileInput { + firstName: String! + lastName: String! +} +``` + +The user will be saved in the db with the profile key set. diff --git a/packages/type-graphql/codegen.yml b/packages/type-graphql/codegen.yml new file mode 100644 index 000000000..7e2a93474 --- /dev/null +++ b/packages/type-graphql/codegen.yml @@ -0,0 +1,14 @@ +overwrite: true +schema: ../graphql-api/src/schema.ts +require: ts-node/register/transpile-only +generates: + ./src/type-graphql.ts: + config: + noNamespaces: true + declarationType: + type: "abstract class" + decoratorName: + type: "InterfaceType" + plugins: + - add: /* tslint:disable */ + - typescript-type-graphql \ No newline at end of file diff --git a/packages/type-graphql/package.json b/packages/type-graphql/package.json new file mode 100644 index 000000000..ef89fcb19 --- /dev/null +++ b/packages/type-graphql/package.json @@ -0,0 +1,51 @@ +{ + "name": "@accounts/type-graphql", + "version": "0.19.0", + "description": "Server side type-graphql objects for accounts", + "main": "lib/index.js", + "typings": "lib/index.d.ts", + "scripts": { + "clean": "rimraf lib", + "start": "gql-gen && tsc --watch", + "precompile": "yarn clean && gql-gen", + "compile": "tsc", + "testonly": "jest", + "coverage": "yarn testonly --coverage", + "prepublishOnly": "yarn compile" + }, + "jest": { + "testEnvironment": "node", + "preset": "ts-jest" + }, + "repository": { + "type": "git", + "url": "https://github.com/accounts-js/accounts/tree/master/packages/type-graphql" + }, + "author": "David Yahalomi", + "license": "MIT", + "bugs": { + "url": "https://github.com/accounts-js/accounts/issues" + }, + "homepage": "https://github.com/accounts-js/accounts", + "devDependencies": { + "@graphql-codegen/add": "^1.7.0", + "@graphql-codegen/cli": "^1.7.0", + "@graphql-codegen/typescript": "^1.7.0", + "@graphql-codegen/typescript-type-graphql": "^1.7.0", + "@types/jest": "24.0.18", + "graphql": "14.5.3", + "graphql-tools": "4.0.5", + "jest": "24.9.0" + }, + "peerDependencies": { + "@accounts/password": "^0.9.3", + "@accounts/server": "^0.9.3", + "@accounts/types": "^0.9.3", + "graphql-tag": "^2.10.0", + "graphql-tools": "^4.0.5" + }, + "dependencies": { + "graphql-toolkit": "^0.5.10", + "type-graphql": "^0.17.5" + } +} diff --git a/packages/type-graphql/src/index.ts b/packages/type-graphql/src/index.ts new file mode 100644 index 000000000..349cc7eed --- /dev/null +++ b/packages/type-graphql/src/index.ts @@ -0,0 +1 @@ +export * from './type-graphql'; diff --git a/packages/type-graphql/src/type-graphql.ts b/packages/type-graphql/src/type-graphql.ts new file mode 100644 index 000000000..a65ea5c00 --- /dev/null +++ b/packages/type-graphql/src/type-graphql.ts @@ -0,0 +1,308 @@ +/* tslint:disable */ +import * as TypeGraphQL from 'type-graphql'; +export type Maybe = T | null; +type FixDecorator = T; +/** All built-in and custom scalars, mapped to their actual values */ +export type Scalars = { + ID: string; + String: string; + Boolean: boolean; + Int: number; + Float: number; +}; + +@TypeGraphQL.InterfaceType() +export class User { + __typename?: 'User'; + + @TypeGraphQL.Field(type => TypeGraphQL.ID) + id!: Scalars['ID']; + + @TypeGraphQL.Field(type => [EmailRecord], { nullable: true }) + emails!: Maybe>; + + @TypeGraphQL.Field(type => String, { nullable: true }) + username!: Maybe; +} + +@TypeGraphQL.InterfaceType() +export class TwoFactorSecretKey { + __typename?: 'TwoFactorSecretKey'; + + @TypeGraphQL.Field(type => String, { nullable: true }) + ascii!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + base32!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + hex!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + qr_code_ascii!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + qr_code_hex!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + qr_code_base32!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + google_auth_qr!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + otpauth_url!: Maybe; +} + +@TypeGraphQL.InterfaceType() +export class Tokens { + __typename?: 'Tokens'; + + @TypeGraphQL.Field(type => String, { nullable: true }) + refreshToken!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + accessToken!: Maybe; +} + +@TypeGraphQL.InterfaceType() +export class LoginResult { + __typename?: 'LoginResult'; + + @TypeGraphQL.Field(type => String, { nullable: true }) + sessionId!: Maybe; + + @TypeGraphQL.Field(type => Tokens, { nullable: true }) + tokens!: Maybe; +} + +@TypeGraphQL.InterfaceType() +export class ImpersonateReturn { + __typename?: 'ImpersonateReturn'; + + @TypeGraphQL.Field(type => Boolean, { nullable: true }) + authorized!: Maybe; + + @TypeGraphQL.Field(type => Tokens, { nullable: true }) + tokens!: Maybe; + + @TypeGraphQL.Field(type => User, { nullable: true }) + user!: Maybe; +} + +@TypeGraphQL.InterfaceType() +export class EmailRecord { + __typename?: 'EmailRecord'; + + @TypeGraphQL.Field(type => String, { nullable: true }) + address!: Maybe; + + @TypeGraphQL.Field(type => Boolean, { nullable: true }) + verified!: Maybe; +} + +@TypeGraphQL.InputType() +export class AuthenticateParamsInput { + @TypeGraphQL.Field(type => String, { nullable: true }) + access_token!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + access_token_secret!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + provider!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + password!: Maybe; + + @TypeGraphQL.Field(type => UserInput, { nullable: true }) + user!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + code!: Maybe; +} + +@TypeGraphQL.InputType() +export class CreateUserInput { + @TypeGraphQL.Field(type => String, { nullable: true }) + username!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + email!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + password!: Maybe; +} + +export class Mutation { + __typename?: 'Mutation'; + + @TypeGraphQL.Field(type => TypeGraphQL.ID, { nullable: true }) + createUser!: Maybe; + + @TypeGraphQL.Field(type => Boolean, { nullable: true }) + verifyEmail!: Maybe; + + @TypeGraphQL.Field(type => LoginResult, { nullable: true }) + resetPassword!: Maybe; + + @TypeGraphQL.Field(type => Boolean, { nullable: true }) + sendVerificationEmail!: Maybe; + + @TypeGraphQL.Field(type => Boolean, { nullable: true }) + sendResetPasswordEmail!: Maybe; + + @TypeGraphQL.Field(type => Boolean, { nullable: true }) + changePassword!: Maybe; + + @TypeGraphQL.Field(type => Boolean, { nullable: true }) + twoFactorSet!: Maybe; + + @TypeGraphQL.Field(type => Boolean, { nullable: true }) + twoFactorUnset!: Maybe; + + @TypeGraphQL.Field(type => ImpersonateReturn, { nullable: true }) + impersonate!: Maybe; + + @TypeGraphQL.Field(type => LoginResult, { nullable: true }) + refreshTokens!: Maybe; + + @TypeGraphQL.Field(type => Boolean, { nullable: true }) + logout!: Maybe; + + @TypeGraphQL.Field(type => LoginResult, { nullable: true }) + authenticate!: Maybe; +} + +@TypeGraphQL.ArgsType() +export class MutationCreateUserArgs { + @TypeGraphQL.Field(type => CreateUserInput) + user!: FixDecorator; +} + +@TypeGraphQL.ArgsType() +export class MutationVerifyEmailArgs { + @TypeGraphQL.Field(type => String) + token!: Scalars['String']; +} + +@TypeGraphQL.ArgsType() +export class MutationResetPasswordArgs { + @TypeGraphQL.Field(type => String) + token!: Scalars['String']; + + @TypeGraphQL.Field(type => String) + newPassword!: Scalars['String']; +} + +@TypeGraphQL.ArgsType() +export class MutationSendVerificationEmailArgs { + @TypeGraphQL.Field(type => String) + email!: Scalars['String']; +} + +@TypeGraphQL.ArgsType() +export class MutationSendResetPasswordEmailArgs { + @TypeGraphQL.Field(type => String) + email!: Scalars['String']; +} + +@TypeGraphQL.ArgsType() +export class MutationChangePasswordArgs { + @TypeGraphQL.Field(type => String) + oldPassword!: Scalars['String']; + + @TypeGraphQL.Field(type => String) + newPassword!: Scalars['String']; +} + +@TypeGraphQL.ArgsType() +export class MutationTwoFactorSetArgs { + @TypeGraphQL.Field(type => TwoFactorSecretKeyInput) + secret!: FixDecorator; + + @TypeGraphQL.Field(type => String) + code!: Scalars['String']; +} + +@TypeGraphQL.ArgsType() +export class MutationTwoFactorUnsetArgs { + @TypeGraphQL.Field(type => String) + code!: Scalars['String']; +} + +@TypeGraphQL.ArgsType() +export class MutationImpersonateArgs { + @TypeGraphQL.Field(type => String) + accessToken!: Scalars['String']; + + @TypeGraphQL.Field(type => String) + username!: Scalars['String']; +} + +@TypeGraphQL.ArgsType() +export class MutationRefreshTokensArgs { + @TypeGraphQL.Field(type => String) + accessToken!: Scalars['String']; + + @TypeGraphQL.Field(type => String) + refreshToken!: Scalars['String']; +} + +@TypeGraphQL.ArgsType() +export class MutationAuthenticateArgs { + @TypeGraphQL.Field(type => String) + serviceName!: Scalars['String']; + + @TypeGraphQL.Field(type => AuthenticateParamsInput) + params!: FixDecorator; +} + +export class Query { + __typename?: 'Query'; + + @TypeGraphQL.Field(type => TwoFactorSecretKey, { nullable: true }) + twoFactorSecret!: Maybe; + + @TypeGraphQL.Field(type => User, { nullable: true }) + getUser!: Maybe; +} + +@TypeGraphQL.InputType() +export class TwoFactorSecretKeyInput { + @TypeGraphQL.Field(type => String, { nullable: true }) + ascii!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + base32!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + hex!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + qr_code_ascii!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + qr_code_hex!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + qr_code_base32!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + google_auth_qr!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + otpauth_url!: Maybe; +} + +@TypeGraphQL.InputType() +export class UserInput { + @TypeGraphQL.Field(type => TypeGraphQL.ID, { nullable: true }) + id!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + email!: Maybe; + + @TypeGraphQL.Field(type => String, { nullable: true }) + username!: Maybe; +} diff --git a/packages/type-graphql/tsconfig.json b/packages/type-graphql/tsconfig.json new file mode 100644 index 000000000..512450c8e --- /dev/null +++ b/packages/type-graphql/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "noUnusedParameters": false, + "noUnusedLocals": false, + "noImplicitAny": false, + "experimentalDecorators": true, + "importHelpers": true + }, + "exclude": ["node_modules", "__tests__", "lib"] +}