UNPKG

@next-safe-action/adapter-react-hook-form

Version:

This adapter offers a way to seamlessly integrate next-safe-action with react-hook-form.

1 lines 3.22 kB
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument */\n\nimport type { ValidationErrors } from \"next-safe-action\";\nimport type { FieldError, FieldErrors } from \"react-hook-form\";\nimport type {} from \"zod\";\nimport type { ErrorMapperProps } from \"./index.types\";\nimport type { InferOutputOrDefault, StandardSchemaV1 } from \"./standard-schema\";\n\n/**\n * Maps a validation errors object to an object of `FieldErrors` compatible with react-hook-form.\n * You should only call this function directly for advanced use cases, and prefer exported hooks.\n */\nexport function mapToHookFormErrors<S extends StandardSchemaV1 | undefined>(\n\tvalidationErrors: ValidationErrors<S> | undefined,\n\tprops?: ErrorMapperProps\n) {\n\tif (!validationErrors || Object.keys(validationErrors).length === 0) {\n\t\treturn undefined;\n\t}\n\n\tconst fieldErrors: FieldErrors<InferOutputOrDefault<S, any>> = {};\n\n\tfunction mapper(ve: Record<string, any>, paths: string[] = []) {\n\t\t// Map through validation errors.\n\t\tfor (const key of Object.keys(ve)) {\n\t\t\t// If validation error is an object, recursively call mapper so we go one level deeper\n\t\t\t// at a time. Pass the current paths to the mapper as well.\n\t\t\tif (typeof ve[key] === \"object\" && ve[key] && !Array.isArray(ve[key])) {\n\t\t\t\tmapper(ve[key], [...paths, key]);\n\t\t\t}\n\n\t\t\t// We're just interested in the `_errors` field, which must be an array.\n\t\t\tif (key === \"_errors\" && Array.isArray(ve[key])) {\n\t\t\t\t// Initially set moving reference to root `fieldErrors` object.\n\t\t\t\tlet ref = fieldErrors as Record<string, any>;\n\n\t\t\t\t// Iterate through the paths, create nested objects if needed and move the reference.\n\t\t\t\tfor (let i = 0; i < paths.length - 1; i++) {\n\t\t\t\t\tconst p = paths[i]!;\n\t\t\t\t\tref[p] ??= {};\n\t\t\t\t\tref = ref[p];\n\t\t\t\t}\n\n\t\t\t\t// The actual path is the last one. If it's undefined, it means that we're at the root level.\n\t\t\t\tconst path = paths.at(-1) ?? \"root\";\n\n\t\t\t\t// Set the error for the current path.\n\t\t\t\tref[path] = {\n\t\t\t\t\ttype: \"validate\",\n\t\t\t\t\tmessage: ve[key].join(props?.joinBy ?? \" \"),\n\t\t\t\t} as FieldError;\n\t\t\t}\n\t\t}\n\t}\n\n\tmapper(validationErrors ?? {});\n\treturn fieldErrors;\n}\n\nexport type * from \"./index.types\";\n"],"mappings":";AAYO,SAAS,oBACf,kBACA,OACC;AACD,MAAI,CAAC,oBAAoB,OAAO,KAAK,gBAAgB,EAAE,WAAW,GAAG;AACpE,WAAO;AAAA,EACR;AAEA,QAAM,cAAyD,CAAC;AAEhE,WAAS,OAAO,IAAyB,QAAkB,CAAC,GAAG;AAE9D,eAAW,OAAO,OAAO,KAAK,EAAE,GAAG;AAGlC,UAAI,OAAO,GAAG,GAAG,MAAM,YAAY,GAAG,GAAG,KAAK,CAAC,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG;AACtE,eAAO,GAAG,GAAG,GAAG,CAAC,GAAG,OAAO,GAAG,CAAC;AAAA,MAChC;AAGA,UAAI,QAAQ,aAAa,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG;AAEhD,YAAI,MAAM;AAGV,iBAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AAC1C,gBAAM,IAAI,MAAM,CAAC;AACjB,cAAI,CAAC,MAAM,CAAC;AACZ,gBAAM,IAAI,CAAC;AAAA,QACZ;AAGA,cAAM,OAAO,MAAM,GAAG,EAAE,KAAK;AAG7B,YAAI,IAAI,IAAI;AAAA,UACX,MAAM;AAAA,UACN,SAAS,GAAG,GAAG,EAAE,KAAK,OAAO,UAAU,GAAG;AAAA,QAC3C;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAEA,SAAO,oBAAoB,CAAC,CAAC;AAC7B,SAAO;AACR;","names":[]}