@midwayjs/koa 4.0.0-beta.1 → 4.0.0-beta.3
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 +1 -1
- package/dist/framework.d.ts +2 -0
- package/dist/framework.js +74 -10
- package/dist/interface.d.ts +48 -0
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +18 -1
- package/package.json +9 -8
package/README.md
CHANGED
package/dist/framework.d.ts
CHANGED
|
@@ -26,5 +26,7 @@ export declare class MidwayKoaFramework extends BaseFramework<IMidwayKoaApplicat
|
|
|
26
26
|
getPort(): string;
|
|
27
27
|
useMiddleware(Middleware: CommonMiddlewareUnion<IMidwayKoaContext, Next, unknown>): void;
|
|
28
28
|
useFilter(Filter: CommonFilterUnion<IMidwayKoaContext, Next, unknown>): void;
|
|
29
|
+
private createVersioningMiddleware;
|
|
30
|
+
private extractVersion;
|
|
29
31
|
}
|
|
30
32
|
//# sourceMappingURL=framework.d.ts.map
|
package/dist/framework.js
CHANGED
|
@@ -14,6 +14,7 @@ const koa = require("koa");
|
|
|
14
14
|
const onerror_1 = require("./onerror");
|
|
15
15
|
const qs = require("qs");
|
|
16
16
|
const querystring = require("querystring");
|
|
17
|
+
const utils_1 = require("./utils");
|
|
17
18
|
const COOKIES = Symbol('context#cookies');
|
|
18
19
|
class KoaControllerGenerator extends core_1.WebControllerGenerator {
|
|
19
20
|
constructor(app, webRouterService) {
|
|
@@ -136,10 +137,16 @@ let MidwayKoaFramework = class MidwayKoaFramework extends core_1.BaseFramework {
|
|
|
136
137
|
throw new core_1.httpError.NotFoundError(`${ctx.path} Not Found`);
|
|
137
138
|
}
|
|
138
139
|
};
|
|
140
|
+
const applyMiddlewares = [notFound];
|
|
141
|
+
// versioning middleware
|
|
142
|
+
const versioningConfig = this.configurationOptions.versioning;
|
|
143
|
+
if (versioningConfig?.enabled) {
|
|
144
|
+
applyMiddlewares.push(this.createVersioningMiddleware(versioningConfig));
|
|
145
|
+
}
|
|
139
146
|
// root middleware
|
|
140
147
|
const midwayRootMiddleware = async (ctx, next) => {
|
|
141
148
|
this.app.createAnonymousContext(ctx);
|
|
142
|
-
await (await this.applyMiddleware(
|
|
149
|
+
await (await this.applyMiddleware(applyMiddlewares))(ctx, next);
|
|
143
150
|
if (ctx.body === undefined &&
|
|
144
151
|
!ctx.response._explicitStatus &&
|
|
145
152
|
ctx._matchedRoute) {
|
|
@@ -216,27 +223,38 @@ let MidwayKoaFramework = class MidwayKoaFramework extends core_1.BaseFramework {
|
|
|
216
223
|
if (core_1.Types.isNumber(this.configurationOptions.serverTimeout)) {
|
|
217
224
|
this.server.setTimeout(this.configurationOptions.serverTimeout);
|
|
218
225
|
}
|
|
226
|
+
this.configurationOptions.listenOptions = {
|
|
227
|
+
port: this.configurationOptions.port,
|
|
228
|
+
host: this.configurationOptions.hostname,
|
|
229
|
+
...this.configurationOptions.listenOptions,
|
|
230
|
+
};
|
|
219
231
|
// set port and listen server
|
|
220
|
-
|
|
221
|
-
|
|
232
|
+
let customPort = process.env.MIDWAY_HTTP_PORT ||
|
|
233
|
+
this.configurationOptions.listenOptions.port;
|
|
234
|
+
if (customPort === 0 || customPort === '0') {
|
|
235
|
+
customPort = await (0, utils_1.getFreePort)();
|
|
236
|
+
this.logger.info(`[midway:koa] server has auto-assigned port ${customPort}`);
|
|
237
|
+
}
|
|
238
|
+
this.configurationOptions.listenOptions.port = Number(customPort);
|
|
239
|
+
if (this.configurationOptions.listenOptions.port) {
|
|
222
240
|
new Promise(resolve => {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
args.push(this.configurationOptions.hostname);
|
|
226
|
-
}
|
|
227
|
-
args.push(() => {
|
|
241
|
+
// 使用 ListenOptions 对象启动服务器
|
|
242
|
+
this.server.listen(this.configurationOptions.listenOptions, () => {
|
|
228
243
|
resolve();
|
|
229
244
|
});
|
|
230
|
-
|
|
231
|
-
process.env.MIDWAY_HTTP_PORT = String(
|
|
245
|
+
// 设置环境变量
|
|
246
|
+
process.env.MIDWAY_HTTP_PORT = String(this.configurationOptions.listenOptions.port);
|
|
232
247
|
});
|
|
248
|
+
this.logger.debug(`[midway:koa] server is listening on port ${customPort}`);
|
|
233
249
|
}
|
|
234
250
|
}
|
|
235
251
|
async beforeStop() {
|
|
236
252
|
if (this.server) {
|
|
237
253
|
new Promise(resolve => {
|
|
238
254
|
this.server.close(resolve);
|
|
255
|
+
process.env.MIDWAY_HTTP_PORT = '';
|
|
239
256
|
});
|
|
257
|
+
this.logger.debug('[midway:koa] server is stopped!');
|
|
240
258
|
}
|
|
241
259
|
}
|
|
242
260
|
getFrameworkName() {
|
|
@@ -254,6 +272,52 @@ let MidwayKoaFramework = class MidwayKoaFramework extends core_1.BaseFramework {
|
|
|
254
272
|
useFilter(Filter) {
|
|
255
273
|
this.filterManager.useFilter(Filter);
|
|
256
274
|
}
|
|
275
|
+
createVersioningMiddleware(config) {
|
|
276
|
+
return async (ctx, next) => {
|
|
277
|
+
// 提取版本信息
|
|
278
|
+
const version = this.extractVersion(ctx, config);
|
|
279
|
+
ctx.apiVersion = version;
|
|
280
|
+
// 对于 URI 版本控制,重写路径
|
|
281
|
+
if (config.type === 'URI' && version) {
|
|
282
|
+
const versionPrefix = `/${config.prefix || 'v'}${version}`;
|
|
283
|
+
if (ctx.path.startsWith(versionPrefix)) {
|
|
284
|
+
ctx.originalPath = ctx.path;
|
|
285
|
+
ctx.path = ctx.path.replace(versionPrefix, '') || '/';
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
await next();
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
extractVersion(ctx, config) {
|
|
292
|
+
// 自定义提取函数优先
|
|
293
|
+
if (config.extractVersionFn) {
|
|
294
|
+
return config.extractVersionFn(ctx);
|
|
295
|
+
}
|
|
296
|
+
const type = config.type || 'URI';
|
|
297
|
+
switch (type) {
|
|
298
|
+
case 'HEADER': {
|
|
299
|
+
const headerName = config.header || 'x-api-version';
|
|
300
|
+
const headerValue = ctx.headers[headerName];
|
|
301
|
+
if (typeof headerValue === 'string') {
|
|
302
|
+
return headerValue.replace(/^v/, '');
|
|
303
|
+
}
|
|
304
|
+
return undefined;
|
|
305
|
+
}
|
|
306
|
+
case 'MEDIA_TYPE': {
|
|
307
|
+
const accept = ctx.headers.accept;
|
|
308
|
+
const paramName = config.mediaTypeParam || 'version';
|
|
309
|
+
const match = accept?.match(new RegExp(`${paramName}=(\\d+)`));
|
|
310
|
+
return match ? match[1] : undefined;
|
|
311
|
+
}
|
|
312
|
+
case 'URI': {
|
|
313
|
+
const prefix = config.prefix || 'v';
|
|
314
|
+
const uriMatch = ctx.path.match(new RegExp(`^/${prefix}(\\d+)`));
|
|
315
|
+
return uriMatch ? uriMatch[1] : undefined;
|
|
316
|
+
}
|
|
317
|
+
default:
|
|
318
|
+
return config.defaultVersion;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
257
321
|
};
|
|
258
322
|
exports.MidwayKoaFramework = MidwayKoaFramework;
|
|
259
323
|
exports.MidwayKoaFramework = MidwayKoaFramework = __decorate([
|
package/dist/interface.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
3
4
|
import { IConfigurationOptions, IMidwayApplication, IMidwayContext } from '@midwayjs/core';
|
|
4
5
|
import * as koa from 'koa';
|
|
5
6
|
import { Context as KoaContext, DefaultState, Middleware, Next } from 'koa';
|
|
6
7
|
import { RouterParamValue } from '@midwayjs/core';
|
|
7
8
|
import * as qs from 'qs';
|
|
9
|
+
import { ListenOptions } from 'net';
|
|
8
10
|
export interface State extends DefaultState {
|
|
9
11
|
}
|
|
10
12
|
export type IMidwayKoaContext = IMidwayContext<KoaContext>;
|
|
@@ -15,6 +17,10 @@ export type IMidwayKoaApplication = IMidwayApplication<IMidwayKoaContext, koa<St
|
|
|
15
17
|
* @param middlewareId
|
|
16
18
|
*/
|
|
17
19
|
generateMiddleware(middlewareId: any): Promise<Middleware<State, IMidwayKoaContext>>;
|
|
20
|
+
/**
|
|
21
|
+
* Get the port that the application is listening on
|
|
22
|
+
*/
|
|
23
|
+
getPort(): string;
|
|
18
24
|
}>;
|
|
19
25
|
/**
|
|
20
26
|
* @deprecated use NextFunction definition
|
|
@@ -86,7 +92,47 @@ export interface IMidwayKoaConfigurationOptions extends IConfigurationOptions {
|
|
|
86
92
|
* qs options
|
|
87
93
|
*/
|
|
88
94
|
queryParseOptions?: qs.IParseOptions;
|
|
95
|
+
/**
|
|
96
|
+
* https/https/http2 server options
|
|
97
|
+
*/
|
|
89
98
|
serverOptions?: Record<string, any>;
|
|
99
|
+
/**
|
|
100
|
+
* listen options
|
|
101
|
+
*/
|
|
102
|
+
listenOptions?: ListenOptions;
|
|
103
|
+
/**
|
|
104
|
+
* 版本控制配置
|
|
105
|
+
*/
|
|
106
|
+
versioning?: {
|
|
107
|
+
/**
|
|
108
|
+
* 是否启用版本控制
|
|
109
|
+
*/
|
|
110
|
+
enabled?: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* 默认版本控制类型
|
|
113
|
+
*/
|
|
114
|
+
type?: 'URI' | 'HEADER' | 'MEDIA_TYPE' | 'CUSTOM';
|
|
115
|
+
/**
|
|
116
|
+
* 默认版本
|
|
117
|
+
*/
|
|
118
|
+
defaultVersion?: string;
|
|
119
|
+
/**
|
|
120
|
+
* URI 版本前缀,默认为 'v'
|
|
121
|
+
*/
|
|
122
|
+
prefix?: string;
|
|
123
|
+
/**
|
|
124
|
+
* Header 版本控制时的 header 名称
|
|
125
|
+
*/
|
|
126
|
+
header?: string;
|
|
127
|
+
/**
|
|
128
|
+
* Media Type 版本控制时的参数名
|
|
129
|
+
*/
|
|
130
|
+
mediaTypeParam?: string;
|
|
131
|
+
/**
|
|
132
|
+
* 自定义版本提取函数
|
|
133
|
+
*/
|
|
134
|
+
extractVersionFn?: (ctx: IMidwayKoaContext) => string | undefined;
|
|
135
|
+
};
|
|
90
136
|
}
|
|
91
137
|
export type MiddlewareParamArray = Array<Middleware<DefaultState, IMidwayKoaContext>>;
|
|
92
138
|
export interface IWebMiddleware {
|
|
@@ -95,6 +141,8 @@ export interface IWebMiddleware {
|
|
|
95
141
|
export type Application = IMidwayKoaApplication;
|
|
96
142
|
export interface Context extends IMidwayKoaContext {
|
|
97
143
|
state: State;
|
|
144
|
+
apiVersion?: string;
|
|
145
|
+
originalPath?: string;
|
|
98
146
|
}
|
|
99
147
|
export interface BodyParserOptions {
|
|
100
148
|
enable?: boolean;
|
package/dist/utils.d.ts
CHANGED
package/dist/utils.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.escapeHtml = exports.tpl = exports.isProduction = exports.sendToWormhole = exports.accepts = exports.detectStatus = void 0;
|
|
3
|
+
exports.getFreePort = exports.escapeHtml = exports.tpl = exports.isProduction = exports.sendToWormhole = exports.accepts = exports.detectStatus = void 0;
|
|
4
|
+
const net_1 = require("net");
|
|
4
5
|
function detectStatus(err) {
|
|
5
6
|
// detect status
|
|
6
7
|
let status = err.status || 500;
|
|
@@ -153,4 +154,20 @@ function escapeHtml(string) {
|
|
|
153
154
|
return lastIndex !== index ? html + str.substring(lastIndex, index) : html;
|
|
154
155
|
}
|
|
155
156
|
exports.escapeHtml = escapeHtml;
|
|
157
|
+
async function getFreePort() {
|
|
158
|
+
return new Promise((resolve, reject) => {
|
|
159
|
+
const server = (0, net_1.createServer)();
|
|
160
|
+
server.listen(0, () => {
|
|
161
|
+
try {
|
|
162
|
+
const port = server.address().port;
|
|
163
|
+
server.close();
|
|
164
|
+
resolve(port);
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
reject(err);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
exports.getFreePort = getFreePort;
|
|
156
173
|
//# sourceMappingURL=utils.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midwayjs/koa",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.3",
|
|
4
4
|
"description": "Midway Web Framework for KOA",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -24,18 +24,19 @@
|
|
|
24
24
|
],
|
|
25
25
|
"license": "MIT",
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@midwayjs/core": "^4.0.0-beta.
|
|
28
|
-
"@midwayjs/mock": "^4.0.0-beta.
|
|
27
|
+
"@midwayjs/core": "^4.0.0-beta.3",
|
|
28
|
+
"@midwayjs/mock": "^4.0.0-beta.3",
|
|
29
29
|
"@types/koa-router": "7.4.8",
|
|
30
|
+
"axios": "1.12.0",
|
|
30
31
|
"fs-extra": "11.3.0"
|
|
31
32
|
},
|
|
32
33
|
"dependencies": {
|
|
33
34
|
"@koa/router": "^12.0.0",
|
|
34
35
|
"@midwayjs/cookies": "^1.3.0",
|
|
35
|
-
"@midwayjs/session": "^4.0.0-beta.
|
|
36
|
-
"@types/koa": "
|
|
36
|
+
"@midwayjs/session": "^4.0.0-beta.3",
|
|
37
|
+
"@types/koa": "3.0.0",
|
|
37
38
|
"@types/qs": "6.9.18",
|
|
38
|
-
"koa": "
|
|
39
|
+
"koa": "3.0.1",
|
|
39
40
|
"koa-bodyparser": "4.4.1",
|
|
40
41
|
"qs": "6.14.0"
|
|
41
42
|
},
|
|
@@ -45,7 +46,7 @@
|
|
|
45
46
|
"url": "https://github.com/midwayjs/midway.git"
|
|
46
47
|
},
|
|
47
48
|
"engines": {
|
|
48
|
-
"node": ">=
|
|
49
|
+
"node": ">=20"
|
|
49
50
|
},
|
|
50
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "b5b7dfaafb81823cdba5fd10ad2709b3e495c6b4"
|
|
51
52
|
}
|