@eggjs/koa 2.21.0 → 2.22.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 +8 -8
- package/dist/commonjs/application.d.ts +12 -12
- package/dist/commonjs/application.js +60 -22
- package/dist/commonjs/context.d.ts +6 -10
- package/dist/commonjs/context.js +21 -10
- package/dist/commonjs/index.d.ts +1 -1
- package/dist/commonjs/index.js +1 -2
- package/dist/commonjs/request.d.ts +3 -2
- package/dist/commonjs/request.js +35 -64
- package/dist/commonjs/response.d.ts +3 -2
- package/dist/commonjs/response.js +27 -20
- package/dist/commonjs/types.d.ts +3 -2
- package/dist/esm/application.d.ts +12 -12
- package/dist/esm/application.js +25 -20
- package/dist/esm/context.d.ts +6 -10
- package/dist/esm/context.js +21 -10
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +1 -2
- package/dist/esm/request.d.ts +3 -2
- package/dist/esm/request.js +35 -64
- package/dist/esm/response.d.ts +3 -2
- package/dist/esm/response.js +27 -20
- package/dist/esm/types.d.ts +3 -2
- package/dist/package.json +1 -1
- package/package.json +18 -8
- package/src/application.ts +48 -30
- package/src/context.ts +73 -29
- package/src/index.ts +1 -1
- package/src/request.ts +73 -54
- package/src/response.ts +54 -28
- package/src/types.ts +4 -2
package/src/response.ts
CHANGED
|
@@ -3,7 +3,10 @@ import { extname } from 'node:path';
|
|
|
3
3
|
import util from 'node:util';
|
|
4
4
|
import Stream from 'node:stream';
|
|
5
5
|
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
import contentDisposition, {
|
|
8
|
+
type Options as ContentDispositionOptions,
|
|
9
|
+
} from 'content-disposition';
|
|
7
10
|
import { getType } from 'cache-content-type';
|
|
8
11
|
import onFinish from 'on-finished';
|
|
9
12
|
import escape from 'escape-html';
|
|
@@ -12,6 +15,7 @@ import statuses from 'statuses';
|
|
|
12
15
|
import destroy from 'destroy';
|
|
13
16
|
import vary from 'vary';
|
|
14
17
|
import encodeUrl from 'encodeurl';
|
|
18
|
+
|
|
15
19
|
import type { Application } from './application.js';
|
|
16
20
|
import type { Context } from './context.js';
|
|
17
21
|
import type { Request } from './request.js';
|
|
@@ -24,7 +28,12 @@ export class Response {
|
|
|
24
28
|
ctx: Context;
|
|
25
29
|
request: Request;
|
|
26
30
|
|
|
27
|
-
constructor(
|
|
31
|
+
constructor(
|
|
32
|
+
app: Application,
|
|
33
|
+
ctx: Context,
|
|
34
|
+
req: IncomingMessage,
|
|
35
|
+
res: ServerResponse
|
|
36
|
+
) {
|
|
28
37
|
this.app = app;
|
|
29
38
|
this.req = req;
|
|
30
39
|
this.res = res;
|
|
@@ -70,17 +79,19 @@ export class Response {
|
|
|
70
79
|
assert(code >= 100 && code <= 999, `invalid status code: ${code}`);
|
|
71
80
|
this._explicitStatus = true;
|
|
72
81
|
this.res.statusCode = code;
|
|
73
|
-
if (this.req.httpVersionMajor < 2) {
|
|
74
|
-
this.res.statusMessage = statuses.message[code]
|
|
82
|
+
if (this.req.httpVersionMajor < 2 && statuses.message[code]) {
|
|
83
|
+
this.res.statusMessage = statuses.message[code];
|
|
84
|
+
}
|
|
85
|
+
if (this.body && statuses.empty[code]) {
|
|
86
|
+
this.body = null;
|
|
75
87
|
}
|
|
76
|
-
if (this.body && statuses.empty[code]) this.body = null;
|
|
77
88
|
}
|
|
78
89
|
|
|
79
90
|
/**
|
|
80
91
|
* Get response status message
|
|
81
92
|
*/
|
|
82
93
|
get message(): string {
|
|
83
|
-
return this.res.statusMessage
|
|
94
|
+
return this.res.statusMessage ?? statuses.message[this.status];
|
|
84
95
|
}
|
|
85
96
|
|
|
86
97
|
/**
|
|
@@ -90,6 +101,7 @@ export class Response {
|
|
|
90
101
|
this.res.statusMessage = msg;
|
|
91
102
|
}
|
|
92
103
|
|
|
104
|
+
// oxlint-disable-next-line typescript/no-explicit-any
|
|
93
105
|
_body: any;
|
|
94
106
|
_explicitNullBody: boolean;
|
|
95
107
|
|
|
@@ -103,14 +115,20 @@ export class Response {
|
|
|
103
115
|
/**
|
|
104
116
|
* Set response body.
|
|
105
117
|
*/
|
|
106
|
-
set body(
|
|
118
|
+
set body(
|
|
119
|
+
val: string | Buffer | object | Stream | null | undefined | boolean
|
|
120
|
+
) {
|
|
107
121
|
const original = this._body;
|
|
108
122
|
this._body = val;
|
|
109
123
|
|
|
110
124
|
// no content
|
|
111
|
-
if (val
|
|
112
|
-
if (!statuses.empty[this.status])
|
|
113
|
-
|
|
125
|
+
if (val === null || val === undefined) {
|
|
126
|
+
if (!statuses.empty[this.status]) {
|
|
127
|
+
this.status = 204;
|
|
128
|
+
}
|
|
129
|
+
if (val === null) {
|
|
130
|
+
this._explicitNullBody = true;
|
|
131
|
+
}
|
|
114
132
|
this.remove('Content-Type');
|
|
115
133
|
this.remove('Content-Length');
|
|
116
134
|
this.remove('Transfer-Encoding');
|
|
@@ -140,14 +158,18 @@ export class Response {
|
|
|
140
158
|
// stream
|
|
141
159
|
if (val instanceof Stream) {
|
|
142
160
|
onFinish(this.res, destroy.bind(null, val));
|
|
143
|
-
//
|
|
161
|
+
// oxlint-disable-next-line eqeqeq
|
|
144
162
|
if (original != val) {
|
|
145
163
|
val.once('error', err => this.ctx.onerror(err));
|
|
146
164
|
// overwriting
|
|
147
|
-
if (original
|
|
165
|
+
if (original !== null && original !== undefined) {
|
|
166
|
+
this.remove('Content-Length');
|
|
167
|
+
}
|
|
148
168
|
}
|
|
149
169
|
|
|
150
|
-
if (setType)
|
|
170
|
+
if (setType) {
|
|
171
|
+
this.type = 'bin';
|
|
172
|
+
}
|
|
151
173
|
return;
|
|
152
174
|
}
|
|
153
175
|
|
|
@@ -173,7 +195,7 @@ export class Response {
|
|
|
173
195
|
*/
|
|
174
196
|
get length(): number | undefined {
|
|
175
197
|
if (this.has('Content-Length')) {
|
|
176
|
-
return parseInt(this.get('Content-Length')
|
|
198
|
+
return Number.parseInt(this.get('Content-Length')) || 0;
|
|
177
199
|
}
|
|
178
200
|
|
|
179
201
|
const { body } = this;
|
|
@@ -234,7 +256,7 @@ export class Response {
|
|
|
234
256
|
if (this.ctx.accepts('html')) {
|
|
235
257
|
url = escape(url);
|
|
236
258
|
this.type = 'text/html; charset=utf-8';
|
|
237
|
-
this.body = `Redirecting to
|
|
259
|
+
this.body = `Redirecting to ${url}.`;
|
|
238
260
|
return;
|
|
239
261
|
}
|
|
240
262
|
|
|
@@ -246,7 +268,7 @@ export class Response {
|
|
|
246
268
|
/**
|
|
247
269
|
* Set Content-Disposition header to "attachment" with optional `filename`.
|
|
248
270
|
*/
|
|
249
|
-
attachment(filename?: string, options?:
|
|
271
|
+
attachment(filename?: string, options?: ContentDispositionOptions) {
|
|
250
272
|
if (filename) this.type = extname(filename);
|
|
251
273
|
this.set('Content-Disposition', contentDisposition(filename, options));
|
|
252
274
|
}
|
|
@@ -292,9 +314,11 @@ export class Response {
|
|
|
292
314
|
* this.response.is('html', 'json')
|
|
293
315
|
*/
|
|
294
316
|
is(type?: string | string[], ...types: string[]): string | false {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
317
|
+
let testTypes: string[] = [];
|
|
318
|
+
if (type) {
|
|
319
|
+
testTypes = Array.isArray(type) ? type : [type];
|
|
320
|
+
}
|
|
321
|
+
return typeis(this.type, [...testTypes, ...types]);
|
|
298
322
|
}
|
|
299
323
|
|
|
300
324
|
/**
|
|
@@ -379,17 +403,21 @@ export class Response {
|
|
|
379
403
|
* this.set('Accept', 'application/json');
|
|
380
404
|
* this.set({ Accept: 'text/plain', 'X-API-Key': 'tobi' });
|
|
381
405
|
*/
|
|
382
|
-
set(
|
|
406
|
+
set(
|
|
407
|
+
field: string | Record<string, string>,
|
|
408
|
+
val?: string | number | unknown[]
|
|
409
|
+
) {
|
|
383
410
|
if (this.headerSent) return;
|
|
384
411
|
if (typeof field === 'string') {
|
|
412
|
+
let value = val as string | string[];
|
|
385
413
|
if (Array.isArray(val)) {
|
|
386
|
-
|
|
414
|
+
value = val.map(v => {
|
|
387
415
|
return typeof v === 'string' ? v : String(v);
|
|
388
416
|
});
|
|
389
417
|
} else if (typeof val !== 'string') {
|
|
390
|
-
|
|
418
|
+
value = String(val);
|
|
391
419
|
}
|
|
392
|
-
this.res.setHeader(field,
|
|
420
|
+
this.res.setHeader(field, value);
|
|
393
421
|
} else {
|
|
394
422
|
for (const key in field) {
|
|
395
423
|
this.set(key, field[key]);
|
|
@@ -408,13 +436,11 @@ export class Response {
|
|
|
408
436
|
* this.append('Warning', '199 Miscellaneous warning');
|
|
409
437
|
*/
|
|
410
438
|
append(field: string, val: string | string[]) {
|
|
411
|
-
const prev = this.get(field);
|
|
439
|
+
const prev = this.get<string | string[]>(field);
|
|
412
440
|
|
|
413
|
-
let value
|
|
441
|
+
let value = val;
|
|
414
442
|
if (prev) {
|
|
415
|
-
value = Array.isArray(prev)
|
|
416
|
-
? prev.concat(value)
|
|
417
|
-
: [ prev ].concat(val);
|
|
443
|
+
value = Array.isArray(prev) ? prev.concat(value) : [prev].concat(val);
|
|
418
444
|
}
|
|
419
445
|
|
|
420
446
|
return this.set(field, value);
|
package/src/types.ts
CHANGED
|
@@ -4,8 +4,10 @@ export type CustomError = Error & {
|
|
|
4
4
|
statusCode?: number;
|
|
5
5
|
code?: string;
|
|
6
6
|
expose?: boolean;
|
|
7
|
+
headerSent?: boolean;
|
|
7
8
|
};
|
|
8
9
|
|
|
9
|
-
export
|
|
10
|
+
export interface AnyProto {
|
|
11
|
+
// oxlint-disable-next-line typescript/no-explicit-any
|
|
10
12
|
[key: string | symbol]: any;
|
|
11
|
-
}
|
|
13
|
+
}
|