serverless-event-orchestrator 2.0.1 → 2.3.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/LICENSE +21 -21
- package/README.md +489 -434
- package/dist/dispatcher.d.ts +6 -1
- package/dist/dispatcher.d.ts.map +1 -1
- package/dist/dispatcher.js +66 -7
- package/dist/dispatcher.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/types/event-type.enum.d.ts +1 -0
- package/dist/types/event-type.enum.d.ts.map +1 -1
- package/dist/types/event-type.enum.js +1 -0
- package/dist/types/event-type.enum.js.map +1 -1
- package/dist/types/routes.d.ts +6 -0
- package/dist/types/routes.d.ts.map +1 -1
- package/jest.config.js +32 -32
- package/package.json +82 -81
- package/src/dispatcher.ts +586 -519
- package/src/http/body-parser.ts +60 -60
- package/src/http/cors.ts +76 -76
- package/src/http/index.ts +3 -3
- package/src/http/response.ts +209 -209
- package/src/identity/extractor.ts +207 -207
- package/src/identity/index.ts +2 -2
- package/src/identity/jwt-verifier.ts +41 -41
- package/src/index.ts +128 -127
- package/src/middleware/crm-guard.ts +51 -51
- package/src/middleware/index.ts +3 -3
- package/src/middleware/init-tenant-context.ts +59 -59
- package/src/middleware/tenant-guard.ts +54 -54
- package/src/tenant/TenantContext.ts +115 -115
- package/src/tenant/helpers.ts +112 -112
- package/src/tenant/index.ts +21 -21
- package/src/tenant/types.ts +101 -101
- package/src/types/event-type.enum.ts +21 -20
- package/src/types/index.ts +2 -2
- package/src/types/routes.ts +218 -211
- package/src/utils/headers.ts +72 -72
- package/src/utils/index.ts +2 -2
- package/src/utils/path-matcher.ts +84 -84
- package/tests/cors.test.ts +133 -133
- package/tests/dispatcher.test.ts +795 -715
- package/tests/headers.test.ts +99 -99
- package/tests/identity.test.ts +301 -301
- package/tests/middleware/crm-guard.test.ts +69 -69
- package/tests/middleware/init-tenant-context.test.ts +147 -147
- package/tests/middleware/tenant-guard.test.ts +100 -100
- package/tests/path-matcher.test.ts +102 -102
- package/tests/response.test.ts +155 -155
- package/tests/tenant/TenantContext.test.ts +134 -134
- package/tests/tenant/helpers.test.ts +187 -187
- package/tsconfig.json +24 -24
package/src/http/response.ts
CHANGED
|
@@ -1,209 +1,209 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Response utilities for consistent HTTP responses
|
|
3
|
-
* Agnostic to domain-specific error codes - allows injection of custom codes
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Standard HTTP status codes
|
|
8
|
-
*/
|
|
9
|
-
export enum HttpStatus {
|
|
10
|
-
OK = 200,
|
|
11
|
-
CREATED = 201,
|
|
12
|
-
NO_CONTENT = 204,
|
|
13
|
-
BAD_REQUEST = 400,
|
|
14
|
-
UNAUTHORIZED = 401,
|
|
15
|
-
FORBIDDEN = 403,
|
|
16
|
-
NOT_FOUND = 404,
|
|
17
|
-
CONFLICT = 409,
|
|
18
|
-
UNPROCESSABLE_ENTITY = 422,
|
|
19
|
-
INTERNAL_SERVER_ERROR = 500,
|
|
20
|
-
SERVICE_UNAVAILABLE = 503,
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Standard response structure
|
|
25
|
-
*/
|
|
26
|
-
export interface StandardResponse<T = unknown, C = string> {
|
|
27
|
-
status: number;
|
|
28
|
-
code: C;
|
|
29
|
-
data?: T;
|
|
30
|
-
message?: string;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Lambda HTTP response format
|
|
35
|
-
*/
|
|
36
|
-
export interface HttpResponse {
|
|
37
|
-
statusCode: number;
|
|
38
|
-
body: string;
|
|
39
|
-
headers?: Record<string, string>;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Default response codes for standard HTTP statuses
|
|
44
|
-
*/
|
|
45
|
-
export const DefaultResponseCode = {
|
|
46
|
-
SUCCESS: 'SUCCESS',
|
|
47
|
-
CREATED: 'CREATED',
|
|
48
|
-
BAD_REQUEST: 'BAD_REQUEST',
|
|
49
|
-
UNAUTHORIZED: 'UNAUTHORIZED',
|
|
50
|
-
FORBIDDEN: 'FORBIDDEN',
|
|
51
|
-
NOT_FOUND: 'NOT_FOUND',
|
|
52
|
-
CONFLICT: 'CONFLICT',
|
|
53
|
-
VALIDATION_ERROR: 'VALIDATION_ERROR',
|
|
54
|
-
INTERNAL_ERROR: 'INTERNAL_ERROR',
|
|
55
|
-
} as const;
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Creates a standardized HTTP response.
|
|
59
|
-
* Automatically handles data/message normalization to ensure consistent structure.
|
|
60
|
-
*
|
|
61
|
-
* @param statusCode - HTTP status code
|
|
62
|
-
* @param data - Response payload (will be placed in 'data' field)
|
|
63
|
-
* @param code - Custom response code (Domain-specific)
|
|
64
|
-
* @param message - Optional message (if provided and data is null, message content will be put into 'data' for backward compatibility if needed, but the library now prefers explicit data)
|
|
65
|
-
* @param headers - Optional headers
|
|
66
|
-
*/
|
|
67
|
-
export function createStandardResponse<T, C = string>(
|
|
68
|
-
statusCode: number,
|
|
69
|
-
data?: T,
|
|
70
|
-
code?: C,
|
|
71
|
-
message?: string,
|
|
72
|
-
headers?: Record<string, string>
|
|
73
|
-
): HttpResponse {
|
|
74
|
-
const responseCode = code ?? (getDefaultCodeForStatus(statusCode) as unknown as C);
|
|
75
|
-
|
|
76
|
-
// Normalización automática:
|
|
77
|
-
// Si tenemos un mensaje pero no data, y el status es error,
|
|
78
|
-
// podríamos querer que el mensaje sea la descripción en data.
|
|
79
|
-
// Pero lo más limpio es seguir la estructura: { status, code, data, message }
|
|
80
|
-
|
|
81
|
-
const body: StandardResponse<T, C> = {
|
|
82
|
-
status: statusCode,
|
|
83
|
-
code: responseCode,
|
|
84
|
-
...(data !== undefined && { data }),
|
|
85
|
-
...(message && { message }),
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
const corsOrigin = process.env.CORS_ALLOWED_ORIGINS || '*';
|
|
89
|
-
const corsHeaders = process.env.CORS_ALLOWED_HEADERS ||
|
|
90
|
-
'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token,appVersion,app-version,platform,geo,x-forwarded-for,x-real-ip';
|
|
91
|
-
const corsMethods = process.env.CORS_ALLOWED_METHODS || 'GET,POST,PUT,PATCH,DELETE,OPTIONS';
|
|
92
|
-
|
|
93
|
-
return {
|
|
94
|
-
statusCode,
|
|
95
|
-
body: JSON.stringify(body, null, 2),
|
|
96
|
-
headers: {
|
|
97
|
-
'Content-Type': 'application/json',
|
|
98
|
-
'Access-Control-Allow-Origin': corsOrigin,
|
|
99
|
-
'Access-Control-Allow-Headers': corsHeaders,
|
|
100
|
-
'Access-Control-Allow-Methods': corsMethods,
|
|
101
|
-
...headers,
|
|
102
|
-
},
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Gets default response code for a status
|
|
108
|
-
*/
|
|
109
|
-
function getDefaultCodeForStatus(status: number): string {
|
|
110
|
-
switch (status) {
|
|
111
|
-
case HttpStatus.OK:
|
|
112
|
-
return DefaultResponseCode.SUCCESS;
|
|
113
|
-
case HttpStatus.CREATED:
|
|
114
|
-
return DefaultResponseCode.CREATED;
|
|
115
|
-
case HttpStatus.BAD_REQUEST:
|
|
116
|
-
return DefaultResponseCode.BAD_REQUEST;
|
|
117
|
-
case HttpStatus.UNAUTHORIZED:
|
|
118
|
-
return DefaultResponseCode.UNAUTHORIZED;
|
|
119
|
-
case HttpStatus.FORBIDDEN:
|
|
120
|
-
return DefaultResponseCode.FORBIDDEN;
|
|
121
|
-
case HttpStatus.NOT_FOUND:
|
|
122
|
-
return DefaultResponseCode.NOT_FOUND;
|
|
123
|
-
case HttpStatus.CONFLICT:
|
|
124
|
-
return DefaultResponseCode.CONFLICT;
|
|
125
|
-
case HttpStatus.UNPROCESSABLE_ENTITY:
|
|
126
|
-
return DefaultResponseCode.VALIDATION_ERROR;
|
|
127
|
-
default:
|
|
128
|
-
return DefaultResponseCode.INTERNAL_ERROR;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Success response (200 OK)
|
|
134
|
-
*/
|
|
135
|
-
export function successResponse<T, C = string>(data?: T, code?: C, headers?: Record<string, string>): HttpResponse {
|
|
136
|
-
return createStandardResponse(HttpStatus.OK, data, code, undefined, headers);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Created response (201 Created)
|
|
141
|
-
*/
|
|
142
|
-
export function createdResponse<T, C = string>(data?: T, code?: C, headers?: Record<string, string>): HttpResponse {
|
|
143
|
-
return createStandardResponse(HttpStatus.CREATED, data, code, undefined, headers);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Bad request response (400)
|
|
148
|
-
*/
|
|
149
|
-
export function badRequestResponse<C = string>(message?: string, code?: C, headers?: Record<string, string>): HttpResponse {
|
|
150
|
-
return createStandardResponse(HttpStatus.BAD_REQUEST, undefined, code, message, headers);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Unauthorized response (401)
|
|
155
|
-
*/
|
|
156
|
-
export function unauthorizedResponse<C = string>(message?: string, code?: C, headers?: Record<string, string>): HttpResponse {
|
|
157
|
-
return createStandardResponse(HttpStatus.UNAUTHORIZED, undefined, code, message, headers);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Forbidden response (403)
|
|
162
|
-
*/
|
|
163
|
-
export function forbiddenResponse<C = string>(message?: string, code?: C, headers?: Record<string, string>): HttpResponse {
|
|
164
|
-
return createStandardResponse(HttpStatus.FORBIDDEN, undefined, code, message, headers);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Not found response (404)
|
|
169
|
-
*/
|
|
170
|
-
export function notFoundResponse<C = string>(message?: string, code?: C, headers?: Record<string, string>): HttpResponse {
|
|
171
|
-
return createStandardResponse(HttpStatus.NOT_FOUND, undefined, code, message, headers);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Conflict response (409)
|
|
176
|
-
*/
|
|
177
|
-
export function conflictResponse<C = string>(message?: string, code?: C, headers?: Record<string, string>): HttpResponse {
|
|
178
|
-
return createStandardResponse(HttpStatus.CONFLICT, undefined, code, message, headers);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Validation error response (422)
|
|
183
|
-
*/
|
|
184
|
-
export function validationErrorResponse<C = string>(message?: string, code?: C, headers?: Record<string, string>): HttpResponse {
|
|
185
|
-
return createStandardResponse(HttpStatus.UNPROCESSABLE_ENTITY, undefined, code, message, headers);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Internal server error response (500)
|
|
190
|
-
*/
|
|
191
|
-
export function internalErrorResponse<C = string>(message?: string, code?: C, headers?: Record<string, string>): HttpResponse {
|
|
192
|
-
return createStandardResponse(HttpStatus.INTERNAL_SERVER_ERROR, undefined, code, message, headers);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Custom error response with automatic status resolution
|
|
197
|
-
* @param customCode - Your domain-specific error code
|
|
198
|
-
* @param message - Error message
|
|
199
|
-
* @param codeToStatusMap - Mapping of custom codes to HTTP statuses
|
|
200
|
-
*/
|
|
201
|
-
export function customErrorResponse<C extends string>(
|
|
202
|
-
customCode: C,
|
|
203
|
-
message?: string,
|
|
204
|
-
codeToStatusMap?: Record<C, HttpStatus>,
|
|
205
|
-
headers?: Record<string, string>
|
|
206
|
-
): HttpResponse {
|
|
207
|
-
const status = codeToStatusMap?.[customCode] ?? HttpStatus.INTERNAL_SERVER_ERROR;
|
|
208
|
-
return createStandardResponse(status, undefined, customCode, message, headers);
|
|
209
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Response utilities for consistent HTTP responses
|
|
3
|
+
* Agnostic to domain-specific error codes - allows injection of custom codes
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Standard HTTP status codes
|
|
8
|
+
*/
|
|
9
|
+
export enum HttpStatus {
|
|
10
|
+
OK = 200,
|
|
11
|
+
CREATED = 201,
|
|
12
|
+
NO_CONTENT = 204,
|
|
13
|
+
BAD_REQUEST = 400,
|
|
14
|
+
UNAUTHORIZED = 401,
|
|
15
|
+
FORBIDDEN = 403,
|
|
16
|
+
NOT_FOUND = 404,
|
|
17
|
+
CONFLICT = 409,
|
|
18
|
+
UNPROCESSABLE_ENTITY = 422,
|
|
19
|
+
INTERNAL_SERVER_ERROR = 500,
|
|
20
|
+
SERVICE_UNAVAILABLE = 503,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Standard response structure
|
|
25
|
+
*/
|
|
26
|
+
export interface StandardResponse<T = unknown, C = string> {
|
|
27
|
+
status: number;
|
|
28
|
+
code: C;
|
|
29
|
+
data?: T;
|
|
30
|
+
message?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Lambda HTTP response format
|
|
35
|
+
*/
|
|
36
|
+
export interface HttpResponse {
|
|
37
|
+
statusCode: number;
|
|
38
|
+
body: string;
|
|
39
|
+
headers?: Record<string, string>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Default response codes for standard HTTP statuses
|
|
44
|
+
*/
|
|
45
|
+
export const DefaultResponseCode = {
|
|
46
|
+
SUCCESS: 'SUCCESS',
|
|
47
|
+
CREATED: 'CREATED',
|
|
48
|
+
BAD_REQUEST: 'BAD_REQUEST',
|
|
49
|
+
UNAUTHORIZED: 'UNAUTHORIZED',
|
|
50
|
+
FORBIDDEN: 'FORBIDDEN',
|
|
51
|
+
NOT_FOUND: 'NOT_FOUND',
|
|
52
|
+
CONFLICT: 'CONFLICT',
|
|
53
|
+
VALIDATION_ERROR: 'VALIDATION_ERROR',
|
|
54
|
+
INTERNAL_ERROR: 'INTERNAL_ERROR',
|
|
55
|
+
} as const;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Creates a standardized HTTP response.
|
|
59
|
+
* Automatically handles data/message normalization to ensure consistent structure.
|
|
60
|
+
*
|
|
61
|
+
* @param statusCode - HTTP status code
|
|
62
|
+
* @param data - Response payload (will be placed in 'data' field)
|
|
63
|
+
* @param code - Custom response code (Domain-specific)
|
|
64
|
+
* @param message - Optional message (if provided and data is null, message content will be put into 'data' for backward compatibility if needed, but the library now prefers explicit data)
|
|
65
|
+
* @param headers - Optional headers
|
|
66
|
+
*/
|
|
67
|
+
export function createStandardResponse<T, C = string>(
|
|
68
|
+
statusCode: number,
|
|
69
|
+
data?: T,
|
|
70
|
+
code?: C,
|
|
71
|
+
message?: string,
|
|
72
|
+
headers?: Record<string, string>
|
|
73
|
+
): HttpResponse {
|
|
74
|
+
const responseCode = code ?? (getDefaultCodeForStatus(statusCode) as unknown as C);
|
|
75
|
+
|
|
76
|
+
// Normalización automática:
|
|
77
|
+
// Si tenemos un mensaje pero no data, y el status es error,
|
|
78
|
+
// podríamos querer que el mensaje sea la descripción en data.
|
|
79
|
+
// Pero lo más limpio es seguir la estructura: { status, code, data, message }
|
|
80
|
+
|
|
81
|
+
const body: StandardResponse<T, C> = {
|
|
82
|
+
status: statusCode,
|
|
83
|
+
code: responseCode,
|
|
84
|
+
...(data !== undefined && { data }),
|
|
85
|
+
...(message && { message }),
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const corsOrigin = process.env.CORS_ALLOWED_ORIGINS || '*';
|
|
89
|
+
const corsHeaders = process.env.CORS_ALLOWED_HEADERS ||
|
|
90
|
+
'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token,appVersion,app-version,platform,geo,x-forwarded-for,x-real-ip';
|
|
91
|
+
const corsMethods = process.env.CORS_ALLOWED_METHODS || 'GET,POST,PUT,PATCH,DELETE,OPTIONS';
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
statusCode,
|
|
95
|
+
body: JSON.stringify(body, null, 2),
|
|
96
|
+
headers: {
|
|
97
|
+
'Content-Type': 'application/json',
|
|
98
|
+
'Access-Control-Allow-Origin': corsOrigin,
|
|
99
|
+
'Access-Control-Allow-Headers': corsHeaders,
|
|
100
|
+
'Access-Control-Allow-Methods': corsMethods,
|
|
101
|
+
...headers,
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Gets default response code for a status
|
|
108
|
+
*/
|
|
109
|
+
function getDefaultCodeForStatus(status: number): string {
|
|
110
|
+
switch (status) {
|
|
111
|
+
case HttpStatus.OK:
|
|
112
|
+
return DefaultResponseCode.SUCCESS;
|
|
113
|
+
case HttpStatus.CREATED:
|
|
114
|
+
return DefaultResponseCode.CREATED;
|
|
115
|
+
case HttpStatus.BAD_REQUEST:
|
|
116
|
+
return DefaultResponseCode.BAD_REQUEST;
|
|
117
|
+
case HttpStatus.UNAUTHORIZED:
|
|
118
|
+
return DefaultResponseCode.UNAUTHORIZED;
|
|
119
|
+
case HttpStatus.FORBIDDEN:
|
|
120
|
+
return DefaultResponseCode.FORBIDDEN;
|
|
121
|
+
case HttpStatus.NOT_FOUND:
|
|
122
|
+
return DefaultResponseCode.NOT_FOUND;
|
|
123
|
+
case HttpStatus.CONFLICT:
|
|
124
|
+
return DefaultResponseCode.CONFLICT;
|
|
125
|
+
case HttpStatus.UNPROCESSABLE_ENTITY:
|
|
126
|
+
return DefaultResponseCode.VALIDATION_ERROR;
|
|
127
|
+
default:
|
|
128
|
+
return DefaultResponseCode.INTERNAL_ERROR;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Success response (200 OK)
|
|
134
|
+
*/
|
|
135
|
+
export function successResponse<T, C = string>(data?: T, code?: C, headers?: Record<string, string>): HttpResponse {
|
|
136
|
+
return createStandardResponse(HttpStatus.OK, data, code, undefined, headers);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Created response (201 Created)
|
|
141
|
+
*/
|
|
142
|
+
export function createdResponse<T, C = string>(data?: T, code?: C, headers?: Record<string, string>): HttpResponse {
|
|
143
|
+
return createStandardResponse(HttpStatus.CREATED, data, code, undefined, headers);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Bad request response (400)
|
|
148
|
+
*/
|
|
149
|
+
export function badRequestResponse<C = string>(message?: string, code?: C, headers?: Record<string, string>): HttpResponse {
|
|
150
|
+
return createStandardResponse(HttpStatus.BAD_REQUEST, undefined, code, message, headers);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Unauthorized response (401)
|
|
155
|
+
*/
|
|
156
|
+
export function unauthorizedResponse<C = string>(message?: string, code?: C, headers?: Record<string, string>): HttpResponse {
|
|
157
|
+
return createStandardResponse(HttpStatus.UNAUTHORIZED, undefined, code, message, headers);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Forbidden response (403)
|
|
162
|
+
*/
|
|
163
|
+
export function forbiddenResponse<C = string>(message?: string, code?: C, headers?: Record<string, string>): HttpResponse {
|
|
164
|
+
return createStandardResponse(HttpStatus.FORBIDDEN, undefined, code, message, headers);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Not found response (404)
|
|
169
|
+
*/
|
|
170
|
+
export function notFoundResponse<C = string>(message?: string, code?: C, headers?: Record<string, string>): HttpResponse {
|
|
171
|
+
return createStandardResponse(HttpStatus.NOT_FOUND, undefined, code, message, headers);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Conflict response (409)
|
|
176
|
+
*/
|
|
177
|
+
export function conflictResponse<C = string>(message?: string, code?: C, headers?: Record<string, string>): HttpResponse {
|
|
178
|
+
return createStandardResponse(HttpStatus.CONFLICT, undefined, code, message, headers);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Validation error response (422)
|
|
183
|
+
*/
|
|
184
|
+
export function validationErrorResponse<C = string>(message?: string, code?: C, headers?: Record<string, string>): HttpResponse {
|
|
185
|
+
return createStandardResponse(HttpStatus.UNPROCESSABLE_ENTITY, undefined, code, message, headers);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Internal server error response (500)
|
|
190
|
+
*/
|
|
191
|
+
export function internalErrorResponse<C = string>(message?: string, code?: C, headers?: Record<string, string>): HttpResponse {
|
|
192
|
+
return createStandardResponse(HttpStatus.INTERNAL_SERVER_ERROR, undefined, code, message, headers);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Custom error response with automatic status resolution
|
|
197
|
+
* @param customCode - Your domain-specific error code
|
|
198
|
+
* @param message - Error message
|
|
199
|
+
* @param codeToStatusMap - Mapping of custom codes to HTTP statuses
|
|
200
|
+
*/
|
|
201
|
+
export function customErrorResponse<C extends string>(
|
|
202
|
+
customCode: C,
|
|
203
|
+
message?: string,
|
|
204
|
+
codeToStatusMap?: Record<C, HttpStatus>,
|
|
205
|
+
headers?: Record<string, string>
|
|
206
|
+
): HttpResponse {
|
|
207
|
+
const status = codeToStatusMap?.[customCode] ?? HttpStatus.INTERNAL_SERVER_ERROR;
|
|
208
|
+
return createStandardResponse(status, undefined, customCode, message, headers);
|
|
209
|
+
}
|