Skip to content

Commit cd85164

Browse files
committed
feat(0.0.6): 添加xml支持
1 parent fac3903 commit cd85164

File tree

4 files changed

+74
-34
lines changed

4 files changed

+74
-34
lines changed

CHANGELOG.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@
33
> 次版本:每季度发布一次,向下兼容的功能性新增
44
> 修订版本:每周发布一次(紧急版本随时发布),向下兼容的问题修正
55
6-
## 0.0.5 [Current]
6+
## 0.0.6 [Current]
7+
###### 发布日期:2023-09-08
8+
###### 兼容性:0.x.x
9+
10+
+ 增加xml支持
11+
+ 修改日志输出
12+
13+
## 0.0.5
714
###### 发布日期:2023-06-27
815
###### 兼容性:0.x.x
916

package.json

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "brisk-controller",
3-
"version": "0.0.5",
3+
"version": "0.0.6",
44
"description": "fast light brisk controller in nodejs(koa)",
55
"main": "lib/index.js",
66
"types": "lib/index.d.ts",
@@ -35,26 +35,28 @@
3535
},
3636
"homepage": "https://github.com/ruixiaozi/brisk-controller#readme",
3737
"dependencies": {
38-
"brisk-ioc": "0.0.5",
39-
"brisk-log": "0.0.5",
40-
"brisk-ts-extends": "0.0.5",
41-
"co-body": "^6.1.0",
38+
"brisk-ioc": "0.0.6",
39+
"brisk-log": "0.0.6",
40+
"brisk-ts-extends": "0.0.6",
41+
"co-body": "6.1.0",
4242
"koa": "2.14.1",
4343
"koa-cors": "0.0.16",
4444
"koa-static": "5.0.0",
4545
"koa2-swagger-ui": "5.6.0",
46-
"path-to-regexp": "^6.2.1",
47-
"portfinder": "^1.0.32"
46+
"path-to-regexp": "6.2.1",
47+
"portfinder": "1.0.32",
48+
"xml2js": "0.6.2"
4849
},
4950
"devDependencies": {
5051
"@commitlint/cli": "16.2.1",
5152
"@commitlint/config-conventional": "16.2.1",
52-
"@types/co-body": "^6.1.0",
53+
"@types/co-body": "6.1.0",
5354
"@types/jest": "29.2.5",
5455
"@types/koa": "2.13.5",
5556
"@types/koa-cors": "0.0.2",
5657
"@types/koa-static": "4.0.2",
5758
"@types/supertest": "2.0.12",
59+
"@types/xml2js": "0.4.11",
5860
"@typescript-eslint/eslint-plugin": "5.36.1",
5961
"@typescript-eslint/parser": "5.36.1",
6062
"copyfiles": "2.4.1",

src/core/core.ts

+36-25
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import { isLike, TypeKind } from 'brisk-ts-extends';
2424
import { get, getParentTypeKind, getSubTypeKind } from 'brisk-ts-extends/runtime';
2525
import { addSwaggerRoute, addSwaggerTag, getSwaggerHandler, initSwaggerConfig } from './swagger';
2626
import { isValid, parseBoolean } from './utils';
27-
import { addRoute, BriskControllerError, initRouter, isFormData, isJson, router, setBaseUrl } from './router';
27+
import { addRoute, BriskControllerError, initRouter, isFormData, isJson, isXml, router, setBaseUrl } from './router';
2828

2929

3030
const defaultRegion = Symbol('briskController');
@@ -117,24 +117,27 @@ export function resultFactory<T>(result: T): BriskControllerResultFactory<T> {
117117
// 参数校验、参数类型转换
118118
function validateAndTransParameter(param: BriskControllerParameter, value: any): any {
119119
if (!isValid(value) && param.required) {
120+
logger.error(`validateAndTransParameter param '${param.name}' required`);
120121
throwError(400, `param '${param.name}' required`);
121122
}
122123

123-
if (!param.type) {
124+
if (!param.type || param.type === 'any') {
124125
return value;
125126
}
126127

127128
if (param.type === 'Date') {
128129
const timestamp = Date.parse(value);
129130
// 无法转换成日期
130131
if (Number.isNaN(timestamp)) {
132+
logger.error(`validateAndTransParameter param '${param.name}' type error`);
131133
throwError(400, `param '${param.name}' type error`);
132134
}
133135
return new Date(timestamp);
134136
}
135137

136138
if (getParentTypeKind(param.type) === 'Array') {
137139
if (!Array.isArray(value)) {
140+
logger.error(`validateAndTransParameter param '${param.name}' type error`);
138141
throwError(400, `param '${param.name}' type error`);
139142
}
140143
return value.map((item: any) => validateAndTransParameter({ ...param, type: getSubTypeKind(param.type) as TypeKind }, item));
@@ -146,18 +149,21 @@ function validateAndTransParameter(param: BriskControllerParameter, value: any):
146149
}
147150

148151
if (typeof value !== 'string') {
152+
logger.error(`validateAndTransParameter param '${param.name}' type error`);
149153
throwError(400, `param '${param.name}' type error`);
150154
}
151155
switch (param.type) {
152156
case 'string':
153157
return value;
154158
case 'number':
155159
if (Number.isNaN(Number(value))) {
160+
logger.error(`validateAndTransParameter param '${param.name}' type error`);
156161
throwError(400, `param '${param.name}' type error`);
157162
}
158163
return Number(value);
159164
case 'boolean':
160165
if (parseBoolean(value) === undefined) {
166+
logger.error(`validateAndTransParameter param '${param.name}' type error`);
161167
throwError(400, `param '${param.name}' type error`);
162168
}
163169
return parseBoolean(value);
@@ -167,6 +173,7 @@ function validateAndTransParameter(param: BriskControllerParameter, value: any):
167173
}
168174

169175
if (!isLike<any>(value, param.type)) {
176+
logger.error(`validateAndTransParameter param '${param.name}' type error`);
170177
throwError(400, `param '${param.name}' type error`);
171178
}
172179

@@ -191,6 +198,7 @@ function validateParameter(param: BriskControllerParameter, value: any) {
191198
const error = param.validator?.(val);
192199

193200
if (error && typeof error === 'object') {
201+
logger.error(Object.values(error)?.[0]?.defaultTip || '');
194202
throwError(400, Object.values(error)?.[0]?.defaultTip);
195203
}
196204

@@ -208,13 +216,13 @@ function getParameters(ctx: Context, params?: BriskControllerParameter[]) {
208216
let value: any;
209217
switch (item.is) {
210218
case BRISK_CONTROLLER_PARAMETER_IS_E.IN_BODY:
211-
value = isJson(ctx) ? data[item.name] : undefined;
219+
value = isJson(ctx) || isXml(ctx) ? data[item.name] : undefined;
212220
break;
213221
case BRISK_CONTROLLER_PARAMETER_IS_E.FORM_DATA:
214222
value = isFormData(ctx) ? data[item.name] : undefined;
215223
break;
216224
case BRISK_CONTROLLER_PARAMETER_IS_E.BODY:
217-
value = isJson(ctx) ? data : undefined;
225+
value = isJson(ctx) || isXml(ctx) ? data : undefined;
218226
break;
219227
case BRISK_CONTROLLER_PARAMETER_IS_E.QUERY:
220228
value = ctx.request.query[item.name];
@@ -290,30 +298,33 @@ export function addRequest(requestPath: string, handler: BriskControllerRequestH
290298
query: ctx.request.query,
291299
});
292300
const res = await Promise.resolve(handler(...getParameters(ctx, option?.params)));
293-
if (res._extra) {
294-
const extra = res._extra;
295-
delete res._extra;
296-
extra.cookies?.forEach?.((item: any) => {
297-
ctx.cookies.set(item.key, item.value, item.option);
298-
});
299-
extra.headers?.forEach?.((item: any) => {
300-
ctx.response.set(item.key, item.value);
301-
});
302-
}
301+
if (typeof res === 'object') {
302+
if (res._extra) {
303+
const extra = res._extra;
304+
delete res._extra;
305+
extra.cookies?.forEach?.((item: any) => {
306+
ctx.cookies.set(item.key, item.value, item.option);
307+
});
308+
extra.headers?.forEach?.((item: any) => {
309+
ctx.response.set(item.key, item.value);
310+
});
311+
}
303312

304-
if (res._briskControllerRedirect) {
305-
ctx.response.status = res._briskControllerRedirect.status;
306-
ctx.redirect(res._briskControllerRedirect.targetPath);
307-
return false;
308-
}
313+
if (res._briskControllerRedirect) {
314+
ctx.response.status = res._briskControllerRedirect.status;
315+
ctx.redirect(res._briskControllerRedirect.targetPath);
316+
return false;
317+
}
309318

310-
if (res._briskControllerForward) {
311-
ctx.request.method = res._briskControllerForward.method.toUpperCase();
312-
ctx.request.path = res._briskControllerForward.targetPath;
313-
await router(ctx, () => Promise.resolve(null));
314-
} else {
315-
ctx.response.body = res;
319+
if (res._briskControllerForward) {
320+
ctx.request.method = res._briskControllerForward.method.toUpperCase();
321+
ctx.request.path = res._briskControllerForward.targetPath;
322+
await router(ctx, () => Promise.resolve(null));
323+
return true;
324+
}
316325
}
326+
ctx.response.body = res;
327+
317328
logger.info(`response ${ctx.request.url}`, {
318329
status: ctx.response.status,
319330
body: ctx.response.body,

src/core/router.ts

+20
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { match } from 'path-to-regexp';
1313
import parse from 'co-body';
1414
import { getLogger, LOGGER_LEVEL_E } from 'brisk-log';
1515
import nodePath from 'path';
16+
import { parseStringPromise } from 'xml2js';
1617

1718
let baseUrl = '/';
1819

@@ -91,6 +92,7 @@ const jsonTypes = [
9192
];
9293
const formTypes = [BRISK_CONTROLLER_MIME_TYPE_E.APPLICATION_X_WWW_FORM_URLENCODED];
9394
const textTypes = [BRISK_CONTROLLER_MIME_TYPE_E.TEXT_PLAIN];
95+
const xmlTypes = [BRISK_CONTROLLER_MIME_TYPE_E.TEXT_XML];
9496

9597
export function isJson(ctx: Context) {
9698
return ctx.request.is(jsonTypes);
@@ -104,6 +106,10 @@ export function isText(ctx: Context) {
104106
return ctx.request.is(textTypes);
105107
}
106108

109+
export function isXml(ctx: Context) {
110+
return ctx.request.is(xmlTypes);
111+
}
112+
107113
function parseBody(ctx: Context) {
108114
if (isJson(ctx)) {
109115
return parse.json(ctx, {
@@ -128,6 +134,19 @@ function parseBody(ctx: Context) {
128134
}).then((res) => res || '');
129135
}
130136

137+
if (isXml(ctx)) {
138+
return parse.text(ctx, {
139+
returnRawBody: true,
140+
encoding: 'utf-8',
141+
}).then((res) => {
142+
logger.debug('xml: ', res);
143+
return parseStringPromise(res.parsed || '').then((xml) => ({
144+
parsed: xml,
145+
raw: res.raw,
146+
}));
147+
});
148+
}
149+
131150
return Promise.resolve({});
132151
}
133152

@@ -184,6 +203,7 @@ export const router: Middleware = async(ctx: Context, next: Next) => {
184203
}
185204
} catch (parseError) {
186205
logger.error('parseBody failed!');
206+
logger.debug('parseBody failed error: ', parseError);
187207
ctx.response.status = 400;
188208
ctx.response.body = 'request body is format error';
189209
return;

0 commit comments

Comments
 (0)