Skip to content

Commit

Permalink
fix(core): types
Browse files Browse the repository at this point in the history
  • Loading branch information
alicanerdurmaz committed Jul 9, 2024
1 parent c62ed1f commit 2758979
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 83 deletions.
52 changes: 27 additions & 25 deletions packages/core/src/definitions/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
import type { UseMutationResult as UseMutationResultBase } from "@tanstack/react-query";
import type {
MutateOptions,
UseMutationResult as UseMutationResultBase,
} from "@tanstack/react-query";

export type Override<A, B> = {
[K in keyof A]: K extends keyof B ? B[K] : A[K];
};

// Type to make array elements optional
export type PartialArray<T extends unknown[]> = {
[K in keyof T]?: T[K];
};
export type MutateAsyncFunction<
TData = unknown,
TError = unknown,
TVariables = void,
TContext = unknown,
> = (
variables?: TVariables,
options?: MutateOptions<TData, TError, TVariables, TContext>,
) => Promise<TData>;

// Type to make function arguments optional
export type MakeFunctionArgsOptional<T> = T extends (
...args: infer P
) => infer R
? (...args: PartialArray<P>) => R
: never;
export type MutateFunction<
TData = unknown,
TError = unknown,
TVariables = void,
TContext = unknown,
> = (
...args: Parameters<MutateAsyncFunction<TData, TError, TVariables, TContext>>
) => void;

/**
* we want to make the mutate and mutateAsync functions optional in the UseMutationResult
Expand All @@ -25,14 +31,10 @@ export type UseMutationResult<
TError = unknown,
TVariables = unknown,
TContext = unknown,
> = Override<
> = Omit<
UseMutationResultBase<TData, TError, TVariables, TContext>,
{
mutate: MakeFunctionArgsOptional<
UseMutationResultBase<TData, TError, TVariables, TContext>["mutate"]
>;
mutateAsync: MakeFunctionArgsOptional<
UseMutationResultBase<TData, TError, TVariables, TContext>["mutateAsync"]
>;
}
>;
"mutate" | "mutateAsync"
> & {
mutate: MutateFunction<TData, TError, TVariables, TContext>;
mutateAsync: MutateAsyncFunction<TData, TError, TVariables, TContext>;
};
91 changes: 33 additions & 58 deletions packages/core/src/hooks/form/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import {
pickNotDeprecated,
} from "@definitions/helpers";

import type { UpdateParams } from "../data/useUpdate";
import type { UseCreateParams } from "../data/useCreate";
import type { UseFormProps, UseFormReturnType } from "./types";
import type {
BaseKey,
Expand Down Expand Up @@ -244,7 +246,9 @@ export const useForm = <
resolve();
}

const variables = {
const variables:
| UpdateParams<TResponse, TResponseError, TVariables>
| UseCreateParams<TResponse, TResponseError, TVariables> = {
values,
resource: identifier ?? resource.name,
meta: { ...combinedMeta, ...props.mutationMeta },
Expand All @@ -262,65 +266,36 @@ export const useForm = <
optimisticUpdateMap: props.optimisticUpdateMap,
}
: {}),
} as const;

if (isEdit) {
updateMutation
.mutateAsync(variables, {
// Call user-defined `onMutationSuccess` and `onMutationError` callbacks if provided
// These callbacks will not have an effect on the submission promise
onSuccess: props.onMutationSuccess
? (data, _, context) => {
props.onMutationSuccess?.(data, values, context, isAutosave);
}
: undefined,
onError: props.onMutationError
? (error: TResponseError, _, context) => {
props.onMutationError?.(error, values, context, isAutosave);
}
: undefined,
})
// If the mutation mode is pessimistic, resolve the promise after the mutation is succeeded
.then((data) => {
if (isPessimistic && !isAutosave) {
deferExecution(() => onSuccessRedirect(data?.data?.id));
}
if (isAutosave) {
setAutosaved(true);
}
resolve(data);
})
// If the mutation mode is pessimistic, reject the promise after the mutation is failed
.catch(reject);
} else {
createMutation
.mutateAsync(variables, {
// Call user-defined `onMutationSuccess` and `onMutationError` callbacks if provided
// These callbacks will not have an effect on the submission promise
onSuccess: props.onMutationSuccess
? (data, _, context) => {
props.onMutationSuccess?.(data, values, context, isAutosave);
}
: undefined,
onError: props.onMutationError
? (error: TResponseError, _, context) => {
props.onMutationError?.(error, values, context, isAutosave);
}
: undefined,
})
// If the mutation mode is pessimistic, resolve the promise after the mutation is succeeded
.then((data) => {
if (isPessimistic && !isAutosave) {
deferExecution(() => onSuccessRedirect(data?.data?.id));
};

const { mutateAsync } = isEdit ? updateMutation : createMutation;

mutateAsync(variables as any, {
// Call user-defined `onMutationSuccess` and `onMutationError` callbacks if provided
// These callbacks will not have an effect on the submission promise
onSuccess: props.onMutationSuccess
? (data, _, context) => {
props.onMutationSuccess?.(data, values, context, isAutosave);
}
if (isAutosave) {
setAutosaved(true);
: undefined,
onError: props.onMutationError
? (error: TResponseError, _, context) => {
props.onMutationError?.(error, values, context, isAutosave);
}
resolve(data);
})
// If the mutation mode is pessimistic, reject the promise after the mutation is failed
.catch(reject);
}
: undefined,
})
// If the mutation mode is pessimistic, resolve the promise after the mutation is succeeded
.then((data) => {
if (isPessimistic && !isAutosave) {
deferExecution(() => onSuccessRedirect(data?.data?.id));
}
if (isAutosave) {
setAutosaved(true);
}
resolve(data);
})
// If the mutation mode is pessimistic, reject the promise after the mutation is failed
.catch(reject);
});

return submissionPromise;
Expand Down

0 comments on commit 2758979

Please sign in to comment.