import { Resource } from './resource' ; import { getClient } from './client' ; import { isDestroyed , isDestroying , tracked , waitForPromise } from '../environment' ; import { ApolloError } from '@apollo/client/core' ; import { settled } from './utils' ; import type { DocumentNode , FetchResult , MutationOptions as ApolloMutationOptions , OperationVariables } from '@apollo/client/core' ; import type { TemplateArgs } from './types' ; type Maybe < T > = T | undefined | null ; interface MutationOptions < TData , TVariables > extends Omit < ApolloMutationOptions < TData , TVariables > , 'mutation' > { clientId ? : string ; onComplete ? : ( data : Maybe < TData > ) => void ; onError ? : ( error : ApolloError ) => void ; } export type MutationPositionalArgs < TData , TVariables = OperationVariables > = [ DocumentNode , MutationOptions < TData , TVariables > ? ] ; export class MutationResource < TData , TVariables = OperationVariables > extends Resource < TemplateArgs < MutationPositionalArgs < TData , TVariables > > > { @ tracked loading = false ; @ tracked called = false ; @ tracked error ? : ApolloError ; @ tracked data : Maybe < TData > ; @ tracked promise ! : Promise < Maybe < TData > > ; async mutate ( variables ? , overrideOptions = { } ) { this . loading = true ; const [ mutation , originalOptions ] = this . args . positional ; const options = { ... originalOptions , ... overrideOptions } ; const client = getClient ( this , options . clientId ) ; if ( ! variables ) { variables = originalOptions ?. variables ; } else if ( variables && originalOptions ?. variables ) { variables = { ... originalOptions . variables , ... variables } ; } this . promise = waitForPromise ( client . mutate < TData , TVariables > ( { mutation , ... options , variables } ) ) . then ( ( result ) => { this . #onComplete ( result ) ; return this . data ; } ) . catch ( ( error ) => { this . #onError ( error ) ; return error ; } ) ; return this . promise ; } settled ( ) { return settled ( this . promise ) ; } #onComplete ( result ) { const { data , errors } = result ; const error = errors && errors . length > 0 ? new ApolloError ( { graphQLErrors : errors } ) : undefined ; this . data = data ; this . error = error ; this . #handleOnCompleteOrOnError ( ) ; } #onError ( error ) { this . error = error ; this . data = undefined ; this . #handleOnCompleteOrOnError ( ) ; } #handleOnCompleteOrOnError ( ) { this . loading = false ; this . called = true ; if ( isDestroyed ( this ) || isDestroying ( this ) ) { return ; } const [ , options ] = this . args . positional ; const { onComplete , onError } = options || { } ; const { data , error } = this ; if ( onComplete && ! error ) { onComplete ( data ) ; } else if ( onError && error ) { onError ( error ) ; } } }