+37
-38
@@ -6,18 +6,19 @@ 'use strict' | ||
| */ | ||
| const util = require('node:util') | ||
| const debug = util.debuglog('koa:application') | ||
| const Emitter = require('node:events') | ||
| const Stream = require('node:stream') | ||
| const http = require('node:http') | ||
| const { AsyncLocalStorage } = require('node:async_hooks') | ||
| const debug = require('debug')('koa:application') | ||
| const assert = require('assert') | ||
| const onFinished = require('on-finished') | ||
| const compose = require('koa-compose') | ||
| const statuses = require('statuses') | ||
| const { HttpError } = require('http-errors') | ||
| const request = require('./request') | ||
| const response = require('./response') | ||
| const compose = require('koa-compose') | ||
| const context = require('./context') | ||
| const request = require('./request') | ||
| const statuses = require('statuses') | ||
| const Emitter = require('events') | ||
| const util = require('util') | ||
| const Stream = require('stream') | ||
| const http = require('http') | ||
| const isStream = require('./is-stream.js') | ||
| const only = require('./only.js') | ||
| const { HttpError } = require('http-errors') | ||
@@ -51,14 +52,14 @@ /** @typedef {typeof import ('./context') & { | ||
| /** | ||
| * | ||
| * @param {object} [options] Application options | ||
| * @param {string} [options.env='development'] Environment | ||
| * @param {string[]} [options.keys] Signed cookie keys | ||
| * @param {boolean} [options.proxy] Trust proxy headers | ||
| * @param {number} [options.subdomainOffset] Subdomain offset | ||
| * @param {string} [options.proxyIpHeader] Proxy IP header, defaults to X-Forwarded-For | ||
| * @param {number} [options.maxIpsCount] Max IPs read from proxy IP header, default to 0 (means infinity) | ||
| * @param {function} [options.compose] Function to handle middleware composition | ||
| * @param {boolean} [options.asyncLocalStorage] Enable AsyncLocalStorage, default to false | ||
| * | ||
| */ | ||
| * | ||
| * @param {object} [options] Application options | ||
| * @param {string} [options.env='development'] Environment | ||
| * @param {string[]} [options.keys] Signed cookie keys | ||
| * @param {boolean} [options.proxy] Trust proxy headers | ||
| * @param {number} [options.subdomainOffset] Subdomain offset | ||
| * @param {string} [options.proxyIpHeader] Proxy IP header, defaults to X-Forwarded-For | ||
| * @param {number} [options.maxIpsCount] Max IPs read from proxy IP header, default to 0 (means infinity) | ||
| * @param {function} [options.compose] Function to handle middleware composition | ||
| * @param {boolean} [options.asyncLocalStorage] Enable AsyncLocalStorage, default to false | ||
| * | ||
| */ | ||
@@ -85,5 +86,7 @@ constructor (options) { | ||
| if (options.asyncLocalStorage) { | ||
| const { AsyncLocalStorage } = require('async_hooks') | ||
| assert(AsyncLocalStorage, 'Requires node 12.17.0 or higher to enable asyncLocalStorage') | ||
| this.ctxStorage = new AsyncLocalStorage() | ||
| if (options.asyncLocalStorage instanceof AsyncLocalStorage) { | ||
| this.ctxStorage = options.asyncLocalStorage | ||
| } else { | ||
| this.ctxStorage = new AsyncLocalStorage() | ||
| } | ||
| } | ||
@@ -117,7 +120,3 @@ } | ||
| toJSON () { | ||
| return only(this, [ | ||
| 'subdomainOffset', | ||
| 'proxy', | ||
| 'env' | ||
| ]) | ||
| return only(this, ['subdomainOffset', 'proxy', 'env']) | ||
| } | ||
@@ -147,3 +146,3 @@ | ||
| use (fn) { | ||
| if (typeof fn !== 'function') throw new TypeError('middleware must be a function!') | ||
| if (typeof fn !== 'function') { throw new TypeError('middleware must be a function!') } | ||
| debug('use %s', fn._name || fn.name || '-') | ||
@@ -196,3 +195,3 @@ this.middleware.push(fn) | ||
| res.statusCode = 404 | ||
| const onerror = err => ctx.onerror(err) | ||
| const onerror = (err) => ctx.onerror(err) | ||
| const handleResponse = () => respond(ctx) | ||
@@ -213,5 +212,5 @@ onFinished(res, onerror) | ||
| /** @type {KoaRequest} */ | ||
| const request = context.request = Object.create(this.request) | ||
| const request = (context.request = Object.create(this.request)) | ||
| /** @type {KoaResponse} */ | ||
| const response = context.response = Object.create(this.response) | ||
| const response = (context.response = Object.create(this.response)) | ||
| context.app = request.app = response.app = this | ||
@@ -242,3 +241,3 @@ context.req = request.req = response.req = req | ||
| err instanceof Error | ||
| if (!isNativeError) throw new TypeError(util.format('non-error thrown: %j', err)) | ||
| if (!isNativeError) { throw new TypeError(util.format('non-error thrown: %j', err)) } | ||
@@ -316,5 +315,5 @@ if (err.status === 404 || err.expose) return | ||
| if (typeof body === 'string') return res.end(body) | ||
| if (body instanceof Blob) return Stream.Readable.from(body.stream()).pipe(res) | ||
| if (body instanceof ReadableStream) return Stream.Readable.from(body).pipe(res) | ||
| if (body instanceof Response) return Stream.Readable.from(body?.body || '').pipe(res) | ||
| if (body instanceof Blob) { return Stream.Readable.from(body.stream()).pipe(res) } | ||
| if (body instanceof ReadableStream) { return Stream.Readable.from(body).pipe(res) } | ||
| if (body instanceof Response) { return Stream.Readable.from(body?.body || '').pipe(res) } | ||
| if (isStream(body)) return body.pipe(res) | ||
@@ -321,0 +320,0 @@ |
+25
-7
@@ -7,4 +7,7 @@ 'use strict' | ||
| const assert = require('node:assert') | ||
| const extname = require('node:path').extname | ||
| const util = require('node:util') | ||
| const contentDisposition = require('content-disposition') | ||
| const getType = require('cache-content-type') | ||
| const onFinish = require('on-finished') | ||
@@ -15,9 +18,8 @@ const escape = require('escape-html') | ||
| const destroy = require('destroy') | ||
| const assert = require('assert') | ||
| const extname = require('path').extname | ||
| const encodeUrl = require('encodeurl') | ||
| const vary = require('vary') | ||
| const getType = require('mime-types').contentType | ||
| const isStream = require('./is-stream.js') | ||
| const only = require('./only.js') | ||
| const util = require('util') | ||
| const encodeUrl = require('encodeurl') | ||
@@ -323,4 +325,20 @@ /** | ||
| back (alt) { | ||
| const url = this.ctx.get('Referrer') || alt || '/' | ||
| this.redirect(url) | ||
| const referrer = this.ctx.get('Referrer') | ||
| if (referrer) { | ||
| // referrer is a relative path | ||
| if (referrer.startsWith('/')) { | ||
| this.redirect(referrer) | ||
| return | ||
| } | ||
| // referrer is an absolute URL, check if it's the same origin | ||
| const url = new URL(referrer, this.ctx.href) | ||
| if (url.host === this.ctx.host) { | ||
| this.redirect(referrer) | ||
| return | ||
| } | ||
| } | ||
| // no referrer, use alt or '/' | ||
| this.redirect(alt || '/') | ||
| }, | ||
@@ -327,0 +345,0 @@ |
+13
-13
| { | ||
| "name": "koa", | ||
| "version": "3.0.0", | ||
| "version": "3.0.1", | ||
| "description": "Koa web app framework", | ||
@@ -21,2 +21,3 @@ "main": "lib/application.js", | ||
| "lint": "standard", | ||
| "lint:fix": "standard --fix", | ||
| "lint:pretty": "standard | snazzy", | ||
@@ -39,18 +40,17 @@ "authors": "git log --format='%aN <%aE>' | sort -u > AUTHORS", | ||
| "dependencies": { | ||
| "accepts": "^1.3.5", | ||
| "cache-content-type": "^1.0.0", | ||
| "content-disposition": "~0.5.2", | ||
| "content-type": "^1.0.4", | ||
| "accepts": "^1.3.8", | ||
| "content-disposition": "~0.5.4", | ||
| "content-type": "^1.0.5", | ||
| "cookies": "~0.9.1", | ||
| "debug": "^4.3.2", | ||
| "delegates": "^1.0.0", | ||
| "destroy": "^1.0.4", | ||
| "destroy": "^1.2.0", | ||
| "encodeurl": "^2.0.0", | ||
| "escape-html": "^1.0.3", | ||
| "fresh": "~0.5.2", | ||
| "http-assert": "^1.3.0", | ||
| "http-assert": "^1.5.0", | ||
| "http-errors": "^2.0.0", | ||
| "koa-compose": "^4.1.0", | ||
| "on-finished": "^2.3.0", | ||
| "parseurl": "^1.3.2", | ||
| "mime-types": "^3.0.1", | ||
| "on-finished": "^2.4.1", | ||
| "parseurl": "^1.3.3", | ||
| "statuses": "^2.0.1", | ||
@@ -62,6 +62,6 @@ "type-is": "^2.0.1", | ||
| "c8": "^10.1.3", | ||
| "gen-esm-wrapper": "^1.0.6", | ||
| "gen-esm-wrapper": "^1.1.3", | ||
| "snazzy": "^9.0.0", | ||
| "standard": "^17.1.0", | ||
| "supertest": "^7.0.0" | ||
| "standard": "^17.1.2", | ||
| "supertest": "^7.1.1" | ||
| }, | ||
@@ -68,0 +68,0 @@ "engines": { |
+7
-8
@@ -22,5 +22,5 @@ <img src="/docs/logo.png" alt="Koa middleware framework for nodejs"/> | ||
| ```sh | ||
| npm install koa | ||
| ``` | ||
| $ npm install koa | ||
| ``` | ||
@@ -85,6 +85,5 @@ ## Hello Koa | ||
| **Old signature middleware support will be removed in v3** | ||
| **Old signature middleware support has been removed in v3** | ||
| Please see the [Migration Guide](docs/migration.md) for more information on upgrading from v1.x and | ||
| using v1.x middleware with v2.x. | ||
| Please see the [Migration Guide from v2.x to v3.x](docs/migration-v2-to-v3.md) for information on upgrading from v2.x to v3.x, and the [Migration Guide from v1.x to v2.x](docs/migration-v1-to-v2.md) for information on upgrading from v1.x to v2.x. | ||
@@ -101,3 +100,3 @@ ## Context, Request and Response | ||
| Koa provides a `Request` object as the `request` property of the `Context`. | ||
| Koa provides a `Request` object as the `request` property of the `Context`. | ||
| Koa's `Request` object provides helpful methods for working with | ||
@@ -118,6 +117,6 @@ http requests which delegate to an [IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage) | ||
| Koa provides a `Response` object as the `response` property of the `Context`. | ||
| Koa provides a `Response` object as the `response` property of the `Context`. | ||
| Koa's `Response` object provides helpful methods for working with | ||
| http responses which delegate to a [ServerResponse](https://nodejs.org/api/http.html#http_class_http_serverresponse) | ||
| . | ||
| . | ||
@@ -124,0 +123,0 @@ Koa's pattern of delegating to Node's request and response objects rather than extending them |
Network access
Supply chain riskThis module accesses the network.
Found 3 instances in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 4 instances in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
64181
0.88%18
-5.26%1737
0.7%4
-20%4
-20%288
-0.35%+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated
Updated
Updated
Updated
Updated