@eggjs/koa 3.1.0-beta.35 → 3.1.0-beta.36

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.
@@ -1,285 +1,244 @@
1
- import Emitter from 'node:events';
2
- import http, {} from 'node:http';
3
- import Stream from 'node:stream';
4
- import util, { debuglog } from 'node:util';
5
- import { getAsyncLocalStorage } from 'gals';
6
- import { HttpError } from 'http-errors';
7
- import { isGeneratorFunction } from 'is-type-of';
8
- import compose from 'koa-compose';
9
- import onFinished from 'on-finished';
10
- import statuses from 'statuses';
11
1
  import { Context } from "./context.js";
12
2
  import { Request } from "./request.js";
13
3
  import { Response } from "./response.js";
14
- // Re-export for external use
15
- export { Context, Request, Response };
16
- const debug = debuglog('egg/koa/application');
4
+ import Emitter from "node:events";
5
+ import http from "node:http";
6
+ import Stream from "node:stream";
7
+ import util, { debuglog } from "node:util";
8
+ import { getAsyncLocalStorage } from "gals";
9
+ import { HttpError } from "http-errors";
10
+ import { isGeneratorFunction } from "is-type-of";
11
+ import compose from "koa-compose";
12
+ import onFinished from "on-finished";
13
+ import statuses from "statuses";
14
+
15
+ //#region src/application.ts
16
+ const debug = debuglog("egg/koa/application");
17
17
  /**
18
- * Expose `Application` class.
19
- * Inherits from `Emitter.prototype`.
20
- */
21
- export class Application extends Emitter {
22
- /**
23
- * Make HttpError available to consumers of the library so that consumers don't
24
- * have a direct dependency upon `http-errors`
25
- */
26
- static HttpError = HttpError;
27
- _proxy;
28
- _env;
29
- subdomainOffset;
30
- proxyIpHeader;
31
- maxIpsCount;
32
- _keys;
33
- middleware;
34
- ctxStorage;
35
- silent;
36
- ContextClass;
37
- context;
38
- RequestClass;
39
- request;
40
- ResponseClass;
41
- response;
42
- /**
43
- * Initialize a new `Application`.
44
- *
45
- * @param {object} [options] Application options
46
- * @param {string} [options.env] Environment, default is `development`
47
- * @param {string[]} [options.keys] Signed cookie keys
48
- * @param {boolean} [options.proxy] Trust proxy headers
49
- * @param {number} [options.subdomainOffset] Subdomain offset
50
- * @param {string} [options.proxyIpHeader] Proxy IP header, defaults to X-Forwarded-For
51
- * @param {number} [options.maxIpsCount] Max IPs read from proxy IP header, default to 0 (means infinity)
52
- */
53
- constructor(options) {
54
- super();
55
- options = options || {};
56
- this._proxy = options.proxy || false;
57
- this.subdomainOffset = options.subdomainOffset || 2;
58
- this.proxyIpHeader = options.proxyIpHeader || 'X-Forwarded-For';
59
- this.maxIpsCount = options.maxIpsCount || 0;
60
- this._env = options.env || process.env.NODE_ENV || 'development';
61
- if (options.keys) {
62
- this._keys = options.keys;
63
- }
64
- this.middleware = [];
65
- this.ctxStorage = getAsyncLocalStorage();
66
- this.silent = false;
67
- this.ContextClass = class ApplicationContext extends Context {
68
- };
69
- this.context = this.ContextClass.prototype;
70
- this.RequestClass = class ApplicationRequest extends Request {
71
- };
72
- this.request = this.RequestClass.prototype;
73
- this.ResponseClass = class ApplicationResponse extends Response {
74
- };
75
- this.response = this.ResponseClass.prototype;
76
- // Set up custom inspect
77
- this[util.inspect.custom] = this.inspect.bind(this);
78
- }
79
- get keys() {
80
- return this._keys;
81
- }
82
- set keys(value) {
83
- this._keys = value;
84
- }
85
- get env() {
86
- return this._env;
87
- }
88
- set env(value) {
89
- this._env = value;
90
- }
91
- get proxy() {
92
- return this._proxy;
93
- }
94
- set proxy(value) {
95
- this._proxy = value;
96
- }
97
- /**
98
- * Shorthand for:
99
- *
100
- * http.createServer(app.callback()).listen(...)
101
- */
102
- // oxlint-disable-next-line typescript/no-explicit-any
103
- listen(...args) {
104
- debug('listen with args: %o', args);
105
- const server = http.createServer(this.callback());
106
- return server.listen(...args);
107
- }
108
- /**
109
- * Return JSON representation.
110
- * We only bother showing settings.
111
- */
112
- toJSON() {
113
- return {
114
- subdomainOffset: this.subdomainOffset,
115
- proxy: this.proxy,
116
- env: this.env,
117
- };
118
- }
119
- /**
120
- * Inspect implementation.
121
- */
122
- inspect() {
123
- return this.toJSON();
124
- }
125
- /**
126
- * Use the given middleware `fn`.
127
- */
128
- use(fn) {
129
- if (typeof fn !== 'function')
130
- throw new TypeError('middleware must be a function!');
131
- const name = fn._name || fn.name || '-';
132
- if (isGeneratorFunction(fn)) {
133
- throw new TypeError(`Support for generators was removed, middleware: ${name}. ` +
134
- 'See the documentation for examples of how to convert old middleware ' +
135
- 'https://github.com/koajs/koa/blob/master/docs/migration.md');
136
- }
137
- debug('use %o #%d', name, this.middleware.length);
138
- this.middleware.push(fn);
139
- return this;
140
- }
141
- /**
142
- * Return a request handler callback
143
- * for node's native http server.
144
- */
145
- callback() {
146
- const fn = compose(this.middleware);
147
- if (!this.listenerCount('error')) {
148
- this.on('error', this.onerror.bind(this));
149
- }
150
- const handleRequest = (req, res) => {
151
- const ctx = this.createContext(req, res);
152
- return this.ctxStorage.run(ctx, async () => {
153
- return await this.handleRequest(ctx, fn);
154
- });
155
- };
156
- return handleRequest;
157
- }
158
- /**
159
- * return current context from async local storage
160
- */
161
- get currentContext() {
162
- return this.ctxStorage.getStore();
163
- }
164
- /**
165
- * Handle request in callback.
166
- * @private
167
- */
168
- async handleRequest(ctx, fnMiddleware) {
169
- this.emit('request', ctx);
170
- const res = ctx.res;
171
- res.statusCode = 404;
172
- const onerror = (err) => ctx.onerror(err);
173
- // oxlint-disable-next-line promise/prefer-await-to-callbacks
174
- onFinished(res, (err) => {
175
- if (err) {
176
- onerror(err);
177
- }
178
- this.emit('response', ctx);
179
- });
180
- try {
181
- await fnMiddleware(ctx);
182
- return this._respond(ctx);
183
- }
184
- catch (err) {
185
- return onerror(err);
186
- }
187
- }
188
- /**
189
- * Initialize a new context.
190
- * @private
191
- */
192
- createContext(req, res) {
193
- const context = new this.ContextClass(this, req, res);
194
- return context;
195
- }
196
- /**
197
- * Default error handler.
198
- * @private
199
- */
200
- onerror(err) {
201
- // When dealing with cross-globals a normal `instanceof` check doesn't work properly.
202
- // See https://github.com/koajs/koa/issues/1466
203
- // We can probably remove it once jest fixes https://github.com/facebook/jest/issues/2549.
204
- const isNativeError = err instanceof Error || Object.prototype.toString.call(err) === '[object Error]';
205
- if (!isNativeError)
206
- throw new TypeError(util.format('non-error thrown: %j', err));
207
- if (err.status === 404 || err.expose)
208
- return;
209
- if (this.silent)
210
- return;
211
- const msg = err.stack || err.toString();
212
- // oxlint-disable-next-line no-console
213
- console.error(`\n${msg.replaceAll(/^/gm, ' ')}\n`);
214
- }
215
- /**
216
- * Response helper.
217
- */
218
- _respond(ctx) {
219
- // allow bypassing koa
220
- if (ctx.respond === false)
221
- return;
222
- if (!ctx.writable)
223
- return;
224
- const res = ctx.res;
225
- let body = ctx.body;
226
- const code = ctx.status;
227
- // ignore body
228
- if (statuses.empty[code]) {
229
- // strip headers
230
- ctx.body = null;
231
- res.end();
232
- return;
233
- }
234
- if (ctx.method === 'HEAD') {
235
- if (!res.headersSent && !ctx.response.has('Content-Length')) {
236
- const { length } = ctx.response;
237
- if (Number.isInteger(length))
238
- ctx.length = length;
239
- }
240
- res.end();
241
- return;
242
- }
243
- // status body
244
- if (body === null || body === undefined) {
245
- if (ctx.response._explicitNullBody) {
246
- ctx.response.remove('Content-Type');
247
- ctx.response.remove('Transfer-Encoding');
248
- res.end();
249
- return;
250
- }
251
- if (ctx.req.httpVersionMajor >= 2) {
252
- body = String(code);
253
- }
254
- else {
255
- body = ctx.message || String(code);
256
- }
257
- if (!res.headersSent) {
258
- ctx.type = 'text';
259
- ctx.length = Buffer.byteLength(body);
260
- }
261
- res.end(body);
262
- return;
263
- }
264
- // responses
265
- if (Buffer.isBuffer(body)) {
266
- res.end(body);
267
- return;
268
- }
269
- if (typeof body === 'string') {
270
- res.end(body);
271
- return;
272
- }
273
- if (body instanceof Stream) {
274
- body.pipe(res);
275
- return;
276
- }
277
- // body: json
278
- body = JSON.stringify(body);
279
- if (!res.headersSent) {
280
- ctx.length = Buffer.byteLength(body);
281
- }
282
- res.end(body);
283
- }
284
- }
285
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwbGljYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvYXBwbGljYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxPQUFPLE1BQU0sYUFBYSxDQUFDO0FBQ2xDLE9BQU8sSUFBSSxFQUFFLEVBQTZDLE1BQU0sV0FBVyxDQUFDO0FBQzVFLE9BQU8sTUFBTSxNQUFNLGFBQWEsQ0FBQztBQUNqQyxPQUFPLElBQUksRUFBRSxFQUFFLFFBQVEsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUUzQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDNUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN4QyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDakQsT0FBTyxPQUFPLE1BQU0sYUFBYSxDQUFDO0FBQ2xDLE9BQU8sVUFBVSxNQUFNLGFBQWEsQ0FBQztBQUNyQyxPQUFPLFFBQVEsTUFBTSxVQUFVLENBQUM7QUFFaEMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUN2QyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHekMsNkJBQTZCO0FBQzdCLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxDQUFDO0FBRXRDLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO0FBVTlDOzs7R0FHRztBQUNILE1BQU0sT0FBTyxXQUFZLFNBQVEsT0FBTztJQUV0Qzs7O09BR0c7SUFDSCxNQUFNLENBQUMsU0FBUyxHQUFxQixTQUFTLENBQUM7SUFFckMsTUFBTSxDQUFVO0lBQ2hCLElBQUksQ0FBUztJQUN2QixlQUFlLENBQVM7SUFDeEIsYUFBYSxDQUFTO0lBQ3RCLFdBQVcsQ0FBUztJQUNWLEtB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
18
+ * Expose `Application` class.
19
+ * Inherits from `Emitter.prototype`.
20
+ */
21
+ var Application = class extends Emitter {
22
+ /**
23
+ * Make HttpError available to consumers of the library so that consumers don't
24
+ * have a direct dependency upon `http-errors`
25
+ */
26
+ static HttpError = HttpError;
27
+ _proxy;
28
+ _env;
29
+ subdomainOffset;
30
+ proxyIpHeader;
31
+ maxIpsCount;
32
+ _keys;
33
+ middleware;
34
+ ctxStorage;
35
+ silent;
36
+ ContextClass;
37
+ context;
38
+ RequestClass;
39
+ request;
40
+ ResponseClass;
41
+ response;
42
+ /**
43
+ * Initialize a new `Application`.
44
+ *
45
+ * @param {object} [options] Application options
46
+ * @param {string} [options.env] Environment, default is `development`
47
+ * @param {string[]} [options.keys] Signed cookie keys
48
+ * @param {boolean} [options.proxy] Trust proxy headers
49
+ * @param {number} [options.subdomainOffset] Subdomain offset
50
+ * @param {string} [options.proxyIpHeader] Proxy IP header, defaults to X-Forwarded-For
51
+ * @param {number} [options.maxIpsCount] Max IPs read from proxy IP header, default to 0 (means infinity)
52
+ */
53
+ constructor(options) {
54
+ super();
55
+ options = options || {};
56
+ this._proxy = options.proxy || false;
57
+ this.subdomainOffset = options.subdomainOffset || 2;
58
+ this.proxyIpHeader = options.proxyIpHeader || "X-Forwarded-For";
59
+ this.maxIpsCount = options.maxIpsCount || 0;
60
+ this._env = options.env || process.env.NODE_ENV || "development";
61
+ if (options.keys) this._keys = options.keys;
62
+ this.middleware = [];
63
+ this.ctxStorage = getAsyncLocalStorage();
64
+ this.silent = false;
65
+ this.ContextClass = class ApplicationContext extends Context {};
66
+ this.context = this.ContextClass.prototype;
67
+ this.RequestClass = class ApplicationRequest extends Request {};
68
+ this.request = this.RequestClass.prototype;
69
+ this.ResponseClass = class ApplicationResponse extends Response {};
70
+ this.response = this.ResponseClass.prototype;
71
+ this[util.inspect.custom] = this.inspect.bind(this);
72
+ }
73
+ get keys() {
74
+ return this._keys;
75
+ }
76
+ set keys(value) {
77
+ this._keys = value;
78
+ }
79
+ get env() {
80
+ return this._env;
81
+ }
82
+ set env(value) {
83
+ this._env = value;
84
+ }
85
+ get proxy() {
86
+ return this._proxy;
87
+ }
88
+ set proxy(value) {
89
+ this._proxy = value;
90
+ }
91
+ /**
92
+ * Shorthand for:
93
+ *
94
+ * http.createServer(app.callback()).listen(...)
95
+ */
96
+ listen(...args) {
97
+ debug("listen with args: %o", args);
98
+ return http.createServer(this.callback()).listen(...args);
99
+ }
100
+ /**
101
+ * Return JSON representation.
102
+ * We only bother showing settings.
103
+ */
104
+ toJSON() {
105
+ return {
106
+ subdomainOffset: this.subdomainOffset,
107
+ proxy: this.proxy,
108
+ env: this.env
109
+ };
110
+ }
111
+ /**
112
+ * Inspect implementation.
113
+ */
114
+ inspect() {
115
+ return this.toJSON();
116
+ }
117
+ /**
118
+ * Use the given middleware `fn`.
119
+ */
120
+ use(fn) {
121
+ if (typeof fn !== "function") throw new TypeError("middleware must be a function!");
122
+ const name = fn._name || fn.name || "-";
123
+ if (isGeneratorFunction(fn)) throw new TypeError(`Support for generators was removed, middleware: ${name}. See the documentation for examples of how to convert old middleware https://github.com/koajs/koa/blob/master/docs/migration.md`);
124
+ debug("use %o #%d", name, this.middleware.length);
125
+ this.middleware.push(fn);
126
+ return this;
127
+ }
128
+ /**
129
+ * Return a request handler callback
130
+ * for node's native http server.
131
+ */
132
+ callback() {
133
+ const fn = compose(this.middleware);
134
+ if (!this.listenerCount("error")) this.on("error", this.onerror.bind(this));
135
+ const handleRequest = (req, res) => {
136
+ const ctx = this.createContext(req, res);
137
+ return this.ctxStorage.run(ctx, async () => {
138
+ return await this.handleRequest(ctx, fn);
139
+ });
140
+ };
141
+ return handleRequest;
142
+ }
143
+ /**
144
+ * return current context from async local storage
145
+ */
146
+ get currentContext() {
147
+ return this.ctxStorage.getStore();
148
+ }
149
+ /**
150
+ * Handle request in callback.
151
+ * @private
152
+ */
153
+ async handleRequest(ctx, fnMiddleware) {
154
+ this.emit("request", ctx);
155
+ const res = ctx.res;
156
+ res.statusCode = 404;
157
+ const onerror = (err) => ctx.onerror(err);
158
+ onFinished(res, (err) => {
159
+ if (err) onerror(err);
160
+ this.emit("response", ctx);
161
+ });
162
+ try {
163
+ await fnMiddleware(ctx);
164
+ return this._respond(ctx);
165
+ } catch (err) {
166
+ return onerror(err);
167
+ }
168
+ }
169
+ /**
170
+ * Initialize a new context.
171
+ * @private
172
+ */
173
+ createContext(req, res) {
174
+ return new this.ContextClass(this, req, res);
175
+ }
176
+ /**
177
+ * Default error handler.
178
+ * @private
179
+ */
180
+ onerror(err) {
181
+ if (!(err instanceof Error || Object.prototype.toString.call(err) === "[object Error]")) throw new TypeError(util.format("non-error thrown: %j", err));
182
+ if (err.status === 404 || err.expose) return;
183
+ if (this.silent) return;
184
+ const msg = err.stack || err.toString();
185
+ console.error(`\n${msg.replaceAll(/^/gm, " ")}\n`);
186
+ }
187
+ /**
188
+ * Response helper.
189
+ */
190
+ _respond(ctx) {
191
+ if (ctx.respond === false) return;
192
+ if (!ctx.writable) return;
193
+ const res = ctx.res;
194
+ let body = ctx.body;
195
+ const code = ctx.status;
196
+ if (statuses.empty[code]) {
197
+ ctx.body = null;
198
+ res.end();
199
+ return;
200
+ }
201
+ if (ctx.method === "HEAD") {
202
+ if (!res.headersSent && !ctx.response.has("Content-Length")) {
203
+ const { length } = ctx.response;
204
+ if (Number.isInteger(length)) ctx.length = length;
205
+ }
206
+ res.end();
207
+ return;
208
+ }
209
+ if (body === null || body === void 0) {
210
+ if (ctx.response._explicitNullBody) {
211
+ ctx.response.remove("Content-Type");
212
+ ctx.response.remove("Transfer-Encoding");
213
+ res.end();
214
+ return;
215
+ }
216
+ if (ctx.req.httpVersionMajor >= 2) body = String(code);
217
+ else body = ctx.message || String(code);
218
+ if (!res.headersSent) {
219
+ ctx.type = "text";
220
+ ctx.length = Buffer.byteLength(body);
221
+ }
222
+ res.end(body);
223
+ return;
224
+ }
225
+ if (Buffer.isBuffer(body)) {
226
+ res.end(body);
227
+ return;
228
+ }
229
+ if (typeof body === "string") {
230
+ res.end(body);
231
+ return;
232
+ }
233
+ if (body instanceof Stream) {
234
+ body.pipe(res);
235
+ return;
236
+ }
237
+ body = JSON.stringify(body);
238
+ if (!res.headersSent) ctx.length = Buffer.byteLength(body);
239
+ res.end(body);
240
+ }
241
+ };
242
+
243
+ //#endregion
244
+ export { Application };