0http-bun 1.1.3 → 1.2.1
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 +72 -3
- package/common.d.ts +37 -2
- package/lib/middleware/README.md +870 -0
- package/lib/middleware/body-parser.js +783 -0
- package/lib/middleware/cors.js +225 -0
- package/lib/middleware/index.d.ts +236 -0
- package/lib/middleware/index.js +45 -0
- package/lib/middleware/jwt-auth.js +406 -0
- package/lib/middleware/logger.js +310 -0
- package/lib/middleware/rate-limit.js +270 -0
- package/lib/router/sequential.js +10 -2
- package/package.json +6 -3
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates CORS (Cross-Origin Resource Sharing) middleware
|
|
3
|
+
* @param {Object} options - CORS configuration options
|
|
4
|
+
* @param {string|Array<string>|Function} options.origin - Allowed origins
|
|
5
|
+
* @param {Array<string>} options.methods - Allowed HTTP methods
|
|
6
|
+
* @param {Array<string>} options.allowedHeaders - Allowed request headers
|
|
7
|
+
* @param {Array<string>} options.exposedHeaders - Headers exposed to the client
|
|
8
|
+
* @param {boolean} options.credentials - Whether to include credentials
|
|
9
|
+
* @param {number} options.maxAge - Preflight cache time in seconds
|
|
10
|
+
* @param {boolean} options.preflightContinue - Pass control to next handler after preflight
|
|
11
|
+
* @param {number} options.optionsSuccessStatus - Status code for successful OPTIONS requests
|
|
12
|
+
* @returns {Function} Middleware function
|
|
13
|
+
*/
|
|
14
|
+
function createCORS(options = {}) {
|
|
15
|
+
const {
|
|
16
|
+
origin = '*',
|
|
17
|
+
methods = ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE'],
|
|
18
|
+
allowedHeaders = ['Content-Type', 'Authorization'],
|
|
19
|
+
exposedHeaders = [],
|
|
20
|
+
credentials = false,
|
|
21
|
+
maxAge = 86400, // 24 hours
|
|
22
|
+
preflightContinue = false,
|
|
23
|
+
optionsSuccessStatus = 204,
|
|
24
|
+
} = options
|
|
25
|
+
|
|
26
|
+
return function corsMiddleware(req, next) {
|
|
27
|
+
const requestOrigin = req.headers.get('origin')
|
|
28
|
+
const allowedOrigin = getAllowedOrigin(origin, requestOrigin, req)
|
|
29
|
+
|
|
30
|
+
const addCorsHeaders = (response) => {
|
|
31
|
+
// Add Vary header for dynamic origins (regardless of whether origin is allowed)
|
|
32
|
+
if (typeof origin === 'function' || Array.isArray(origin)) {
|
|
33
|
+
const existingVary = response.headers.get('Vary')
|
|
34
|
+
if (existingVary) {
|
|
35
|
+
if (!existingVary.includes('Origin')) {
|
|
36
|
+
response.headers.set('Vary', `${existingVary}, Origin`)
|
|
37
|
+
}
|
|
38
|
+
} else {
|
|
39
|
+
response.headers.set('Vary', 'Origin')
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (allowedOrigin !== false) {
|
|
44
|
+
response.headers.set('Access-Control-Allow-Origin', allowedOrigin)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Don't allow wildcard origin with credentials
|
|
48
|
+
if (credentials && allowedOrigin !== '*') {
|
|
49
|
+
response.headers.set('Access-Control-Allow-Credentials', 'true')
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Handle exposedHeaders (can be string or array)
|
|
53
|
+
const exposedHeadersList = Array.isArray(exposedHeaders)
|
|
54
|
+
? exposedHeaders
|
|
55
|
+
: typeof exposedHeaders === 'string'
|
|
56
|
+
? [exposedHeaders]
|
|
57
|
+
: []
|
|
58
|
+
if (exposedHeadersList.length > 0) {
|
|
59
|
+
response.headers.set(
|
|
60
|
+
'Access-Control-Expose-Headers',
|
|
61
|
+
exposedHeadersList.join(', '),
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Add method and header info for all requests (not just OPTIONS)
|
|
66
|
+
response.headers.set(
|
|
67
|
+
'Access-Control-Allow-Methods',
|
|
68
|
+
(Array.isArray(methods) ? methods : [methods]).join(', '),
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
const resolvedAllowedHeaders =
|
|
72
|
+
typeof allowedHeaders === 'function'
|
|
73
|
+
? allowedHeaders(req)
|
|
74
|
+
: allowedHeaders
|
|
75
|
+
const allowedHeadersList = Array.isArray(resolvedAllowedHeaders)
|
|
76
|
+
? resolvedAllowedHeaders
|
|
77
|
+
: typeof resolvedAllowedHeaders === 'string'
|
|
78
|
+
? [resolvedAllowedHeaders]
|
|
79
|
+
: []
|
|
80
|
+
response.headers.set(
|
|
81
|
+
'Access-Control-Allow-Headers',
|
|
82
|
+
allowedHeadersList.join(', '),
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
return response
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (req.method === 'OPTIONS') {
|
|
89
|
+
// Handle preflight request
|
|
90
|
+
const requestMethod = req.headers.get('access-control-request-method')
|
|
91
|
+
const requestHeaders = req.headers.get('access-control-request-headers')
|
|
92
|
+
|
|
93
|
+
// Check if requested method is allowed
|
|
94
|
+
if (requestMethod && !methods.includes(requestMethod)) {
|
|
95
|
+
return new Response(null, {status: 404})
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Check if requested headers are allowed
|
|
99
|
+
if (requestHeaders) {
|
|
100
|
+
const requestedHeaders = requestHeaders.split(',').map((h) => h.trim())
|
|
101
|
+
const resolvedAllowedHeaders =
|
|
102
|
+
typeof allowedHeaders === 'function'
|
|
103
|
+
? allowedHeaders(req)
|
|
104
|
+
: allowedHeaders
|
|
105
|
+
const allowedHeadersList = Array.isArray(resolvedAllowedHeaders)
|
|
106
|
+
? resolvedAllowedHeaders
|
|
107
|
+
: []
|
|
108
|
+
|
|
109
|
+
const hasDisallowedHeaders = requestedHeaders.some(
|
|
110
|
+
(header) =>
|
|
111
|
+
!allowedHeadersList.some(
|
|
112
|
+
(allowed) => allowed.toLowerCase() === header.toLowerCase(),
|
|
113
|
+
),
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
if (hasDisallowedHeaders) {
|
|
117
|
+
return new Response(null, {status: 404})
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const response = new Response(null, {status: optionsSuccessStatus})
|
|
122
|
+
|
|
123
|
+
if (allowedOrigin !== false) {
|
|
124
|
+
response.headers.set('Access-Control-Allow-Origin', allowedOrigin)
|
|
125
|
+
|
|
126
|
+
// Add Vary header for dynamic origins
|
|
127
|
+
if (typeof origin === 'function' || Array.isArray(origin)) {
|
|
128
|
+
response.headers.set('Vary', 'Origin')
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Don't allow wildcard origin with credentials
|
|
133
|
+
if (credentials && allowedOrigin !== '*') {
|
|
134
|
+
response.headers.set('Access-Control-Allow-Credentials', 'true')
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
response.headers.set(
|
|
138
|
+
'Access-Control-Allow-Methods',
|
|
139
|
+
(Array.isArray(methods) ? methods : [methods]).join(', '),
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
const resolvedAllowedHeaders =
|
|
143
|
+
typeof allowedHeaders === 'function'
|
|
144
|
+
? allowedHeaders(req)
|
|
145
|
+
: allowedHeaders
|
|
146
|
+
const allowedHeadersList = Array.isArray(resolvedAllowedHeaders)
|
|
147
|
+
? resolvedAllowedHeaders
|
|
148
|
+
: []
|
|
149
|
+
response.headers.set(
|
|
150
|
+
'Access-Control-Allow-Headers',
|
|
151
|
+
allowedHeadersList.join(', '),
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
response.headers.set('Access-Control-Max-Age', maxAge.toString())
|
|
155
|
+
|
|
156
|
+
if (preflightContinue) {
|
|
157
|
+
const result = next()
|
|
158
|
+
if (result instanceof Promise) {
|
|
159
|
+
return result.then(addCorsHeaders)
|
|
160
|
+
}
|
|
161
|
+
return addCorsHeaders(result)
|
|
162
|
+
} else {
|
|
163
|
+
return response
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const result = next()
|
|
168
|
+
if (result instanceof Promise) {
|
|
169
|
+
return result.then(addCorsHeaders)
|
|
170
|
+
}
|
|
171
|
+
return addCorsHeaders(result)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Determines the allowed origin for CORS
|
|
177
|
+
* @param {string|Array<string>|Function} origin - Origin configuration
|
|
178
|
+
* @param {string} requestOrigin - Origin from request header
|
|
179
|
+
* @param {Request} req - Request object
|
|
180
|
+
* @returns {string|false} Allowed origin or false if not allowed
|
|
181
|
+
*/
|
|
182
|
+
function getAllowedOrigin(origin, requestOrigin, req) {
|
|
183
|
+
if (origin === '*') {
|
|
184
|
+
return '*'
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (origin === false) {
|
|
188
|
+
return false
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (typeof origin === 'string') {
|
|
192
|
+
return origin === requestOrigin ? requestOrigin : false
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (Array.isArray(origin)) {
|
|
196
|
+
return origin.includes(requestOrigin) ? requestOrigin : false
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (typeof origin === 'function') {
|
|
200
|
+
const result = origin(requestOrigin)
|
|
201
|
+
return result === true ? requestOrigin : result || false
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return false
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Simple CORS middleware for development
|
|
209
|
+
* Allows all origins, methods, and headers
|
|
210
|
+
* @returns {Function} Middleware function
|
|
211
|
+
*/
|
|
212
|
+
function simpleCORS() {
|
|
213
|
+
return createCORS({
|
|
214
|
+
origin: '*',
|
|
215
|
+
methods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE', 'OPTIONS'],
|
|
216
|
+
allowedHeaders: ['*'],
|
|
217
|
+
credentials: false,
|
|
218
|
+
})
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
module.exports = {
|
|
222
|
+
createCORS,
|
|
223
|
+
simpleCORS,
|
|
224
|
+
getAllowedOrigin,
|
|
225
|
+
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import {RequestHandler, ZeroRequest, StepFunction} from '../../common'
|
|
2
|
+
import {Logger} from 'pino'
|
|
3
|
+
|
|
4
|
+
// Logger middleware types
|
|
5
|
+
export interface LoggerOptions {
|
|
6
|
+
pinoOptions?: any
|
|
7
|
+
serializers?: Record<string, (obj: any) => any>
|
|
8
|
+
logBody?: boolean
|
|
9
|
+
excludePaths?: string[]
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function createLogger(options?: LoggerOptions): RequestHandler
|
|
13
|
+
export function simpleLogger(): RequestHandler
|
|
14
|
+
|
|
15
|
+
// JWT Authentication middleware types
|
|
16
|
+
export interface JWKSLike {
|
|
17
|
+
getKey?: (protectedHeader: any, token: string) => Promise<any>
|
|
18
|
+
[key: string]: any
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface JWTAuthOptions {
|
|
22
|
+
secret?:
|
|
23
|
+
| string
|
|
24
|
+
| Uint8Array
|
|
25
|
+
| ((req: ZeroRequest) => Promise<string | Uint8Array>)
|
|
26
|
+
| ((protectedHeader: any, token: string) => Promise<string | Uint8Array>)
|
|
27
|
+
jwksUri?: string
|
|
28
|
+
jwks?: JWKSLike
|
|
29
|
+
jwtOptions?: {
|
|
30
|
+
algorithms?: string[]
|
|
31
|
+
audience?: string | string[]
|
|
32
|
+
issuer?: string | string[]
|
|
33
|
+
subject?: string
|
|
34
|
+
clockTolerance?: number
|
|
35
|
+
maxTokenAge?: number
|
|
36
|
+
}
|
|
37
|
+
// Token extraction options
|
|
38
|
+
getToken?: (req: ZeroRequest) => string | null
|
|
39
|
+
tokenHeader?: string
|
|
40
|
+
tokenQuery?: string
|
|
41
|
+
// Authentication behavior options
|
|
42
|
+
optional?: boolean
|
|
43
|
+
excludePaths?: string[]
|
|
44
|
+
// API key authentication options
|
|
45
|
+
apiKeys?:
|
|
46
|
+
| string
|
|
47
|
+
| string[]
|
|
48
|
+
| ((
|
|
49
|
+
key: string,
|
|
50
|
+
req: ZeroRequest,
|
|
51
|
+
) => Promise<boolean | any> | boolean | any)
|
|
52
|
+
apiKeyHeader?: string
|
|
53
|
+
apiKeyValidator?:
|
|
54
|
+
| ((key: string) => Promise<boolean | any> | boolean | any)
|
|
55
|
+
| ((
|
|
56
|
+
key: string,
|
|
57
|
+
req: ZeroRequest,
|
|
58
|
+
) => Promise<boolean | any> | boolean | any)
|
|
59
|
+
validateApiKey?:
|
|
60
|
+
| ((key: string) => Promise<boolean | any> | boolean | any)
|
|
61
|
+
| ((
|
|
62
|
+
key: string,
|
|
63
|
+
req: ZeroRequest,
|
|
64
|
+
) => Promise<boolean | any> | boolean | any)
|
|
65
|
+
// JWT specific options (can also be in jwtOptions)
|
|
66
|
+
audience?: string | string[]
|
|
67
|
+
issuer?: string
|
|
68
|
+
algorithms?: string[]
|
|
69
|
+
// Custom response and error handling
|
|
70
|
+
unauthorizedResponse?:
|
|
71
|
+
| Response
|
|
72
|
+
| ((error: Error, req: ZeroRequest) => Response | any)
|
|
73
|
+
| {
|
|
74
|
+
status?: number
|
|
75
|
+
body?: any
|
|
76
|
+
headers?: Record<string, string>
|
|
77
|
+
}
|
|
78
|
+
onError?: (error: Error, req: ZeroRequest) => Response | any
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface APIKeyAuthOptions {
|
|
82
|
+
keys:
|
|
83
|
+
| string
|
|
84
|
+
| string[]
|
|
85
|
+
| ((key: string, req: ZeroRequest) => Promise<boolean> | boolean)
|
|
86
|
+
header?: string
|
|
87
|
+
getKey?: (req: ZeroRequest) => string | null
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface TokenExtractionOptions {
|
|
91
|
+
getToken?: (req: ZeroRequest) => string | null
|
|
92
|
+
tokenHeader?: string
|
|
93
|
+
tokenQuery?: string
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function createJWTAuth(options?: JWTAuthOptions): RequestHandler
|
|
97
|
+
export function createAPIKeyAuth(options: APIKeyAuthOptions): RequestHandler
|
|
98
|
+
export function extractTokenFromHeader(req: ZeroRequest): string | null
|
|
99
|
+
export function extractToken(
|
|
100
|
+
req: ZeroRequest,
|
|
101
|
+
options?: TokenExtractionOptions,
|
|
102
|
+
): string | null
|
|
103
|
+
export function validateApiKeyInternal(
|
|
104
|
+
apiKey: string,
|
|
105
|
+
apiKeys: JWTAuthOptions['apiKeys'],
|
|
106
|
+
apiKeyValidator: JWTAuthOptions['apiKeyValidator'],
|
|
107
|
+
req: ZeroRequest,
|
|
108
|
+
): Promise<boolean | any>
|
|
109
|
+
export function handleAuthError(
|
|
110
|
+
error: Error,
|
|
111
|
+
handlers: {
|
|
112
|
+
unauthorizedResponse?: JWTAuthOptions['unauthorizedResponse']
|
|
113
|
+
onError?: JWTAuthOptions['onError']
|
|
114
|
+
},
|
|
115
|
+
req: ZeroRequest,
|
|
116
|
+
): Response
|
|
117
|
+
|
|
118
|
+
// Rate limiting middleware types
|
|
119
|
+
export interface RateLimitOptions {
|
|
120
|
+
windowMs?: number
|
|
121
|
+
max?: number
|
|
122
|
+
keyGenerator?: (req: ZeroRequest) => Promise<string> | string
|
|
123
|
+
handler?: (
|
|
124
|
+
req: ZeroRequest,
|
|
125
|
+
totalHits: number,
|
|
126
|
+
max: number,
|
|
127
|
+
resetTime: Date,
|
|
128
|
+
) => Promise<Response> | Response
|
|
129
|
+
store?: RateLimitStore
|
|
130
|
+
standardHeaders?: boolean
|
|
131
|
+
excludePaths?: string[]
|
|
132
|
+
skip?: (req: ZeroRequest) => boolean
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export interface RateLimitStore {
|
|
136
|
+
increment(
|
|
137
|
+
key: string,
|
|
138
|
+
windowMs: number,
|
|
139
|
+
): Promise<{totalHits: number; resetTime: Date}>
|
|
140
|
+
reset(key: string): Promise<void>
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export class MemoryStore implements RateLimitStore {
|
|
144
|
+
constructor()
|
|
145
|
+
increment(
|
|
146
|
+
key: string,
|
|
147
|
+
windowMs: number,
|
|
148
|
+
): Promise<{totalHits: number; resetTime: Date}>
|
|
149
|
+
reset(key: string): Promise<void>
|
|
150
|
+
cleanup(now: number): void
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function createRateLimit(options?: RateLimitOptions): RequestHandler
|
|
154
|
+
export function createSlidingWindowRateLimit(
|
|
155
|
+
options?: RateLimitOptions,
|
|
156
|
+
): RequestHandler
|
|
157
|
+
export function defaultKeyGenerator(req: ZeroRequest): string
|
|
158
|
+
export function defaultHandler(
|
|
159
|
+
req: ZeroRequest,
|
|
160
|
+
totalHits: number,
|
|
161
|
+
max: number,
|
|
162
|
+
resetTime: Date,
|
|
163
|
+
): Response
|
|
164
|
+
|
|
165
|
+
// CORS middleware types
|
|
166
|
+
export interface CORSOptions {
|
|
167
|
+
origin?:
|
|
168
|
+
| string
|
|
169
|
+
| string[]
|
|
170
|
+
| boolean
|
|
171
|
+
| ((origin: string, req: ZeroRequest) => boolean | string)
|
|
172
|
+
methods?: string[]
|
|
173
|
+
allowedHeaders?: string[]
|
|
174
|
+
exposedHeaders?: string[]
|
|
175
|
+
credentials?: boolean
|
|
176
|
+
maxAge?: number
|
|
177
|
+
preflightContinue?: boolean
|
|
178
|
+
optionsSuccessStatus?: number
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export function createCORS(options?: CORSOptions): RequestHandler
|
|
182
|
+
export function simpleCORS(): RequestHandler
|
|
183
|
+
export function getAllowedOrigin(
|
|
184
|
+
origin: any,
|
|
185
|
+
requestOrigin: string,
|
|
186
|
+
req: ZeroRequest,
|
|
187
|
+
): string | false
|
|
188
|
+
|
|
189
|
+
// Body parser middleware types
|
|
190
|
+
export interface JSONParserOptions {
|
|
191
|
+
limit?: number
|
|
192
|
+
reviver?: (key: string, value: any) => any
|
|
193
|
+
strict?: boolean
|
|
194
|
+
type?: string
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export interface TextParserOptions {
|
|
198
|
+
limit?: number
|
|
199
|
+
type?: string
|
|
200
|
+
defaultCharset?: string
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export interface URLEncodedParserOptions {
|
|
204
|
+
limit?: number
|
|
205
|
+
extended?: boolean
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export interface MultipartParserOptions {
|
|
209
|
+
limit?: number
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export interface BodyParserOptions {
|
|
213
|
+
json?: JSONParserOptions
|
|
214
|
+
text?: TextParserOptions
|
|
215
|
+
urlencoded?: URLEncodedParserOptions
|
|
216
|
+
multipart?: MultipartParserOptions
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export interface ParsedFile {
|
|
220
|
+
name: string
|
|
221
|
+
size: number
|
|
222
|
+
type: string
|
|
223
|
+
data: File
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export function createJSONParser(options?: JSONParserOptions): RequestHandler
|
|
227
|
+
export function createTextParser(options?: TextParserOptions): RequestHandler
|
|
228
|
+
export function createURLEncodedParser(
|
|
229
|
+
options?: URLEncodedParserOptions,
|
|
230
|
+
): RequestHandler
|
|
231
|
+
export function createMultipartParser(
|
|
232
|
+
options?: MultipartParserOptions,
|
|
233
|
+
): RequestHandler
|
|
234
|
+
export function createBodyParser(options?: BodyParserOptions): RequestHandler
|
|
235
|
+
export function hasBody(req: ZeroRequest): boolean
|
|
236
|
+
export function shouldParse(req: ZeroRequest, type: string): boolean
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Export all middleware modules
|
|
2
|
+
const loggerModule = require('./logger')
|
|
3
|
+
const jwtAuthModule = require('./jwt-auth')
|
|
4
|
+
const rateLimitModule = require('./rate-limit')
|
|
5
|
+
const corsModule = require('./cors')
|
|
6
|
+
const bodyParserModule = require('./body-parser')
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
// Simple interface for common use cases (matches test expectations)
|
|
10
|
+
logger: loggerModule.createLogger,
|
|
11
|
+
jwtAuth: jwtAuthModule.createJWTAuth,
|
|
12
|
+
rateLimit: rateLimitModule.createRateLimit,
|
|
13
|
+
cors: corsModule.createCORS,
|
|
14
|
+
bodyParser: bodyParserModule.createBodyParser,
|
|
15
|
+
|
|
16
|
+
// Complete factory functions for advanced usage
|
|
17
|
+
createLogger: loggerModule.createLogger,
|
|
18
|
+
simpleLogger: loggerModule.simpleLogger,
|
|
19
|
+
|
|
20
|
+
// Authentication middleware
|
|
21
|
+
createJWTAuth: jwtAuthModule.createJWTAuth,
|
|
22
|
+
createAPIKeyAuth: jwtAuthModule.createAPIKeyAuth,
|
|
23
|
+
extractTokenFromHeader: jwtAuthModule.extractTokenFromHeader,
|
|
24
|
+
|
|
25
|
+
// Rate limiting middleware
|
|
26
|
+
createRateLimit: rateLimitModule.createRateLimit,
|
|
27
|
+
createSlidingWindowRateLimit: rateLimitModule.createSlidingWindowRateLimit,
|
|
28
|
+
MemoryStore: rateLimitModule.MemoryStore,
|
|
29
|
+
defaultKeyGenerator: rateLimitModule.defaultKeyGenerator,
|
|
30
|
+
defaultHandler: rateLimitModule.defaultHandler,
|
|
31
|
+
|
|
32
|
+
// CORS middleware
|
|
33
|
+
createCORS: corsModule.createCORS,
|
|
34
|
+
simpleCORS: corsModule.simpleCORS,
|
|
35
|
+
getAllowedOrigin: corsModule.getAllowedOrigin,
|
|
36
|
+
|
|
37
|
+
// Body parser middleware
|
|
38
|
+
createJSONParser: bodyParserModule.createJSONParser,
|
|
39
|
+
createTextParser: bodyParserModule.createTextParser,
|
|
40
|
+
createURLEncodedParser: bodyParserModule.createURLEncodedParser,
|
|
41
|
+
createMultipartParser: bodyParserModule.createMultipartParser,
|
|
42
|
+
createBodyParser: bodyParserModule.createBodyParser,
|
|
43
|
+
hasBody: bodyParserModule.hasBody,
|
|
44
|
+
shouldParse: bodyParserModule.shouldParse,
|
|
45
|
+
}
|