@makano/rew 1.5.3 → 1.5.4
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/lib/rew/pkgs/serve.app.js +21 -15
- package/lib/rew/pkgs/serve.js +63 -10
- package/package.json +1 -1
@@ -7,6 +7,14 @@ module.exports = (context) => {
|
|
7
7
|
|
8
8
|
let appOptions = {};
|
9
9
|
|
10
|
+
const additionalParams = {
|
11
|
+
text: svr.prototype.text,
|
12
|
+
html: svr.prototype.html,
|
13
|
+
status: svr.prototype.status,
|
14
|
+
json: svr.prototype.json,
|
15
|
+
error: svr.prototype.error
|
16
|
+
};
|
17
|
+
|
10
18
|
const mkRouter = (options = {}) => svr.prototype.router({ type: 'auto', ...appOptions, ...options });
|
11
19
|
|
12
20
|
class Events {
|
@@ -251,7 +259,7 @@ module.exports = (context) => {
|
|
251
259
|
that.controller.register(method, _path, cb, middleWare);
|
252
260
|
return cb;
|
253
261
|
}
|
254
|
-
const mkReq = (usage) => (req,
|
262
|
+
const mkReq = (usage) => (req, ...args) => usage.call(req, req, ...args);
|
255
263
|
class SControllerContext extends Context('controller') {
|
256
264
|
|
257
265
|
middleWares = [];
|
@@ -317,18 +325,21 @@ module.exports = (context) => {
|
|
317
325
|
}
|
318
326
|
|
319
327
|
function mkBody(req){
|
328
|
+
if(!req.data) return null;
|
320
329
|
const type = req.headers.get('content-type');
|
321
330
|
if(type == 'application/json'){
|
322
331
|
return req.data.json();
|
323
|
-
} else {
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
332
|
+
} else if(type.startsWith('multipart/form-data')){
|
333
|
+
return req.data.multipart();
|
334
|
+
} else if(type == 'multipart/form-data'){
|
335
|
+
return req.data;
|
336
|
+
} else try {
|
337
|
+
return req.data.json();
|
338
|
+
} catch(e){
|
339
|
+
return req.data?.text();
|
329
340
|
}
|
330
341
|
}
|
331
|
-
|
342
|
+
let f;
|
332
343
|
class SController extends Injectable {
|
333
344
|
|
334
345
|
constructor(root){
|
@@ -341,14 +352,9 @@ module.exports = (context) => {
|
|
341
352
|
return async (req, ctx) => {
|
342
353
|
let context = {...{
|
343
354
|
request: req,
|
355
|
+
params: req.params || {},
|
344
356
|
body: mkBody(req)
|
345
|
-
},...ctx, ...(cb.parent || {}), ...
|
346
|
-
text: svr.prototype.text,
|
347
|
-
html: svr.prototype.html,
|
348
|
-
status: svr.prototype.status,
|
349
|
-
json: svr.prototype.json,
|
350
|
-
error: svr.prototype.error
|
351
|
-
}};
|
357
|
+
},...ctx, ...(cb.parent || {}), ...additionalParams};
|
352
358
|
return await cb.call(context, ...Object.keys(context).map(i => context[i]));
|
353
359
|
}
|
354
360
|
}
|
package/lib/rew/pkgs/serve.js
CHANGED
@@ -30,7 +30,65 @@ module.exports = (context) => {
|
|
30
30
|
return new Request(url, options);
|
31
31
|
}
|
32
32
|
|
33
|
-
|
33
|
+
|
34
|
+
function parseMultipart(req, content) {
|
35
|
+
const contentType = req.headers.get('content-type');
|
36
|
+
const boundary = contentType.split('boundary=')[1];
|
37
|
+
if (!boundary) throw new Error('No boundary in multipart/form-data');
|
38
|
+
|
39
|
+
const body = content;
|
40
|
+
const parts = body.split(`--${boundary}`).filter(part => part.trim() !== '--' && part.trim() !== '');
|
41
|
+
|
42
|
+
const fields = {};
|
43
|
+
const files = {};
|
44
|
+
|
45
|
+
parts.forEach(part => {
|
46
|
+
const [headers, ...content] = part.split('\r\n\r\n');
|
47
|
+
const contentBody = content.join('\r\n\r\n').trim();
|
48
|
+
const headerLines = headers.split('\r\n');
|
49
|
+
|
50
|
+
let name, filename, contentType;
|
51
|
+
headerLines.forEach(line => {
|
52
|
+
if (line.startsWith('Content-Disposition')) {
|
53
|
+
const matchName = /name="([^"]+)"/.exec(line);
|
54
|
+
const matchFilename = /filename="([^"]+)"/.exec(line);
|
55
|
+
if (matchName) name = matchName[1];
|
56
|
+
if (matchFilename) filename = matchFilename[1];
|
57
|
+
}
|
58
|
+
if (line.startsWith('Content-Type')) {
|
59
|
+
contentType = line.split(': ')[1];
|
60
|
+
}
|
61
|
+
});
|
62
|
+
|
63
|
+
if (filename) {
|
64
|
+
files[name] = {
|
65
|
+
filename,
|
66
|
+
contentType,
|
67
|
+
...handleBuffer(Buffer.from(contentBody, 'binary'))
|
68
|
+
};
|
69
|
+
} else {
|
70
|
+
fields[name] = contentBody;
|
71
|
+
}
|
72
|
+
});
|
73
|
+
|
74
|
+
return { ...fields, ...files };
|
75
|
+
}
|
76
|
+
|
77
|
+
function handleBuffer(buffer){
|
78
|
+
return {
|
79
|
+
text(){
|
80
|
+
return buffer.toString();
|
81
|
+
},
|
82
|
+
json(){
|
83
|
+
return JSON.parse(buffer.toString());
|
84
|
+
},
|
85
|
+
buffer(){
|
86
|
+
return buffer;
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
function getBody(req, request){
|
34
92
|
return new Promise((resolve, reject) => {
|
35
93
|
const chunks = [];
|
36
94
|
|
@@ -41,14 +99,9 @@ module.exports = (context) => {
|
|
41
99
|
req.on('end', () => {
|
42
100
|
let buffer = chunks.length ? Buffer.concat(chunks) : null;
|
43
101
|
resolve(buffer ? {
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
json(){
|
48
|
-
return JSON.parse(buffer.toString());
|
49
|
-
},
|
50
|
-
buffer(){
|
51
|
-
return buffer;
|
102
|
+
...handleBuffer(buffer),
|
103
|
+
multipart(){
|
104
|
+
return parseMultipart(request, buffer.toString());
|
52
105
|
}
|
53
106
|
} : null);
|
54
107
|
});
|
@@ -81,7 +134,7 @@ module.exports = (context) => {
|
|
81
134
|
|
82
135
|
context.getRealRequest = () => req;
|
83
136
|
|
84
|
-
request.data = await getBody(req);
|
137
|
+
request.data = await getBody(req, request);
|
85
138
|
|
86
139
|
if(this.options.fetch == 'router'){
|
87
140
|
if(!Object.keys(this.options.routers).length) throw new Error('No fetch function nor routers found');
|