react-form-action 2.4.0 → 2.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -0
- package/dist/chunk-LPB4R2UB.mjs +1 -0
- package/dist/client.d.mts +2 -5
- package/dist/client.mjs +1 -1
- package/dist/{createFormAction-CX4Fk5xA.d.mts → createFormAction-DjhozgiG.d.mts} +7 -3
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-HL47DG4L.mjs +0 -1
package/README.md
CHANGED
|
@@ -8,6 +8,7 @@ End-to-end typesafe success, error & validation state control for Next.js form a
|
|
|
8
8
|
|
|
9
9
|
- ✅ Provides envelope objects with `"initial" | "invalid" | "success" | "failure"` response types.
|
|
10
10
|
- ✅ Define generic payload for each of the response type.
|
|
11
|
+
- ✅ Bind action arguments.
|
|
11
12
|
|
|
12
13
|
**tRPC-like Form Action builder**
|
|
13
14
|
|
|
@@ -250,6 +251,45 @@ export const updateUser = createFormAction<
|
|
|
250
251
|
);
|
|
251
252
|
```
|
|
252
253
|
|
|
254
|
+
The action creator supports arguments binding:
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
export const updateUser = createFormAction(
|
|
258
|
+
(
|
|
259
|
+
{ success, failure, invalid },
|
|
260
|
+
userId: string /* Here you can specify multiple arguments */
|
|
261
|
+
) =>
|
|
262
|
+
async (prevState, formData) => {
|
|
263
|
+
try {
|
|
264
|
+
const { name } = updateUserSchema.parse({
|
|
265
|
+
name: formData.get("name"),
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
const user = await db.users.findById(userId);
|
|
269
|
+
|
|
270
|
+
if (!user) {
|
|
271
|
+
return failure({ message: "No such user." });
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const updated = await user.update({ name });
|
|
275
|
+
|
|
276
|
+
if (updated) {
|
|
277
|
+
return success({
|
|
278
|
+
message: "User has been updated.",
|
|
279
|
+
});
|
|
280
|
+
} else {
|
|
281
|
+
return failure({ message: "Failed to update." });
|
|
282
|
+
}
|
|
283
|
+
} catch (error) {
|
|
284
|
+
// handle error
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
// call bind as usuall, the "123" becomes the "userId"
|
|
290
|
+
updateUser.bind(null, "123");
|
|
291
|
+
```
|
|
292
|
+
|
|
253
293
|
### Action Context
|
|
254
294
|
|
|
255
295
|
The `<Action>` components enables you to access your `action`'s state with the `useActionContext()` hook:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function u(a){return{type:"initial",data:a,error:null,validationError:null}}function d(a){function t(r){return{type:"success",data:r,error:null,validationError:null}}function o(r){return{type:"failure",data:null,error:r,validationError:null}}function n(r){return{type:"invalid",data:null,error:null,validationError:r}}return(...r)=>{let e=r.pop(),i=r.pop(),l=[...r];return a({success:t,failure:o,invalid:n},...l)(i,e)}}export{u as a,d as b};
|
package/dist/client.d.mts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import React__default, { PropsWithChildren, JSX } from 'react';
|
|
3
|
-
import { F as FormAction, A as ActionState, I as InitialState, a as InvalidState, b as FailureState, S as SuccessState } from './createFormAction-
|
|
3
|
+
import { F as FormAction, A as ActionState, I as InitialState, a as InvalidState, b as FailureState, S as SuccessState } from './createFormAction-DjhozgiG.mjs';
|
|
4
4
|
import { ZodFormattedError } from 'zod';
|
|
5
5
|
import { RenderProp, RP } from 'react-render-prop-type';
|
|
6
|
-
import { useFormStatus } from 'react-dom';
|
|
7
6
|
|
|
8
7
|
type ActionProps<Data, Error, ValidationError> = PropsWithChildren<{
|
|
9
8
|
action: FormAction<Data, Error, ValidationError>;
|
|
@@ -79,8 +78,6 @@ declare function createComponents<Data, Error, ValidationError extends ZodFormat
|
|
|
79
78
|
}>) => React__default.ReactNode;
|
|
80
79
|
};
|
|
81
80
|
|
|
82
|
-
declare function FormStatus({ children, }: RenderProp<ReturnType<typeof useFormStatus>>): React.ReactNode;
|
|
83
|
-
|
|
84
81
|
/**
|
|
85
82
|
* Conditionally renders the children, when the form action is in the "pending" state.
|
|
86
83
|
*/
|
|
@@ -88,4 +85,4 @@ declare function Pending({ children, }: PropsWithChildren | RP<{
|
|
|
88
85
|
isPending: boolean;
|
|
89
86
|
}>): React.ReactNode;
|
|
90
87
|
|
|
91
|
-
export { Action, type ActionContextState, type ActionProps, Form, type FormProps,
|
|
88
|
+
export { Action, type ActionContextState, type ActionProps, Form, type FormProps, type InferZodErrorPaths, type Paths, Pending, ZodFieldError, type ZodFieldErrorChildrenProps, type ZodFieldErrorProps, createComponents, noError, useActionContext };
|
package/dist/client.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{a as m}from"./chunk-
|
|
1
|
+
"use client";import{a as m}from"./chunk-LPB4R2UB.mjs";import y from"react";import{createContext as P,use as S}from"react";import{useActionState as F}from"react";var p={isInitial:!1,isInvalid:!1,isFailure:!1,isSuccess:!1},u=P(null);function a(o){let t=S(u);if(!t)throw new Error("ActionContext must be initialized before use. Is your useActionContext hook wrapped with an <Action> Component?");return t}function I({children:o,action:t,initialData:i,permalink:e}){let[r,n,s]=F(t,m(i),e),l=r.type==="initial"?{...r,...p,action:n,isPending:s,isInitial:!0}:r.type==="invalid"?{...r,...p,action:n,isPending:s,isInvalid:!0}:r.type==="failure"?{...r,...p,action:n,isPending:s,isFailure:!0}:{...r,...p,action:n,isPending:s,isSuccess:!0};return y.createElement(u,{value:l},o)}import A,{startTransition as C}from"react";function V({autoReset:o=!1,...t}){let{action:i}=a();return A.createElement("form",{...o?{action:i}:{onSubmit:r=>{r.preventDefault();let n=r.currentTarget;C(()=>{i(new FormData(n))})}},...t})}import c from"react";import f from"react";var h=".",d=Object.freeze({_errors:Object.freeze([])});function E({errors:o,name:t,children:i=({error:e})=>f.createElement(f.Fragment,null,e)}){if(t.length===0)return i({name:t,error:o._errors[0],errors:o._errors});let e=t.split(h),r=o;for(;e.length;){let n=e.shift();r=r[n]??d}return i({name:t,error:r._errors[0],errors:r._errors})}function $(o){function t({name:e,children:r}){let{isInvalid:n,validationError:s}=a(o);return c.createElement(E,{errors:s??d,name:e},r??(({error:x})=>n&&c.createElement(c.Fragment,null,x)))}function i({children:e}){let{isSuccess:r,data:n}=a(o);return typeof e=="function"?e(r?{isSuccess:r,data:n}:{isSuccess:r,data:n}):r&&e}return{FieldError:t,Success:i}}function X({children:o}){let{isPending:t}=a();return typeof o=="function"?o({isPending:t}):t&&o}export{I as Action,V as Form,X as Pending,E as ZodFieldError,$ as createComponents,d as noError,a as useActionContext};
|
|
@@ -23,12 +23,16 @@ type SuccessState<T> = {
|
|
|
23
23
|
validationError: null;
|
|
24
24
|
};
|
|
25
25
|
type ActionState<Data, Error, ValidationError = Record<string, never>> = InitialState<Data> | InvalidState<ValidationError> | FailureState<Error> | SuccessState<Data>;
|
|
26
|
-
type FormAction<Data, Error = Data, ValidationError = Record<string, never>, Payload = FormData
|
|
26
|
+
type FormAction<Data, Error = Data, ValidationError = Record<string, never>, Payload = FormData, Arguments extends unknown[] = []> = (...args: [
|
|
27
|
+
...Arguments,
|
|
28
|
+
state: ActionState<Data, Error, ValidationError>,
|
|
29
|
+
payload: Payload
|
|
30
|
+
]) => Promise<ActionState<Data, Error, ValidationError>>;
|
|
27
31
|
declare function initial<Data>(data: Data): InitialState<Data>;
|
|
28
|
-
declare function createFormAction<Data, Error = Data, ValidationError = Record<string, never>, Payload = FormData>(formAction: (params: {
|
|
32
|
+
declare function createFormAction<Data, Error = Data, ValidationError = Record<string, never>, Payload = FormData, Arguments extends [...unknown[]] = []>(formAction: (params: {
|
|
29
33
|
success: (data: Data) => SuccessState<Data>;
|
|
30
34
|
failure: (error: Error) => FailureState<Error>;
|
|
31
35
|
invalid: (validationError: ValidationError) => InvalidState<ValidationError>;
|
|
32
|
-
}) => FormAction<Data, Error, ValidationError, Payload>): (state: ActionState<Data, Error, ValidationError>, payload: Payload) => Promise<ActionState<Data, Error, ValidationError>>;
|
|
36
|
+
}, ...args: Arguments) => FormAction<Data, Error, ValidationError, Payload>): (...args: [...Arguments, state: ActionState<Data, Error, ValidationError>, payload: Payload]) => Promise<ActionState<Data, Error, ValidationError>>;
|
|
33
37
|
|
|
34
38
|
export { type ActionState as A, type FormAction as F, type InitialState as I, type SuccessState as S, type InvalidState as a, type FailureState as b, createFormAction as c, initial as i };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as ActionState, a as InvalidState, b as FailureState, S as SuccessState } from './createFormAction-
|
|
2
|
-
export { F as FormAction, I as InitialState, c as createFormAction, i as initial } from './createFormAction-
|
|
1
|
+
import { A as ActionState, a as InvalidState, b as FailureState, S as SuccessState } from './createFormAction-DjhozgiG.mjs';
|
|
2
|
+
export { F as FormAction, I as InitialState, c as createFormAction, i as initial } from './createFormAction-DjhozgiG.mjs';
|
|
3
3
|
import { ZodTypeAny, ZodType, ZodObject, ZodRawShape, objectUtil, z, ZodSchema, ZodEffects } from 'zod';
|
|
4
4
|
|
|
5
5
|
declare const emptyInput: unique symbol;
|
|
@@ -34,7 +34,7 @@ type FormActionBuilder<Schema extends ZodTypeAny | EmptyInput, Err = Error, Cont
|
|
|
34
34
|
* @param action async function to execute. It will receive parsed formData as input, when the builder was initialized with a schema.
|
|
35
35
|
* @returns runnable server action exportable from a module.
|
|
36
36
|
*/
|
|
37
|
-
run: Schema extends ZodTypeAny ? <Data>(action: SchemaAction<Data, Context
|
|
37
|
+
run: Schema extends ZodTypeAny ? <Data>(action: SchemaAction<Data, Flatten<Context>, Schema>) => (state: ActionState<Data, Err, z.inferFormattedError<Schema>>, payload: FormData) => Promise<Flatten<InvalidState<z.inferFormattedError<Schema>> | FailureState<Err> | SuccessState<Data>>> : <Data>(action: Action<Data, Flatten<Context>>) => (state: ActionState<Data, Err>, payload: FormData) => Promise<Flatten<FailureState<Err> | SuccessState<Data>>>;
|
|
38
38
|
/**
|
|
39
39
|
* A chainable context enhancing helper.
|
|
40
40
|
* @param middleware A function which receives the current context, and returns an object which will be added to the context.
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as A,b as p}from"./chunk-
|
|
1
|
+
import{a as A,b as p}from"./chunk-LPB4R2UB.mjs";import{ZodFirstPartyTypeKind as E}from"zod";import{zfd as C}from"zod-form-data";var d=Symbol();function i(r,o=[],n){async function f(t){let e={formData:t};for(let a of o){let s=await a({ctx:e});e={...e,...s}}return e}return{input(t){if(r===d)return i(t,o,n);if(r._def.effect)throw new Error("Previous input is not augmentable because it contains an effect.");if(t._def.effect)throw new Error("Your input contains effect which prevents merging it with the previous inputs.");if(r._def.typeName===E.ZodObject){let e=r.merge(t);return i(e,o)}else throw Error("Merging inputs works only for object schemas without effects.")},use(t){return i(r,[...o,t],n)},error(t){return i(r,o,t)},run:r===d?t=>p(({success:e,failure:a})=>async(s,m)=>{let x=await f(m);try{return e(await t({ctx:x}))}catch(c){if(n)return a(await n({error:c,ctx:x}));throw c}}):r===d?void 0:t=>p(({success:e,failure:a,invalid:s})=>{let m=C.formData(r);return async(x,c)=>{let y=await f(c),u=m.safeParse(c);if(!u.success)return s(u.error.format());let h=u.data;try{return e(await t({input:h,ctx:y}))}catch(S){if(n)return a(await n({error:S,ctx:y}));throw S}}})}}var P=i(d);export{p as createFormAction,P as formAction,A as initial};
|
package/package.json
CHANGED
package/dist/chunk-HL47DG4L.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
function l(a){return{type:"initial",data:a,error:null,validationError:null}}function n(a){function t(r){return{type:"success",data:r,error:null,validationError:null}}function o(r){return{type:"failure",data:null,error:r,validationError:null}}function i(r){return{type:"invalid",data:null,error:null,validationError:r}}return(r,e)=>a({success:t,failure:o,invalid:i})(r,e)}export{l as a,n as b};
|