@paragrav/rhf-utils 0.66.0 → 0.67.0

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.
@@ -0,0 +1,56 @@
1
+ import { a as RhfUtilsFormOptions, i as SafeFieldValues } from "./RhfUtilsContextType-BFmDtONY.js";
2
+ import { n as FormRelay, r as FormRelayStateSelected, t as FormRelayOptions } from "./FormRelayOptions-mBqiP41Z.js";
3
+ import React$1 from "react";
4
+ import { FormState } from "react-hook-form";
5
+
6
+ //#region src/form/relay/context/FormRelayContextProvider.d.ts
7
+ type Props$1 = React$1.PropsWithChildren;
8
+ declare const FormRelayContextProvider: React$1.FC<Props$1>;
9
+ //#endregion
10
+ //#region src/form/relay/get/FormRelayGroupType.d.ts
11
+ type FormRelayGroup = Partial<Omit<FormState<SafeFieldValues>, 'defaultValues' | 'dirtyFields' | 'touchedFields' | 'validatingFields' | 'errors' | 'submitErrors'> & {
12
+ hasErrors: boolean;
13
+ hasDirtyFields: boolean;
14
+ hasTouchedFields: boolean;
15
+ hasValidatingFields: boolean; /** Sum of all submit counts. */
16
+ submitCount: number;
17
+ /**
18
+ * Consider form flagged when mounted.
19
+ *
20
+ * (To use, return via `FormRelayOptions`'s `select`'s return's `FormRelayStateSelected`'s `isMounted` property.)
21
+ */
22
+ isMounted: boolean;
23
+ }>;
24
+ //#endregion
25
+ //#region src/form/relay/get/grouper/useFirstFormStateGroup.d.ts
26
+ /**
27
+ * Use this when you don't (want to) know whether component is wrapped
28
+ * with RHF context, `FormRelayGrouperContext`, or `FormRelayContext`.
29
+ * Will return `FormRelayGroup`, regardless.
30
+ *
31
+ * Allows you to build naive components that are not tied to one specific context.
32
+ */
33
+ declare const useFirstFormStateGroup: () => FormRelayGroup;
34
+ //#endregion
35
+ //#region src/form/relay/get/useFormRelay.d.ts
36
+ declare const useFormRelayId: (formId: string) => FormRelay | undefined;
37
+ type FormRelayGroupCriteria = {
38
+ groups: string[];
39
+ } | {
40
+ predicate: (context: {
41
+ groups: FormRelayOptions['groups'];
42
+ options: RhfUtilsFormOptions;
43
+ }) => boolean;
44
+ };
45
+ declare const useFormRelayGroup: (criteria?: FormRelayGroupCriteria) => FormRelayGroup;
46
+ //#endregion
47
+ //#region src/form/relay/set/FormRelaySetter.d.ts
48
+ type Props = {
49
+ options?: FormRelayOptions;
50
+ };
51
+ declare const FormRelaySetter: React.FC<Props>;
52
+ //#endregion
53
+ //#region src/form/relay/set/useFormRelaySet.d.ts
54
+ declare const useFormRelaySet: (options?: FormRelayOptions) => void;
55
+ //#endregion
56
+ export { type FormRelay, FormRelayContextProvider, type FormRelayGroup, FormRelaySetter, type FormRelayStateSelected, useFirstFormStateGroup, useFormRelayGroup, useFormRelayId, useFormRelaySet };
@@ -0,0 +1,71 @@
1
+ import { c as FormRelayContextProvider, i as isEmptyObject, l as useFormRelayContext, n as useFormRelaySet, s as useRhfUtilsMaybeContext, t as FormRelaySetter, u as createContext } from "./FormRelaySetter-BKO0Wodf.js";
2
+ import React from "react";
3
+ import { useFormState } from "react-hook-form";
4
+ //#region src/form/relay/context/utils.ts
5
+ /** Condense list of form states to singular booleans. */
6
+ const getFormRelayedAggregatedByRelayedItem = (formStates) => formStates.reduce((acc, curr) => ({
7
+ isDirty: acc.isDirty || curr.isDirty,
8
+ isSubmitting: acc.isSubmitting || curr.isSubmitting,
9
+ isLoading: acc.isLoading || curr.isLoading,
10
+ isSubmitted: acc.isSubmitted || curr.isSubmitted,
11
+ isSubmitSuccessful: acc.isSubmitSuccessful || curr.isSubmitSuccessful,
12
+ isValidating: acc.isValidating || curr.isValidating,
13
+ isValid: acc.isValid || curr.isValid,
14
+ isReady: acc.isReady || curr.isReady,
15
+ disabled: acc.disabled || curr.disabled,
16
+ hasErrors: acc.hasErrors || curr.errors && !isEmptyObject(curr.errors),
17
+ hasDirtyFields: acc.hasDirtyFields || curr.dirtyFields && !isEmptyObject(curr.dirtyFields),
18
+ hasTouchedFields: acc.hasTouchedFields || curr.touchedFields && !isEmptyObject(curr.touchedFields),
19
+ hasValidatingFields: acc.hasValidatingFields || curr.validatingFields && !isEmptyObject(curr.validatingFields),
20
+ submitCount: (acc.submitCount ?? 0) + (curr.submitCount ?? 0),
21
+ isMounted: acc.isMounted || curr.isMounted
22
+ }), {
23
+ isDirty: void 0,
24
+ isSubmitting: void 0,
25
+ isLoading: void 0,
26
+ isSubmitted: void 0,
27
+ isSubmitSuccessful: void 0,
28
+ isValidating: void 0,
29
+ isReady: void 0,
30
+ isValid: void 0,
31
+ disabled: void 0,
32
+ hasErrors: void 0,
33
+ hasDirtyFields: void 0,
34
+ hasTouchedFields: void 0,
35
+ hasValidatingFields: void 0,
36
+ submitCount: void 0,
37
+ isMounted: void 0
38
+ });
39
+ //#endregion
40
+ //#region src/form/relay/get/useFormRelay.ts
41
+ const useFormRelayId = (formId) => useFormRelayContext().state[formId];
42
+ const useFormRelayGroup = (criteria) => {
43
+ const relayState = useFormRelayContext().state;
44
+ const state = getFormRelayedAggregatedByRelayedItem(getFormRelaysByCriteria(relayState, criteria).map(({ state }) => state));
45
+ const jsonState = JSON.stringify(state);
46
+ return React.useMemo(() => state, [jsonState]);
47
+ };
48
+ const getFormRelaysByCriteria = (relayState, criteria) => Object.values(relayState).filter(({ options, utils }) => !criteria || "groups" in criteria && criteria.groups.filter((group) => options.groups?.includes(group)).length || "predicate" in criteria && criteria.predicate({
49
+ groups: options.groups,
50
+ options: utils.options
51
+ }));
52
+ //#endregion
53
+ //#region src/form/relay/get/grouper/context/index.ts
54
+ const { Provider: _FormRelayGrouperContextProvider, useRequired: _useFormRelayGrouperContext, useMaybe: _useFormRelayGrouperMaybeContext } = createContext();
55
+ //#endregion
56
+ //#region src/form/relay/get/grouper/useFirstFormStateGroup.ts
57
+ /**
58
+ * Use this when you don't (want to) know whether component is wrapped
59
+ * with RHF context, `FormRelayGrouperContext`, or `FormRelayContext`.
60
+ * Will return `FormRelayGroup`, regardless.
61
+ *
62
+ * Allows you to build naive components that are not tied to one specific context.
63
+ */
64
+ const useFirstFormStateGroup = () => {
65
+ if (useRhfUtilsMaybeContext()) return getFormRelayedAggregatedByRelayedItem([useFormState()]);
66
+ const maybeRelayCtx = _useFormRelayGrouperMaybeContext();
67
+ if (maybeRelayCtx) return maybeRelayCtx.state;
68
+ return useFormRelayGroup();
69
+ };
70
+ //#endregion
71
+ export { FormRelayContextProvider, FormRelaySetter, useFirstFormStateGroup, useFormRelayGroup, useFormRelayId, useFormRelaySet };
@@ -0,0 +1,36 @@
1
+ import { c as FormSubmitFieldErrors, t as RhfUtilsClientConfig } from "./RhfUtilsClientConfigType-CeOJzNAc.js";
2
+ import { TRPCClientErrorLike } from "@trpc/client";
3
+ import { z } from "zod";
4
+ import { AnyTRPCRouter } from "@trpc/server";
5
+
6
+ //#region src/errors/trpc/makeOnSubmitTrpcClientErrorHandler.d.ts
7
+ /**
8
+ * HOF that returns submit error handler for {@link RhfUtilsClientConfig.onSubmitErrorUnknown}.
9
+ *
10
+ * @param onError Fallback for handling non-TRPC errors.
11
+ * @returns FormSubmitError
12
+ */
13
+ declare const makeOnSubmitTrpcClientErrorHandler: (onNotTrpcClientError: NonNullable<RhfUtilsClientConfig["onSubmitErrorUnknown"]>) => (error: unknown) => FormSubmitFieldErrors | undefined;
14
+ //#endregion
15
+ //#region src/errors/trpc/trpcClientErrorToFormSubmitFieldErrorsSchemaTransformer.d.ts
16
+ /**
17
+ * Schema that transforms {@link TRPCClientError} to RHF {@link FormSubmitFieldErrors}.
18
+ */
19
+ declare const trpcClientErrorToFormSubmitFieldErrorsSchemaTransformer: z.ZodEffects<z.ZodEffects<z.ZodPipeline<z.ZodEffects<z.ZodEffects<z.ZodType<TRPCClientErrorLike<AnyTRPCRouter>, z.ZodTypeDef, TRPCClientErrorLike<AnyTRPCRouter>>, string, TRPCClientErrorLike<AnyTRPCRouter>>, unknown, TRPCClientErrorLike<AnyTRPCRouter>>, z.ZodArray<z.ZodObject<{
20
+ code: z.ZodString;
21
+ message: z.ZodString;
22
+ path: z.ZodArray<z.ZodString, "many">;
23
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
24
+ code: z.ZodString;
25
+ message: z.ZodString;
26
+ path: z.ZodArray<z.ZodString, "many">;
27
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
28
+ code: z.ZodString;
29
+ message: z.ZodString;
30
+ path: z.ZodArray<z.ZodString, "many">;
31
+ }, z.ZodTypeAny, "passthrough">>, "many">>, (readonly [string, {
32
+ type: string;
33
+ message: string;
34
+ }])[], TRPCClientErrorLike<AnyTRPCRouter>>, FormSubmitFieldErrors, TRPCClientErrorLike<AnyTRPCRouter>>;
35
+ //#endregion
36
+ export { makeOnSubmitTrpcClientErrorHandler, trpcClientErrorToFormSubmitFieldErrorsSchemaTransformer };
@@ -0,0 +1,47 @@
1
+ import { TRPCClientError } from "@trpc/client";
2
+ import { z } from "zod";
3
+ //#region src/errors/trpc/trpcClientErrorMessageSchema.ts
4
+ /**
5
+ * Schema for {@link TRPCClientError} message.
6
+ *
7
+ * (Sent from backend as JSON string.)
8
+ */
9
+ const trpcClientErrorMessageSchema = z.object({
10
+ code: z.string(),
11
+ message: z.string(),
12
+ path: z.array(z.string())
13
+ }).passthrough();
14
+ //#endregion
15
+ //#region src/errors/trpc/trpcClientErrorToFormSubmitFieldErrorsSchemaTransformer.ts
16
+ /**
17
+ * Schema that transforms {@link TRPCClientError} to RHF {@link FormSubmitFieldErrors}.
18
+ */
19
+ const trpcClientErrorToFormSubmitFieldErrorsSchemaTransformer = z.custom((error) => error instanceof TRPCClientError).transform((error) => error.message).transform((json) => {
20
+ try {
21
+ return JSON.parse(json);
22
+ } catch (error) {
23
+ return [{
24
+ validation: "root",
25
+ code: "server",
26
+ message: json,
27
+ path: ["root"]
28
+ }];
29
+ }
30
+ }).pipe(z.array(trpcClientErrorMessageSchema)).transform((errors) => errors.map((error) => [error.path.join("."), {
31
+ type: error.code,
32
+ message: error.message
33
+ }])).transform((errors) => Object.fromEntries(errors));
34
+ //#endregion
35
+ //#region src/errors/trpc/makeOnSubmitTrpcClientErrorHandler.ts
36
+ /**
37
+ * HOF that returns submit error handler for {@link RhfUtilsClientConfig.onSubmitErrorUnknown}.
38
+ *
39
+ * @param onError Fallback for handling non-TRPC errors.
40
+ * @returns FormSubmitError
41
+ */
42
+ const makeOnSubmitTrpcClientErrorHandler = (onNotTrpcClientError) => (error) => {
43
+ if (error instanceof TRPCClientError) return trpcClientErrorToFormSubmitFieldErrorsSchemaTransformer.parse(error);
44
+ return onNotTrpcClientError(error);
45
+ };
46
+ //#endregion
47
+ export { makeOnSubmitTrpcClientErrorHandler, trpcClientErrorToFormSubmitFieldErrorsSchemaTransformer };
package/package.json CHANGED
@@ -1,13 +1,12 @@
1
1
  {
2
2
  "name": "@paragrav/rhf-utils",
3
3
  "author": "paragrav.dev",
4
- "version": "0.66.0",
4
+ "version": "0.67.0",
5
5
  "description": "Integration utilities for react-hook-form.",
6
6
  "type": "module",
7
7
  "sideEffects": false,
8
8
  "files": [
9
- "dist/esm/*",
10
- "dist/dts/*"
9
+ "dist/tsdown/*"
11
10
  ],
12
11
  "exports": {
13
12
  ".": "./dist/tsdown/index.js",