@leancodepl/validation 8.5.0 → 8.6.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 +106 -0
- package/index.cjs.default.js +1 -0
- package/index.cjs.js +128 -0
- package/index.cjs.mjs +2 -0
- package/index.d.ts +1 -0
- package/index.esm.js +125 -0
- package/package.json +2 -7
- package/src/index.d.ts +2 -0
- package/src/lib/handleResponse.d.ts +28 -0
- package/src/lib/handleValidationErrors.d.ts +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# @leancodepl/validation
|
|
2
|
+
|
|
3
|
+
TypeScript library for handling validation errors in CQRS command responses with type-safe error code mapping.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @leancodepl/validation
|
|
9
|
+
# or
|
|
10
|
+
yarn add @leancodepl/validation
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## API
|
|
14
|
+
|
|
15
|
+
### `handleValidationErrors(validationErrors, errorCodesMap, validationResults)`
|
|
16
|
+
|
|
17
|
+
Creates a validation error handler that processes errors with type-safe error code mapping.
|
|
18
|
+
|
|
19
|
+
**Parameters:**
|
|
20
|
+
|
|
21
|
+
- `validationErrors: ValidationError<TAllErrors>[]` - Array of validation errors to process
|
|
22
|
+
- `errorCodesMap: TAllErrors` - Mapping of error names to numeric codes
|
|
23
|
+
- `validationResults?: TInResult[]` - Optional array of previous handler results
|
|
24
|
+
|
|
25
|
+
**Returns:** Handler with `handle`, `handleAll`, and `check` methods
|
|
26
|
+
|
|
27
|
+
### `handleResponse(response, errorCodesMap)`
|
|
28
|
+
|
|
29
|
+
Handles CQRS command responses and transforms them into validation error handlers.
|
|
30
|
+
|
|
31
|
+
**Parameters:**
|
|
32
|
+
|
|
33
|
+
- `response: ApiResponse<CommandResult<TErrors>>` - API response containing command result
|
|
34
|
+
- `errorCodesMap: TErrors` - Mapping of error names to numeric codes
|
|
35
|
+
|
|
36
|
+
**Returns:** Validation error handler with success/failure support
|
|
37
|
+
|
|
38
|
+
## Usage Examples
|
|
39
|
+
|
|
40
|
+
### Basic Error Handling
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { handleValidationErrors } from "@leancodepl/validation"
|
|
44
|
+
|
|
45
|
+
const errorCodes = { EmailExists: 1, InvalidEmail: 2 } as const
|
|
46
|
+
const errors = [
|
|
47
|
+
{ ErrorCode: 1, ErrorMessage: "Email exists", PropertyName: "Email", AttemptedValue: "user@example.com" },
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
handleValidationErrors(errors, errorCodes)
|
|
51
|
+
.handle("EmailExists", () => console.log("Email already registered"))
|
|
52
|
+
.handle("InvalidEmail", () => console.log("Invalid email format"))
|
|
53
|
+
.check()
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Command Response Handling
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { handleResponse } from "@leancodepl/validation"
|
|
60
|
+
|
|
61
|
+
const errorCodes = { UserNotFound: 1 } as const
|
|
62
|
+
const response = await fetch("/api/users/123", { method: "PUT", body: JSON.stringify({ name: "John" }) })
|
|
63
|
+
|
|
64
|
+
handleResponse(response, errorCodes)
|
|
65
|
+
.handle("success", () => console.log("User updated"))
|
|
66
|
+
.handle("UserNotFound", () => console.log("User not found"))
|
|
67
|
+
.handle("failure", () => console.log("Request failed"))
|
|
68
|
+
.check()
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Multiple Error Handling
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import { handleValidationErrors } from "@leancodepl/validation"
|
|
75
|
+
|
|
76
|
+
const errorCodes = { Required: 1, Invalid: 2 } as const
|
|
77
|
+
const errors = [
|
|
78
|
+
{ ErrorCode: 1, PropertyName: "email", ErrorMessage: "Email required" },
|
|
79
|
+
{ ErrorCode: 2, PropertyName: "name", ErrorMessage: "Invalid name" },
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
handleValidationErrors(errors, errorCodes)
|
|
83
|
+
.handleAll(["Required", "Invalid"], errorGroups => {
|
|
84
|
+
errorGroups.forEach(({ errors }) => {
|
|
85
|
+
errors.forEach(error => console.log(`${error.PropertyName}: ${error.ErrorMessage}`))
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
.check()
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Success/Failure Result Processing
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
import { handleResponse } from "@leancodepl/validation"
|
|
95
|
+
|
|
96
|
+
const errorCodes = { InvalidData: 1 } as const
|
|
97
|
+
const response = await fetch("/api/data")
|
|
98
|
+
|
|
99
|
+
const isSuccess = handleResponse(response, errorCodes)
|
|
100
|
+
.handle("success", () => true)
|
|
101
|
+
.handle(["InvalidData", "failure"], () => false)
|
|
102
|
+
.check({
|
|
103
|
+
reducer: (prev, current) => prev && current,
|
|
104
|
+
initialValue: true,
|
|
105
|
+
})
|
|
106
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
exports._default = require('./index.cjs.js').default;
|
package/index.cjs.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates a validation error handler that processes errors with type-safe error code mapping.
|
|
5
|
+
*
|
|
6
|
+
* @template TAllErrors - Error codes map type extending Record<string, number>
|
|
7
|
+
* @template TInResult - Type of results accumulated from previous handlers
|
|
8
|
+
* @param validationErrors - Array of validation errors to process
|
|
9
|
+
* @param errorCodesMap - Mapping of error names to numeric codes
|
|
10
|
+
* @param validationResults - Optional array of previous handler results
|
|
11
|
+
* @returns Handler with handle, handleAll, and check methods
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const errorCodes = { EmailExists: 1, InvalidEmail: 2 } as const;
|
|
15
|
+
* const errors = [{ ErrorCode: 1, ErrorMessage: 'Email exists', PropertyName: 'Email', AttemptedValue: 'test@example.com' }];
|
|
16
|
+
*
|
|
17
|
+
* handleValidationErrors(errors, errorCodes)
|
|
18
|
+
* .handle('EmailExists', () => console.warn('Email already registered'))
|
|
19
|
+
* .handle('InvalidEmail', () => console.warn('Invalid email format'))
|
|
20
|
+
* .check();
|
|
21
|
+
* ```
|
|
22
|
+
*/ function handleValidationErrors(validationErrors, errorCodesMap, validationResults = []) {
|
|
23
|
+
const handle = (validationErrorsToHandle, handler)=>{
|
|
24
|
+
let result = undefined;
|
|
25
|
+
for (const validationErrorToHandle of Array.isArray(validationErrorsToHandle) ? validationErrorsToHandle : [
|
|
26
|
+
validationErrorsToHandle
|
|
27
|
+
]){
|
|
28
|
+
const ve = validationErrors.find((ve)=>ve.ErrorCode === errorCodesMap[validationErrorToHandle]);
|
|
29
|
+
if (ve) {
|
|
30
|
+
result = handler(validationErrorToHandle, ve);
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
let nextResult = validationResults;
|
|
35
|
+
if (result !== undefined) {
|
|
36
|
+
nextResult = [
|
|
37
|
+
...nextResult,
|
|
38
|
+
result
|
|
39
|
+
];
|
|
40
|
+
}
|
|
41
|
+
return handleValidationErrors(validationErrors, errorCodesMap, nextResult);
|
|
42
|
+
};
|
|
43
|
+
const handleAll = (_validationErrorsToHandle, handler)=>{
|
|
44
|
+
let result = undefined;
|
|
45
|
+
const validationErrorsToHandle = Array.isArray(_validationErrorsToHandle) ? _validationErrorsToHandle : [
|
|
46
|
+
_validationErrorsToHandle
|
|
47
|
+
];
|
|
48
|
+
const foundErrors = validationErrorsToHandle.reduce((prev, cur)=>{
|
|
49
|
+
const ves = validationErrors.filter((ve)=>ve.ErrorCode === errorCodesMap[cur]);
|
|
50
|
+
if (ves.length === 0) {
|
|
51
|
+
return prev;
|
|
52
|
+
}
|
|
53
|
+
return [
|
|
54
|
+
...prev,
|
|
55
|
+
{
|
|
56
|
+
errorName: cur,
|
|
57
|
+
errors: ves
|
|
58
|
+
}
|
|
59
|
+
];
|
|
60
|
+
}, []);
|
|
61
|
+
if (foundErrors.length > 0) {
|
|
62
|
+
result = handler(foundErrors);
|
|
63
|
+
}
|
|
64
|
+
let nextResult = validationResults;
|
|
65
|
+
if (result !== undefined) {
|
|
66
|
+
nextResult = [
|
|
67
|
+
...nextResult,
|
|
68
|
+
result
|
|
69
|
+
];
|
|
70
|
+
}
|
|
71
|
+
return handleValidationErrors(validationErrors, errorCodesMap, nextResult);
|
|
72
|
+
};
|
|
73
|
+
return {
|
|
74
|
+
handle,
|
|
75
|
+
handleAll,
|
|
76
|
+
check: (reducer)=>{
|
|
77
|
+
if (reducer) {
|
|
78
|
+
return validationResults.reduce(reducer.reducer, reducer.initialValue);
|
|
79
|
+
}
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Handles CQRS command responses and transforms them into validation error handlers.
|
|
87
|
+
*
|
|
88
|
+
* @template TErrors - Error codes map type extending Record<string, number>
|
|
89
|
+
* @param response - API response containing command result
|
|
90
|
+
* @param errorCodesMap - Mapping of error names to numeric codes
|
|
91
|
+
* @returns Validation error handler with success/failure support
|
|
92
|
+
* @example
|
|
93
|
+
* ```typescript
|
|
94
|
+
* const errorCodes = { UserNotFound: 1 } as const;
|
|
95
|
+
* const response = await commandClient.execute(createUserCommand);
|
|
96
|
+
*
|
|
97
|
+
* handleResponse(response, errorCodes)
|
|
98
|
+
* .handle('success', () => console.log('User created'))
|
|
99
|
+
* .handle('failure', () => console.log('Network error'))
|
|
100
|
+
* .handle('UserNotFound', () => console.log('User not found'))
|
|
101
|
+
* .check();
|
|
102
|
+
* ```
|
|
103
|
+
*/ function handleResponse(response, errorCodesMap) {
|
|
104
|
+
const newErrorCodesMap = {
|
|
105
|
+
...errorCodesMap,
|
|
106
|
+
success: -1,
|
|
107
|
+
failure: -2
|
|
108
|
+
};
|
|
109
|
+
const validationErrors = response.isSuccess ? response.result.WasSuccessful ? [
|
|
110
|
+
{
|
|
111
|
+
AttemptedValue: "",
|
|
112
|
+
ErrorMessage: "",
|
|
113
|
+
PropertyName: "",
|
|
114
|
+
ErrorCode: -1
|
|
115
|
+
}
|
|
116
|
+
] : response.result.ValidationErrors : [
|
|
117
|
+
{
|
|
118
|
+
AttemptedValue: "",
|
|
119
|
+
ErrorMessage: "",
|
|
120
|
+
PropertyName: "",
|
|
121
|
+
ErrorCode: -2
|
|
122
|
+
}
|
|
123
|
+
];
|
|
124
|
+
return handleValidationErrors(validationErrors, newErrorCodesMap);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
exports.handleResponse = handleResponse;
|
|
128
|
+
exports.handleValidationErrors = handleValidationErrors;
|
package/index.cjs.mjs
ADDED
package/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./src/index";
|
package/index.esm.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a validation error handler that processes errors with type-safe error code mapping.
|
|
3
|
+
*
|
|
4
|
+
* @template TAllErrors - Error codes map type extending Record<string, number>
|
|
5
|
+
* @template TInResult - Type of results accumulated from previous handlers
|
|
6
|
+
* @param validationErrors - Array of validation errors to process
|
|
7
|
+
* @param errorCodesMap - Mapping of error names to numeric codes
|
|
8
|
+
* @param validationResults - Optional array of previous handler results
|
|
9
|
+
* @returns Handler with handle, handleAll, and check methods
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const errorCodes = { EmailExists: 1, InvalidEmail: 2 } as const;
|
|
13
|
+
* const errors = [{ ErrorCode: 1, ErrorMessage: 'Email exists', PropertyName: 'Email', AttemptedValue: 'test@example.com' }];
|
|
14
|
+
*
|
|
15
|
+
* handleValidationErrors(errors, errorCodes)
|
|
16
|
+
* .handle('EmailExists', () => console.warn('Email already registered'))
|
|
17
|
+
* .handle('InvalidEmail', () => console.warn('Invalid email format'))
|
|
18
|
+
* .check();
|
|
19
|
+
* ```
|
|
20
|
+
*/ function handleValidationErrors(validationErrors, errorCodesMap, validationResults = []) {
|
|
21
|
+
const handle = (validationErrorsToHandle, handler)=>{
|
|
22
|
+
let result = undefined;
|
|
23
|
+
for (const validationErrorToHandle of Array.isArray(validationErrorsToHandle) ? validationErrorsToHandle : [
|
|
24
|
+
validationErrorsToHandle
|
|
25
|
+
]){
|
|
26
|
+
const ve = validationErrors.find((ve)=>ve.ErrorCode === errorCodesMap[validationErrorToHandle]);
|
|
27
|
+
if (ve) {
|
|
28
|
+
result = handler(validationErrorToHandle, ve);
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
let nextResult = validationResults;
|
|
33
|
+
if (result !== undefined) {
|
|
34
|
+
nextResult = [
|
|
35
|
+
...nextResult,
|
|
36
|
+
result
|
|
37
|
+
];
|
|
38
|
+
}
|
|
39
|
+
return handleValidationErrors(validationErrors, errorCodesMap, nextResult);
|
|
40
|
+
};
|
|
41
|
+
const handleAll = (_validationErrorsToHandle, handler)=>{
|
|
42
|
+
let result = undefined;
|
|
43
|
+
const validationErrorsToHandle = Array.isArray(_validationErrorsToHandle) ? _validationErrorsToHandle : [
|
|
44
|
+
_validationErrorsToHandle
|
|
45
|
+
];
|
|
46
|
+
const foundErrors = validationErrorsToHandle.reduce((prev, cur)=>{
|
|
47
|
+
const ves = validationErrors.filter((ve)=>ve.ErrorCode === errorCodesMap[cur]);
|
|
48
|
+
if (ves.length === 0) {
|
|
49
|
+
return prev;
|
|
50
|
+
}
|
|
51
|
+
return [
|
|
52
|
+
...prev,
|
|
53
|
+
{
|
|
54
|
+
errorName: cur,
|
|
55
|
+
errors: ves
|
|
56
|
+
}
|
|
57
|
+
];
|
|
58
|
+
}, []);
|
|
59
|
+
if (foundErrors.length > 0) {
|
|
60
|
+
result = handler(foundErrors);
|
|
61
|
+
}
|
|
62
|
+
let nextResult = validationResults;
|
|
63
|
+
if (result !== undefined) {
|
|
64
|
+
nextResult = [
|
|
65
|
+
...nextResult,
|
|
66
|
+
result
|
|
67
|
+
];
|
|
68
|
+
}
|
|
69
|
+
return handleValidationErrors(validationErrors, errorCodesMap, nextResult);
|
|
70
|
+
};
|
|
71
|
+
return {
|
|
72
|
+
handle,
|
|
73
|
+
handleAll,
|
|
74
|
+
check: (reducer)=>{
|
|
75
|
+
if (reducer) {
|
|
76
|
+
return validationResults.reduce(reducer.reducer, reducer.initialValue);
|
|
77
|
+
}
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Handles CQRS command responses and transforms them into validation error handlers.
|
|
85
|
+
*
|
|
86
|
+
* @template TErrors - Error codes map type extending Record<string, number>
|
|
87
|
+
* @param response - API response containing command result
|
|
88
|
+
* @param errorCodesMap - Mapping of error names to numeric codes
|
|
89
|
+
* @returns Validation error handler with success/failure support
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* const errorCodes = { UserNotFound: 1 } as const;
|
|
93
|
+
* const response = await commandClient.execute(createUserCommand);
|
|
94
|
+
*
|
|
95
|
+
* handleResponse(response, errorCodes)
|
|
96
|
+
* .handle('success', () => console.log('User created'))
|
|
97
|
+
* .handle('failure', () => console.log('Network error'))
|
|
98
|
+
* .handle('UserNotFound', () => console.log('User not found'))
|
|
99
|
+
* .check();
|
|
100
|
+
* ```
|
|
101
|
+
*/ function handleResponse(response, errorCodesMap) {
|
|
102
|
+
const newErrorCodesMap = {
|
|
103
|
+
...errorCodesMap,
|
|
104
|
+
success: -1,
|
|
105
|
+
failure: -2
|
|
106
|
+
};
|
|
107
|
+
const validationErrors = response.isSuccess ? response.result.WasSuccessful ? [
|
|
108
|
+
{
|
|
109
|
+
AttemptedValue: "",
|
|
110
|
+
ErrorMessage: "",
|
|
111
|
+
PropertyName: "",
|
|
112
|
+
ErrorCode: -1
|
|
113
|
+
}
|
|
114
|
+
] : response.result.ValidationErrors : [
|
|
115
|
+
{
|
|
116
|
+
AttemptedValue: "",
|
|
117
|
+
ErrorMessage: "",
|
|
118
|
+
PropertyName: "",
|
|
119
|
+
ErrorCode: -2
|
|
120
|
+
}
|
|
121
|
+
];
|
|
122
|
+
return handleValidationErrors(validationErrors, newErrorCodesMap);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export { handleResponse, handleValidationErrors };
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leancodepl/validation",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.6.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@leancodepl/cqrs-client-base": "8.
|
|
6
|
+
"@leancodepl/cqrs-client-base": "8.6.0"
|
|
7
7
|
},
|
|
8
8
|
"devDependencies": {
|
|
9
9
|
"sinon": "15.2.0"
|
|
@@ -38,11 +38,6 @@
|
|
|
38
38
|
"name": "LeanCode",
|
|
39
39
|
"url": "https://leancode.co"
|
|
40
40
|
},
|
|
41
|
-
"files": [
|
|
42
|
-
"dist",
|
|
43
|
-
"README.md",
|
|
44
|
-
"CHANGELOG.md"
|
|
45
|
-
],
|
|
46
41
|
"sideEffects": false,
|
|
47
42
|
"exports": {
|
|
48
43
|
"./package.json": "./package.json",
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ApiResponse, CommandResult } from "@leancodepl/cqrs-client-base";
|
|
2
|
+
export type SuccessOrFailureMarker = {
|
|
3
|
+
success: -1;
|
|
4
|
+
failure: -2;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Handles CQRS command responses and transforms them into validation error handlers.
|
|
8
|
+
*
|
|
9
|
+
* @template TErrors - Error codes map type extending Record<string, number>
|
|
10
|
+
* @param response - API response containing command result
|
|
11
|
+
* @param errorCodesMap - Mapping of error names to numeric codes
|
|
12
|
+
* @returns Validation error handler with success/failure support
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const errorCodes = { UserNotFound: 1 } as const;
|
|
16
|
+
* const response = await commandClient.execute(createUserCommand);
|
|
17
|
+
*
|
|
18
|
+
* handleResponse(response, errorCodes)
|
|
19
|
+
* .handle('success', () => console.log('User created'))
|
|
20
|
+
* .handle('failure', () => console.log('Network error'))
|
|
21
|
+
* .handle('UserNotFound', () => console.log('User not found'))
|
|
22
|
+
* .check();
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function handleResponse<TErrors extends Record<string, number>>(response: ApiResponse<CommandResult<TErrors>>, errorCodesMap: TErrors): import("./handleValidationErrors").ValidationErrorsHandler<TErrors & {
|
|
26
|
+
readonly success: -1;
|
|
27
|
+
readonly failure: -2;
|
|
28
|
+
}, never>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ValidationError } from "@leancodepl/cqrs-client-base";
|
|
2
|
+
export type ReducerDescription<THandlerResult, TReturnValue = THandlerResult> = {
|
|
3
|
+
reducer: (prev: TReturnValue, cur: THandlerResult) => TReturnValue;
|
|
4
|
+
initialValue: TReturnValue;
|
|
5
|
+
};
|
|
6
|
+
export type SpecificValidationError<TErrors extends Record<string, number>, TError extends keyof TErrors> = ValidationError<Record<TError, TErrors[TError]>>;
|
|
7
|
+
export type ValidationErrorHandlerFunc<TErrorsToHandle extends Record<string, number>, THandledErrors extends keyof TErrorsToHandle, TResult> = (errorName: THandledErrors, error: SpecificValidationError<TErrorsToHandle, THandledErrors>) => TResult;
|
|
8
|
+
export type ValidationErrorsHandleFunc<TErrorsToHandle extends Record<string, number>, TInResult> = {
|
|
9
|
+
<THandledErrors extends keyof TErrorsToHandle, TResult>(validationErrors: THandledErrors | THandledErrors[], handler: ValidationErrorHandlerFunc<TErrorsToHandle, THandledErrors, TResult>): ValidationErrorsHandler<Omit<TErrorsToHandle, THandledErrors>, TInResult | TResult>;
|
|
10
|
+
};
|
|
11
|
+
export type ValidationErrorHandlerAllFunc<TErrorsToHandle extends Record<string, number>, THandledErrors extends keyof TErrorsToHandle, TResult> = (errors: {
|
|
12
|
+
errorName: THandledErrors;
|
|
13
|
+
errors: SpecificValidationError<TErrorsToHandle, THandledErrors>[];
|
|
14
|
+
}[]) => TResult;
|
|
15
|
+
export type ValidationErrorsHandleAllFunc<TErrorsToHandle extends Record<string, number>, TInResult> = {
|
|
16
|
+
<THandledErrors extends keyof TErrorsToHandle, TResult>(validationErrors: THandledErrors | THandledErrors[], handler: ValidationErrorHandlerAllFunc<TErrorsToHandle, THandledErrors, TResult>): ValidationErrorsHandler<Omit<TErrorsToHandle, THandledErrors>, TInResult | TResult>;
|
|
17
|
+
};
|
|
18
|
+
export interface ValidationErrorsHandler<TRemainingErrors extends Record<string, number>, TResult> {
|
|
19
|
+
handle: ValidationErrorsHandleFunc<TRemainingErrors, TResult>;
|
|
20
|
+
handleAll: ValidationErrorsHandleAllFunc<TRemainingErrors, TResult>;
|
|
21
|
+
check: object extends TRemainingErrors ? <TReturnValue = void>(reducer?: ReducerDescription<TResult, TReturnValue>) => TReturnValue : unknown;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Creates a validation error handler that processes errors with type-safe error code mapping.
|
|
25
|
+
*
|
|
26
|
+
* @template TAllErrors - Error codes map type extending Record<string, number>
|
|
27
|
+
* @template TInResult - Type of results accumulated from previous handlers
|
|
28
|
+
* @param validationErrors - Array of validation errors to process
|
|
29
|
+
* @param errorCodesMap - Mapping of error names to numeric codes
|
|
30
|
+
* @param validationResults - Optional array of previous handler results
|
|
31
|
+
* @returns Handler with handle, handleAll, and check methods
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* const errorCodes = { EmailExists: 1, InvalidEmail: 2 } as const;
|
|
35
|
+
* const errors = [{ ErrorCode: 1, ErrorMessage: 'Email exists', PropertyName: 'Email', AttemptedValue: 'test@example.com' }];
|
|
36
|
+
*
|
|
37
|
+
* handleValidationErrors(errors, errorCodes)
|
|
38
|
+
* .handle('EmailExists', () => console.warn('Email already registered'))
|
|
39
|
+
* .handle('InvalidEmail', () => console.warn('Invalid email format'))
|
|
40
|
+
* .check();
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare function handleValidationErrors<TAllErrors extends Record<string, number>, TInResult = never>(validationErrors: ValidationError<TAllErrors>[], errorCodesMap: TAllErrors, validationResults?: TInResult[]): ValidationErrorsHandler<TAllErrors, TInResult>;
|