@naman_deep_singh/http-response 3.0.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 +189 -0
- package/dist/cjs/adapters/express/ExpressResponder.d.ts +18 -0
- package/dist/cjs/adapters/express/ExpressResponder.js +46 -0
- package/dist/cjs/constants/httpStatus.d.ts +54 -0
- package/dist/cjs/constants/httpStatus.js +34 -0
- package/dist/cjs/core/BaseResponder.d.ts +31 -0
- package/dist/cjs/core/BaseResponder.js +116 -0
- package/dist/cjs/core/config.d.ts +15 -0
- package/dist/cjs/core/config.js +15 -0
- package/dist/cjs/core/factory.d.ts +3 -0
- package/dist/cjs/core/factory.js +10 -0
- package/dist/cjs/core/types.d.ts +32 -0
- package/dist/cjs/core/types.js +2 -0
- package/dist/cjs/index.d.ts +8 -0
- package/dist/cjs/index.js +32 -0
- package/dist/cjs/legacy.d.ts +19 -0
- package/dist/cjs/legacy.js +23 -0
- package/dist/cjs/middleware/express/expressMiddleware.d.ts +3 -0
- package/dist/cjs/middleware/express/expressMiddleware.js +13 -0
- package/dist/esm/adapters/express/ExpressResponder.d.ts +18 -0
- package/dist/esm/adapters/express/ExpressResponder.js +42 -0
- package/dist/esm/constants/httpStatus.d.ts +54 -0
- package/dist/esm/constants/httpStatus.js +31 -0
- package/dist/esm/core/BaseResponder.d.ts +31 -0
- package/dist/esm/core/BaseResponder.js +112 -0
- package/dist/esm/core/config.d.ts +15 -0
- package/dist/esm/core/config.js +12 -0
- package/dist/esm/core/factory.d.ts +3 -0
- package/dist/esm/core/factory.js +6 -0
- package/dist/esm/core/types.d.ts +32 -0
- package/dist/esm/core/types.js +1 -0
- package/dist/esm/index.d.ts +8 -0
- package/dist/esm/index.js +10 -0
- package/dist/esm/legacy.d.ts +19 -0
- package/dist/esm/legacy.js +18 -0
- package/dist/esm/middleware/express/expressMiddleware.d.ts +3 -0
- package/dist/esm/middleware/express/expressMiddleware.js +9 -0
- package/dist/types/adapters/express/ExpressResponder.d.ts +18 -0
- package/dist/types/constants/httpStatus.d.ts +54 -0
- package/dist/types/core/BaseResponder.d.ts +31 -0
- package/dist/types/core/config.d.ts +15 -0
- package/dist/types/core/factory.d.ts +3 -0
- package/dist/types/core/types.d.ts +32 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/legacy.d.ts +19 -0
- package/dist/types/middleware/express/expressMiddleware.d.ts +3 -0
- package/package.json +53 -0
- package/src/adapters/express/ExpressResponder.ts +64 -0
- package/src/constants/httpStatus.ts +42 -0
- package/src/core/BaseResponder.ts +198 -0
- package/src/core/config.ts +29 -0
- package/src/core/factory.ts +11 -0
- package/src/core/types.ts +34 -0
- package/src/index.ts +13 -0
- package/src/middleware/express/expressMiddleware.ts +14 -0
- package/tsconfig.base.json +11 -0
- package/tsconfig.cjs.json +9 -0
- package/tsconfig.esm.json +9 -0
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@naman_deep_singh/http-response",
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "TypeScript utilities for standardized API responses",
|
|
5
|
+
"author": "Naman Deep Singh",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "./dist/cjs/index.js",
|
|
9
|
+
"module": "./dist/esm/index.js",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": "./dist/esm/index.js",
|
|
13
|
+
"require": "./dist/cjs/index.js",
|
|
14
|
+
"types": "./dist/types/index.d.ts"
|
|
15
|
+
},
|
|
16
|
+
"./express": {
|
|
17
|
+
"import": "./dist/esm/adapters/express/index.js",
|
|
18
|
+
"require": "./dist/cjs/adapters/express/index.js",
|
|
19
|
+
"types": "./dist/types/adapters/express/index.d.ts"
|
|
20
|
+
},
|
|
21
|
+
"./legacy": {
|
|
22
|
+
"import": "./dist/esm/legacy/index.js",
|
|
23
|
+
"require": "./dist/cjs/legacy/index.js",
|
|
24
|
+
"types": "./dist/types/legacy/index.d.ts"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"sideEffects": false,
|
|
28
|
+
"keywords": [
|
|
29
|
+
"response",
|
|
30
|
+
"http",
|
|
31
|
+
"api",
|
|
32
|
+
"utils",
|
|
33
|
+
"express",
|
|
34
|
+
"typescript"
|
|
35
|
+
],
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"express": "^5.1.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/express": "^5.0.5",
|
|
41
|
+
"express": "^5.1.0",
|
|
42
|
+
"typescript": "^5.9.3",
|
|
43
|
+
"rimraf": "^5.0.5"
|
|
44
|
+
},
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"access": "public"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "pnpm run build:types && tsc -p tsconfig.cjs.json && tsc -p tsconfig.esm.json",
|
|
50
|
+
"build:types": "tsc -p tsconfig.base.json --emitDeclarationOnly --outDir dist/types",
|
|
51
|
+
"clean": "rimraf dist"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { Response } from 'express'
|
|
2
|
+
import { BaseResponder } from '../../core/BaseResponder'
|
|
3
|
+
import type { ResponderConfig } from '../../core/config'
|
|
4
|
+
|
|
5
|
+
export class ExpressResponder<P = unknown> extends BaseResponder<P> {
|
|
6
|
+
constructor(
|
|
7
|
+
cfg: Partial<ResponderConfig> | undefined,
|
|
8
|
+
private readonly res: Response,
|
|
9
|
+
) {
|
|
10
|
+
// attach sender which calls res.status().json()
|
|
11
|
+
super(cfg, (status, body) => res.status(status).json(body))
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// convenience methods that return void for middleware/controller ergonomics
|
|
15
|
+
okAndSend(data?: P, message?: string) {
|
|
16
|
+
void this.ok(data, message)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
createdAndSend(data?: P, message?: string) {
|
|
20
|
+
void this.created(data, message)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
badRequestAndSend(message?: string, error?: unknown) {
|
|
24
|
+
void this.badRequest(message, error)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
unauthorizedAndSend(message?: string) {
|
|
28
|
+
void this.unauthorized(message)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
forbiddenAndSend(message?: string) {
|
|
32
|
+
void this.forbidden(message)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
notFoundAndSend(message?: string) {
|
|
36
|
+
void this.notFound(message)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
conflictAndSend(message?: string) {
|
|
40
|
+
void this.conflict(message)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
unprocessableEntityAndSend(message?: string, error?: unknown) {
|
|
44
|
+
void this.unprocessableEntity(message, error)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
tooManyRequestsAndSend(message?: string) {
|
|
48
|
+
void this.tooManyRequests(message)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
serverErrorAndSend(message?: string, error?: unknown) {
|
|
52
|
+
void this.serverError(message, error)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
paginateAndSend(
|
|
56
|
+
data: P[],
|
|
57
|
+
page: number,
|
|
58
|
+
limit: number,
|
|
59
|
+
total: number,
|
|
60
|
+
message?: string,
|
|
61
|
+
) {
|
|
62
|
+
void this.paginate(data, page, limit, total, message)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const SUCCESS = Object.freeze({
|
|
2
|
+
OK: 200,
|
|
3
|
+
CREATED: 201,
|
|
4
|
+
ACCEPTED: 202,
|
|
5
|
+
NO_CONTENT: 204,
|
|
6
|
+
} as const)
|
|
7
|
+
|
|
8
|
+
const REDIRECTION = Object.freeze({
|
|
9
|
+
NOT_MODIFIED: 304,
|
|
10
|
+
} as const)
|
|
11
|
+
|
|
12
|
+
const CLIENT_ERROR = Object.freeze({
|
|
13
|
+
BAD_REQUEST: 400,
|
|
14
|
+
UNAUTHORIZED: 401,
|
|
15
|
+
FORBIDDEN: 403,
|
|
16
|
+
NOT_FOUND: 404,
|
|
17
|
+
METHOD_NOT_ALLOWED: 405,
|
|
18
|
+
CONFLICT: 409,
|
|
19
|
+
UNPROCESSABLE_ENTITY: 422,
|
|
20
|
+
TOO_MANY_REQUESTS: 429,
|
|
21
|
+
} as const)
|
|
22
|
+
|
|
23
|
+
const SERVER_ERROR = Object.freeze({
|
|
24
|
+
INTERNAL_SERVER_ERROR: 500,
|
|
25
|
+
NOT_IMPLEMENTED: 501,
|
|
26
|
+
BAD_GATEWAY: 502,
|
|
27
|
+
SERVICE_UNAVAILABLE: 503,
|
|
28
|
+
} as const)
|
|
29
|
+
|
|
30
|
+
export const HTTP_STATUS = Object.freeze({
|
|
31
|
+
SUCCESS,
|
|
32
|
+
REDIRECTION,
|
|
33
|
+
CLIENT_ERROR,
|
|
34
|
+
SERVER_ERROR,
|
|
35
|
+
} as const)
|
|
36
|
+
|
|
37
|
+
// flattened union type if needed:
|
|
38
|
+
export type HttpStatusCode =
|
|
39
|
+
| (typeof SUCCESS)[keyof typeof SUCCESS]
|
|
40
|
+
| (typeof REDIRECTION)[keyof typeof REDIRECTION]
|
|
41
|
+
| (typeof CLIENT_ERROR)[keyof typeof CLIENT_ERROR]
|
|
42
|
+
| (typeof SERVER_ERROR)[keyof typeof SERVER_ERROR]
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { HTTP_STATUS } from '../constants/httpStatus'
|
|
2
|
+
|
|
3
|
+
import { type ResponderConfig, defaultConfig } from './config'
|
|
4
|
+
|
|
5
|
+
import type { PaginationMeta, ResponseEnvelope, Sender } from './types'
|
|
6
|
+
|
|
7
|
+
export class BaseResponder<P = unknown, M = PaginationMeta> {
|
|
8
|
+
protected readonly cfg: ResponderConfig
|
|
9
|
+
protected sender?: Sender
|
|
10
|
+
|
|
11
|
+
constructor(cfg?: Partial<ResponderConfig>, sender?: Sender) {
|
|
12
|
+
this.cfg = { ...defaultConfig, ...(cfg ?? {}) }
|
|
13
|
+
this.sender = sender
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
attachSender(sender: Sender) {
|
|
17
|
+
this.sender = sender
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
protected normalizeError(err: unknown): {
|
|
21
|
+
message: string
|
|
22
|
+
code?: string
|
|
23
|
+
details?: unknown
|
|
24
|
+
} {
|
|
25
|
+
// errors-utils AppError compatibility
|
|
26
|
+
if (typeof err === 'object' && err !== null) {
|
|
27
|
+
const e = err as Record<string, unknown>
|
|
28
|
+
|
|
29
|
+
if (typeof e.message === 'string') {
|
|
30
|
+
return {
|
|
31
|
+
message: e.message,
|
|
32
|
+
code: typeof e.code === 'string' ? e.code : undefined,
|
|
33
|
+
details: e.details,
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (err instanceof Error) {
|
|
39
|
+
return { message: err.message }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (typeof err === 'string') {
|
|
43
|
+
return { message: err }
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
message: 'Internal server error',
|
|
48
|
+
details: err,
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
protected buildEnvelope(
|
|
53
|
+
data?: P,
|
|
54
|
+
message?: string,
|
|
55
|
+
error?: unknown,
|
|
56
|
+
meta?: M,
|
|
57
|
+
) {
|
|
58
|
+
const env: ResponseEnvelope<P, M> = {
|
|
59
|
+
success: !error,
|
|
60
|
+
message: message ?? (error ? 'Error' : undefined),
|
|
61
|
+
data: error ? undefined : data,
|
|
62
|
+
error: error ? this.normalizeError(error) : null,
|
|
63
|
+
meta: meta ?? null,
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (this.cfg.timestamp) {
|
|
67
|
+
env.meta = {
|
|
68
|
+
...(env.meta ?? {}),
|
|
69
|
+
timestamp: new Date().toISOString(),
|
|
70
|
+
} as M
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (this.cfg.extra) {
|
|
74
|
+
Object.assign(env as Record<string, unknown>, this.cfg.extra)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return env
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
protected send(status: number, envelope: ResponseEnvelope<P, M>) {
|
|
81
|
+
if (!this.sender) return { status, body: envelope }
|
|
82
|
+
return this.sender(status, envelope)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** -----------------------------
|
|
86
|
+
* Standard REST Response Helpers
|
|
87
|
+
* ----------------------------- */
|
|
88
|
+
ok(data?: P, message = 'Success') {
|
|
89
|
+
return this.send(HTTP_STATUS.SUCCESS.OK, this.buildEnvelope(data, message))
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
created(data?: P, message = 'Created successfully') {
|
|
93
|
+
return this.send(
|
|
94
|
+
HTTP_STATUS.SUCCESS.CREATED,
|
|
95
|
+
this.buildEnvelope(data, message),
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
noContent(message = 'No Content') {
|
|
100
|
+
return this.send(
|
|
101
|
+
HTTP_STATUS.SUCCESS.NO_CONTENT,
|
|
102
|
+
this.buildEnvelope(undefined, message),
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
badRequest(message = 'Bad request', error?: unknown) {
|
|
107
|
+
return this.send(
|
|
108
|
+
HTTP_STATUS.CLIENT_ERROR.BAD_REQUEST,
|
|
109
|
+
this.buildEnvelope(undefined, message, error),
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
unauthorized(message = 'Unauthorized') {
|
|
114
|
+
return this.send(
|
|
115
|
+
HTTP_STATUS.CLIENT_ERROR.UNAUTHORIZED,
|
|
116
|
+
this.buildEnvelope(undefined, message),
|
|
117
|
+
)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
forbidden(message = 'Forbidden') {
|
|
121
|
+
return this.send(
|
|
122
|
+
HTTP_STATUS.CLIENT_ERROR.FORBIDDEN,
|
|
123
|
+
this.buildEnvelope(undefined, message),
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
notFound(message = 'Not found') {
|
|
128
|
+
return this.send(
|
|
129
|
+
HTTP_STATUS.CLIENT_ERROR.NOT_FOUND,
|
|
130
|
+
this.buildEnvelope(undefined, message),
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
conflict(message = 'Conflict') {
|
|
135
|
+
return this.send(
|
|
136
|
+
HTTP_STATUS.CLIENT_ERROR.CONFLICT,
|
|
137
|
+
this.buildEnvelope(undefined, message),
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
unprocessableEntity(message = 'Unprocessable Entity', error?: unknown) {
|
|
142
|
+
return this.send(
|
|
143
|
+
HTTP_STATUS.CLIENT_ERROR.UNPROCESSABLE_ENTITY,
|
|
144
|
+
this.buildEnvelope(undefined, message, error),
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
tooManyRequests(message = 'Too Many Requests') {
|
|
149
|
+
return this.send(
|
|
150
|
+
HTTP_STATUS.CLIENT_ERROR.TOO_MANY_REQUESTS,
|
|
151
|
+
this.buildEnvelope(undefined, message),
|
|
152
|
+
)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
serverError(message = 'Internal server error', error?: unknown) {
|
|
156
|
+
return this.send(
|
|
157
|
+
HTTP_STATUS.SERVER_ERROR.INTERNAL_SERVER_ERROR,
|
|
158
|
+
this.buildEnvelope(undefined, message, error),
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
paginate(
|
|
163
|
+
data: P[],
|
|
164
|
+
page: number,
|
|
165
|
+
limit: number,
|
|
166
|
+
total: number,
|
|
167
|
+
message = 'Success',
|
|
168
|
+
) {
|
|
169
|
+
const totalPages = Math.max(1, Math.ceil(total / limit))
|
|
170
|
+
const offset = (page - 1) * limit
|
|
171
|
+
|
|
172
|
+
const pagination: PaginationMeta = {
|
|
173
|
+
page,
|
|
174
|
+
limit,
|
|
175
|
+
total,
|
|
176
|
+
totalPages,
|
|
177
|
+
offset,
|
|
178
|
+
hasNext: page < totalPages,
|
|
179
|
+
hasPrev: page > 1,
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return this.send(
|
|
183
|
+
HTTP_STATUS.SUCCESS.OK,
|
|
184
|
+
this.buildEnvelope(data as any, message, undefined, pagination as any),
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
paginateOffset(
|
|
189
|
+
data: P[],
|
|
190
|
+
offset: number,
|
|
191
|
+
limit: number,
|
|
192
|
+
total: number,
|
|
193
|
+
message = 'Success',
|
|
194
|
+
) {
|
|
195
|
+
const page = Math.floor(offset / limit) + 1
|
|
196
|
+
return this.paginate(data, page, limit, total, message)
|
|
197
|
+
}
|
|
198
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { PlainObject } from './types'
|
|
2
|
+
|
|
3
|
+
export type EnvelopeKeys = {
|
|
4
|
+
success?: string
|
|
5
|
+
message?: string
|
|
6
|
+
data?: string
|
|
7
|
+
error?: string
|
|
8
|
+
meta?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type ResponderConfig = {
|
|
12
|
+
envelopeKeys?: EnvelopeKeys
|
|
13
|
+
defaultStatus?: number
|
|
14
|
+
timestamp?: boolean
|
|
15
|
+
extra?: PlainObject | null
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const defaultConfig: ResponderConfig = {
|
|
19
|
+
envelopeKeys: {
|
|
20
|
+
success: 'success',
|
|
21
|
+
message: 'message',
|
|
22
|
+
data: 'data',
|
|
23
|
+
error: 'error',
|
|
24
|
+
meta: 'meta',
|
|
25
|
+
},
|
|
26
|
+
defaultStatus: 200,
|
|
27
|
+
timestamp: false,
|
|
28
|
+
extra: null,
|
|
29
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ExpressResponder } from '../adapters/express/ExpressResponder'
|
|
2
|
+
|
|
3
|
+
import type { ResponderConfig } from './config'
|
|
4
|
+
|
|
5
|
+
export const createResponderFactory = (cfg?: Partial<ResponderConfig>) => {
|
|
6
|
+
return <P = unknown, _M = Record<string, unknown>>(
|
|
7
|
+
res: import('express').Response,
|
|
8
|
+
) => {
|
|
9
|
+
return new ExpressResponder<P>(cfg, res)
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export type PlainObject = Record<string, unknown>
|
|
2
|
+
|
|
3
|
+
export type ErrorShape = {
|
|
4
|
+
code?: string
|
|
5
|
+
message: string
|
|
6
|
+
details?: unknown
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type ResponseEnvelope<T = unknown, M = PlainObject> = {
|
|
10
|
+
success: boolean
|
|
11
|
+
message?: string
|
|
12
|
+
data?: T
|
|
13
|
+
error?: ErrorShape | null
|
|
14
|
+
meta?: M | null
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type TransportResult = { status: number; body: unknown }
|
|
18
|
+
|
|
19
|
+
export type Sender = (status: number, body: unknown) => Promise<any> | any
|
|
20
|
+
|
|
21
|
+
export interface PaginationMeta {
|
|
22
|
+
page: number
|
|
23
|
+
limit: number
|
|
24
|
+
total: number
|
|
25
|
+
totalPages: number
|
|
26
|
+
hasNext?: boolean
|
|
27
|
+
hasPrev?: boolean
|
|
28
|
+
offset?: number
|
|
29
|
+
links?: {
|
|
30
|
+
next?: string
|
|
31
|
+
prev?: string
|
|
32
|
+
self: string
|
|
33
|
+
}
|
|
34
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Core Responders
|
|
2
|
+
export { BaseResponder } from './core/BaseResponder'
|
|
3
|
+
export { createResponderFactory } from './core/factory'
|
|
4
|
+
export * from './core/types'
|
|
5
|
+
export * from './core/config'
|
|
6
|
+
|
|
7
|
+
// Adapters (Express)
|
|
8
|
+
export { ExpressResponder } from './adapters/express/ExpressResponder'
|
|
9
|
+
export { responderMiddleware } from './middleware/express/expressMiddleware'
|
|
10
|
+
|
|
11
|
+
// HTTP Status Constants
|
|
12
|
+
export { HTTP_STATUS } from './constants/httpStatus'
|
|
13
|
+
export type { HttpStatusCode } from './constants/httpStatus'
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { RequestHandler } from 'express'
|
|
2
|
+
import type { ResponderConfig } from '../../core/config'
|
|
3
|
+
import { createResponderFactory } from '../../core/factory'
|
|
4
|
+
|
|
5
|
+
export const responderMiddleware = (
|
|
6
|
+
cfg?: Partial<ResponderConfig>,
|
|
7
|
+
): RequestHandler => {
|
|
8
|
+
const factory = createResponderFactory(cfg)
|
|
9
|
+
|
|
10
|
+
return (_req, res, next) => {
|
|
11
|
+
;(res as any).responder = <P = unknown>() => factory<P>(res)
|
|
12
|
+
next()
|
|
13
|
+
}
|
|
14
|
+
}
|