@codewithagents/api-errors 0.1.0 → 0.2.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.
package/README.md CHANGED
@@ -32,16 +32,42 @@ function SignupForm() {
32
32
  <form onSubmit={handleSubmit(onSubmit)}>
33
33
  <input {...register('email')} />
34
34
  {errors.email && <p>{errors.email.message}</p>}
35
-
36
- <input {...register('name')} />
37
- {errors.name && <p>{errors.name.message}</p>}
38
-
39
35
  <button type="submit">Sign up</button>
40
36
  </form>
41
37
  )
42
38
  }
43
39
  ```
44
40
 
41
+ ### With typed React Hook Form forms
42
+
43
+ `mapApiErrors` accepts any function matching `(field: string, error: { type: string; message: string }) => void`, which is compatible with RHF's `UseFormSetError<T>`. No casting needed:
44
+
45
+ ```tsx
46
+ type FormValues = { email: string; name: string }
47
+
48
+ const { setError } = useForm<FormValues>()
49
+
50
+ // ✅ works — setError is assignable to the expected signature
51
+ mapApiErrors(error, setError)
52
+ ```
53
+
54
+ ### With native `fetch` (no Axios)
55
+
56
+ Pass the parsed response body directly to `extractFieldErrors`:
57
+
58
+ ```ts
59
+ import { extractFieldErrors } from '@codewithagents/api-errors'
60
+
61
+ const res = await fetch('/api/signup', { method: 'POST', body: JSON.stringify(data) })
62
+ if (!res.ok) {
63
+ const body = await res.json()
64
+ const fieldErrors = extractFieldErrors(body)
65
+ for (const { field, message } of fieldErrors) {
66
+ setError(field, { type: 'server', message })
67
+ }
68
+ }
69
+ ```
70
+
45
71
  ### Standalone with `extractFieldErrors`
46
72
 
47
73
  Use `extractFieldErrors` when you need the normalized error list without a form library:
@@ -54,22 +80,31 @@ try {
54
80
  } catch (error) {
55
81
  const fieldErrors = extractFieldErrors(error)
56
82
  // [{ field: 'email', message: 'must not be blank' }, ...]
57
-
58
83
  for (const { field, message } of fieldErrors) {
59
84
  console.warn(`${field}: ${message}`)
60
85
  }
61
86
  }
62
87
  ```
63
88
 
64
- You can customize the fallback field name and transform field names:
89
+ ### Options
90
+
91
+ Both `extractFieldErrors` and `mapApiErrors` accept an options object:
65
92
 
66
93
  ```ts
67
94
  const fieldErrors = extractFieldErrors(error, {
68
- fallbackField: 'root', // used when no field is found (default: 'root')
69
- transformField: (f) => f.replace(/([A-Z])/g, '.$1').toLowerCase(), // camelCase → dot.path
95
+ // Field name used when no field can be determined (default: 'root')
96
+ fallbackField: 'serverError',
97
+
98
+ // Transform field names — e.g. camelCase backend → dot.path for nested RHF fields
99
+ transformField: (f) => f.replace(/([A-Z])/g, '.$1').toLowerCase(),
70
100
  })
101
+
102
+ // Options work on mapApiErrors too
103
+ mapApiErrors(error, setError, { fallbackField: 'root' })
71
104
  ```
72
105
 
106
+ > **Note:** `transformField` is also applied to `fallbackField`. If you transform `emailAddress` → `email.address`, the fallback field name is transformed the same way.
107
+
73
108
  ## Supported Error Formats
74
109
 
75
110
  **RFC 7807 Problem Details** (Spring Boot 3+, standard):
@@ -99,11 +134,27 @@ const fieldErrors = extractFieldErrors(error, {
99
134
  ```json
100
135
  { "field": "email", "message": "Invalid email" }
101
136
  ```
102
- or as an array:
137
+
138
+ **Array of flat objects:**
103
139
  ```json
104
140
  [{ "field": "email", "message": "Invalid email" }]
105
141
  ```
106
142
 
143
+ Response wrappers are automatically unwrapped — both Axios-style `error.response.data` and generic `{ data: { ... } }` shapes.
144
+
145
+ ## Known behaviour: multiple errors for the same field
146
+
147
+ When a backend returns multiple errors for the same field (e.g. in the flat array format), `extractFieldErrors` returns all of them. If you pass them all to React Hook Form's `setError`, the **last call wins** — only the last message is displayed. If you need to show all messages, collect them before calling `setError`:
148
+
149
+ ```ts
150
+ const fieldErrors = extractFieldErrors(error)
151
+ const grouped = Map.groupBy(fieldErrors, (e) => e.field)
152
+
153
+ for (const [field, errs] of grouped) {
154
+ setError(field, { type: 'server', message: errs.map((e) => e.message).join(', ') })
155
+ }
156
+ ```
157
+
107
158
  ## TypeScript
108
159
 
109
160
  This package is written in TypeScript and ships full type declarations. No `@types` package needed.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;CAC3C;AAmID;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,mBAAmB,GAC5B,UAAU,EAAE,CAyCd;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,EAC3E,OAAO,CAAC,EAAE,mBAAmB,GAC5B,IAAI,CAKN"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;CAC3C;AAiID;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,mBAAmB,GAC5B,UAAU,EAAE,CAyCd;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,EAC3E,OAAO,CAAC,EAAE,mBAAmB,GAC5B,IAAI,CAKN"}
package/dist/index.js CHANGED
@@ -29,10 +29,7 @@ function tryParseRfc7807(body, fallbackField, transformField) {
29
29
  else if (typeof messages === 'string') {
30
30
  result.push({ field, message: messages });
31
31
  }
32
- else {
33
- // Unknown value shape — use fallback field with stringified message
34
- result.push({ field: transformField(fallbackField), message: String(messages) });
35
- }
32
+ // null / unknown value shapes are skipped — no partial/garbage errors
36
33
  }
37
34
  return result.length > 0 ? result : null;
38
35
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codewithagents/api-errors",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Map backend API errors to form field errors. Framework-agnostic core with React Hook Form adapter.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=index.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
@@ -1,161 +0,0 @@
1
- import { describe, expect, it, vi } from 'vitest';
2
- import { extractFieldErrors, mapApiErrors } from './index.js';
3
- // ---------------------------------------------------------------------------
4
- // extractFieldErrors
5
- // ---------------------------------------------------------------------------
6
- describe('extractFieldErrors', () => {
7
- describe('RFC 7807 / Spring Boot 3+ format', () => {
8
- it('maps a single field with one message', () => {
9
- const error = { errors: { email: ['must not be blank'] } };
10
- expect(extractFieldErrors(error)).toEqual([
11
- { field: 'email', message: 'must not be blank' },
12
- ]);
13
- });
14
- it('maps multiple fields', () => {
15
- const error = {
16
- errors: {
17
- email: ['must not be blank'],
18
- name: ['too short'],
19
- },
20
- };
21
- const result = extractFieldErrors(error);
22
- expect(result).toHaveLength(2);
23
- expect(result).toContainEqual({ field: 'email', message: 'must not be blank' });
24
- expect(result).toContainEqual({ field: 'name', message: 'too short' });
25
- });
26
- it('expands multiple messages per field into separate FieldErrors', () => {
27
- const error = { errors: { email: ['must not be blank', 'invalid format'] } };
28
- expect(extractFieldErrors(error)).toEqual([
29
- { field: 'email', message: 'must not be blank' },
30
- { field: 'email', message: 'invalid format' },
31
- ]);
32
- });
33
- });
34
- describe('Spring Boot default validation format (array)', () => {
35
- it('maps field + defaultMessage', () => {
36
- const error = {
37
- status: 400,
38
- errors: [{ field: 'email', defaultMessage: 'must not be blank' }],
39
- };
40
- expect(extractFieldErrors(error)).toEqual([
41
- { field: 'email', message: 'must not be blank' },
42
- ]);
43
- });
44
- it('falls back to message when defaultMessage is absent', () => {
45
- const error = {
46
- errors: [{ field: 'email', message: 'must not be blank' }],
47
- };
48
- expect(extractFieldErrors(error)).toEqual([
49
- { field: 'email', message: 'must not be blank' },
50
- ]);
51
- });
52
- it('maps multiple entries', () => {
53
- const error = {
54
- errors: [
55
- { field: 'email', defaultMessage: 'must not be blank' },
56
- { field: 'name', defaultMessage: 'too short' },
57
- ],
58
- };
59
- expect(extractFieldErrors(error)).toHaveLength(2);
60
- });
61
- });
62
- describe('flat object format', () => {
63
- it('maps { field, message } directly', () => {
64
- const error = { field: 'email', message: 'Invalid email' };
65
- expect(extractFieldErrors(error)).toEqual([
66
- { field: 'email', message: 'Invalid email' },
67
- ]);
68
- });
69
- it('uses fallbackField when field is absent', () => {
70
- const error = { message: 'Something went wrong' };
71
- expect(extractFieldErrors(error, { fallbackField: 'root' })).toEqual([
72
- { field: 'root', message: 'Something went wrong' },
73
- ]);
74
- });
75
- });
76
- describe('flat array format', () => {
77
- it('maps an array of { field, message } objects', () => {
78
- const error = [
79
- { field: 'email', message: 'Invalid' },
80
- { field: 'name', message: 'Required' },
81
- ];
82
- expect(extractFieldErrors(error)).toEqual([
83
- { field: 'email', message: 'Invalid' },
84
- { field: 'name', message: 'Required' },
85
- ]);
86
- });
87
- it('skips entries without a message', () => {
88
- const error = [{ field: 'email' }, { field: 'name', message: 'Required' }];
89
- expect(extractFieldErrors(error)).toEqual([
90
- { field: 'name', message: 'Required' },
91
- ]);
92
- });
93
- });
94
- describe('Axios-style response wrapper', () => {
95
- it('unwraps response.data before parsing', () => {
96
- const error = {
97
- response: {
98
- data: { errors: { email: ['must not be blank'] } },
99
- },
100
- };
101
- expect(extractFieldErrors(error)).toEqual([
102
- { field: 'email', message: 'must not be blank' },
103
- ]);
104
- });
105
- });
106
- describe('unrecognized / unknown shapes', () => {
107
- it('returns [] for an unrecognized object', () => {
108
- expect(extractFieldErrors({ foo: 'bar' })).toEqual([]);
109
- });
110
- it('returns [] for null', () => {
111
- expect(extractFieldErrors(null)).toEqual([]);
112
- });
113
- it('returns [] for undefined', () => {
114
- expect(extractFieldErrors(undefined)).toEqual([]);
115
- });
116
- it('returns [] for a plain string', () => {
117
- expect(extractFieldErrors('something went wrong')).toEqual([]);
118
- });
119
- it('never throws', () => {
120
- expect(() => extractFieldErrors({ deeply: { nested: { evil: true } } })).not.toThrow();
121
- });
122
- });
123
- describe('options', () => {
124
- it('uses fallbackField for errors without a field name', () => {
125
- const error = { message: 'Unauthorised' };
126
- const result = extractFieldErrors(error, { fallbackField: 'serverError' });
127
- expect(result).toEqual([{ field: 'serverError', message: 'Unauthorised' }]);
128
- });
129
- it('applies transformField to every resolved field name', () => {
130
- const error = { errors: { emailAddress: ['invalid'] } };
131
- const result = extractFieldErrors(error, {
132
- transformField: (f) => f.replace(/([A-Z])/g, '.$1').toLowerCase(),
133
- });
134
- expect(result).toEqual([{ field: 'email.address', message: 'invalid' }]);
135
- });
136
- });
137
- });
138
- // ---------------------------------------------------------------------------
139
- // mapApiErrors
140
- // ---------------------------------------------------------------------------
141
- describe('mapApiErrors', () => {
142
- it('calls setError for each field error with type "server"', () => {
143
- const setError = vi.fn();
144
- const error = { errors: { email: ['must not be blank'], name: ['too short'] } };
145
- mapApiErrors(error, setError);
146
- expect(setError).toHaveBeenCalledTimes(2);
147
- expect(setError).toHaveBeenCalledWith('email', { type: 'server', message: 'must not be blank' });
148
- expect(setError).toHaveBeenCalledWith('name', { type: 'server', message: 'too short' });
149
- });
150
- it('never calls setError for unrecognized errors', () => {
151
- const setError = vi.fn();
152
- mapApiErrors({ foo: 'bar' }, setError);
153
- expect(setError).not.toHaveBeenCalled();
154
- });
155
- it('never calls setError for null', () => {
156
- const setError = vi.fn();
157
- mapApiErrors(null, setError);
158
- expect(setError).not.toHaveBeenCalled();
159
- });
160
- });
161
- //# sourceMappingURL=index.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"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"}