@swarmmachina/swm-core 1.1.3 → 1.1.5
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 +10 -0
- package/package.json +1 -1
- package/src/http-context.js +96 -13
- package/src/res-streamer.js +1 -1
package/README.md
CHANGED
|
@@ -327,6 +327,16 @@ const page = ctx.query('page') // ?page=1
|
|
|
327
327
|
|
|
328
328
|
**Returns:** `string`
|
|
329
329
|
|
|
330
|
+
##### `ctx.fullQuery()`
|
|
331
|
+
|
|
332
|
+
Get full raw query string.
|
|
333
|
+
|
|
334
|
+
```javascript
|
|
335
|
+
const q = ctx.fullQuery() // page=1&limit=20
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**Returns:** `string`
|
|
339
|
+
|
|
330
340
|
##### `ctx.param(indexOrName)`
|
|
331
341
|
|
|
332
342
|
Get URL parameter by index or name (for pattern matching in native routing).
|
package/package.json
CHANGED
package/src/http-context.js
CHANGED
|
@@ -8,12 +8,14 @@ export default class HttpContext {
|
|
|
8
8
|
#url = ''
|
|
9
9
|
#headersCached = false
|
|
10
10
|
#headers = {}
|
|
11
|
-
#fullQuery =
|
|
11
|
+
#fullQuery = ''
|
|
12
|
+
#fullQueryCached = false
|
|
12
13
|
#fullQueryParsed = false
|
|
13
14
|
#query = {}
|
|
14
15
|
#params = {}
|
|
15
16
|
#statusOverride = null
|
|
16
17
|
#contentLength = undefined
|
|
18
|
+
#pendingHeaders = new Map()
|
|
17
19
|
#bodyParser = new BodyParser()
|
|
18
20
|
#resStreamer = new ResStreamer()
|
|
19
21
|
|
|
@@ -114,13 +116,15 @@ export default class HttpContext {
|
|
|
114
116
|
|
|
115
117
|
this.#statusOverride = null
|
|
116
118
|
this.#contentLength = undefined
|
|
119
|
+
this.#pendingHeaders.clear()
|
|
117
120
|
|
|
118
121
|
this.#ip = ''
|
|
119
122
|
this.#url = ''
|
|
120
123
|
this.#method = ''
|
|
121
124
|
this.#headersCached = false
|
|
122
125
|
this.#headers = {}
|
|
123
|
-
this.#fullQuery =
|
|
126
|
+
this.#fullQuery = ''
|
|
127
|
+
this.#fullQueryCached = false
|
|
124
128
|
this.#fullQueryParsed = false
|
|
125
129
|
this.#query = {}
|
|
126
130
|
this.#params = {}
|
|
@@ -147,12 +151,14 @@ export default class HttpContext {
|
|
|
147
151
|
|
|
148
152
|
this.#statusOverride = null
|
|
149
153
|
this.#contentLength = undefined
|
|
154
|
+
this.#pendingHeaders.clear()
|
|
150
155
|
this.#ip = ''
|
|
151
156
|
this.#url = ''
|
|
152
157
|
this.#method = ''
|
|
153
158
|
this.#headersCached = false
|
|
154
159
|
this.#headers = {}
|
|
155
|
-
this.#fullQuery =
|
|
160
|
+
this.#fullQuery = ''
|
|
161
|
+
this.#fullQueryCached = false
|
|
156
162
|
this.#fullQueryParsed = false
|
|
157
163
|
this.#query = {}
|
|
158
164
|
this.#params = {}
|
|
@@ -197,13 +203,14 @@ export default class HttpContext {
|
|
|
197
203
|
}
|
|
198
204
|
|
|
199
205
|
cacheQuery() {
|
|
200
|
-
if (this.#
|
|
206
|
+
if (this.#fullQueryCached || !this.req) {
|
|
201
207
|
return
|
|
202
208
|
}
|
|
203
209
|
|
|
204
210
|
const fullQuery = this.req.getQuery()
|
|
205
211
|
|
|
206
212
|
this.#fullQuery = typeof fullQuery === 'string' ? fullQuery : ''
|
|
213
|
+
this.#fullQueryCached = true
|
|
207
214
|
this.#fullQueryParsed = false
|
|
208
215
|
}
|
|
209
216
|
|
|
@@ -288,6 +295,27 @@ export default class HttpContext {
|
|
|
288
295
|
return this.#url
|
|
289
296
|
}
|
|
290
297
|
|
|
298
|
+
/**
|
|
299
|
+
* @returns {string}
|
|
300
|
+
*/
|
|
301
|
+
fullQuery() {
|
|
302
|
+
if (this.#fullQueryCached) {
|
|
303
|
+
return this.#fullQuery
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (!this.req) {
|
|
307
|
+
return ''
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
const fullQuery = this.req.getQuery()
|
|
311
|
+
|
|
312
|
+
this.#fullQuery = typeof fullQuery === 'string' ? fullQuery : ''
|
|
313
|
+
this.#fullQueryCached = true
|
|
314
|
+
this.#fullQueryParsed = false
|
|
315
|
+
|
|
316
|
+
return this.#fullQuery
|
|
317
|
+
}
|
|
318
|
+
|
|
291
319
|
/**
|
|
292
320
|
* @param {string} name
|
|
293
321
|
* @returns {string|undefined}
|
|
@@ -297,7 +325,7 @@ export default class HttpContext {
|
|
|
297
325
|
return this.#query[name]
|
|
298
326
|
}
|
|
299
327
|
|
|
300
|
-
if (this.#
|
|
328
|
+
if (this.#fullQueryCached) {
|
|
301
329
|
this.#parseFullQuery()
|
|
302
330
|
|
|
303
331
|
if (name in this.#query) {
|
|
@@ -396,7 +424,11 @@ export default class HttpContext {
|
|
|
396
424
|
* @returns {HttpContext}
|
|
397
425
|
*/
|
|
398
426
|
setHeader(key, value) {
|
|
399
|
-
this.
|
|
427
|
+
if (this.replied || this.aborted) {
|
|
428
|
+
return this
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
this.#stageHeader(key, value)
|
|
400
432
|
return this
|
|
401
433
|
}
|
|
402
434
|
|
|
@@ -404,32 +436,83 @@ export default class HttpContext {
|
|
|
404
436
|
* @param {Record<string, string> | null | undefined} headers
|
|
405
437
|
*/
|
|
406
438
|
setHeaders(headers) {
|
|
439
|
+
if (this.replied || this.aborted) {
|
|
440
|
+
return
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
this.#stageHeaders(headers)
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* @param {Record<string, string> | null | undefined} headers
|
|
448
|
+
*/
|
|
449
|
+
flushHeaders(headers = null) {
|
|
450
|
+
this.#flushPendingHeaders(headers)
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* @param {string} key
|
|
455
|
+
* @param {string} value
|
|
456
|
+
*/
|
|
457
|
+
#stageHeader(key, value) {
|
|
458
|
+
if (value === undefined || value === null) {
|
|
459
|
+
return
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
const headerName = String(key)
|
|
463
|
+
const headerValue = String(value)
|
|
464
|
+
|
|
465
|
+
this.#pendingHeaders.set(headerName.toLowerCase(), [headerName, headerValue])
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* @param {Record<string, string> | null | undefined} headers
|
|
470
|
+
*/
|
|
471
|
+
#stageHeaders(headers) {
|
|
407
472
|
if (!headers) {
|
|
408
473
|
return
|
|
409
474
|
}
|
|
410
475
|
|
|
411
476
|
if (headers === TEXT_PLAIN_HEADER) {
|
|
412
|
-
this
|
|
477
|
+
this.#stageHeader('content-type', 'text/plain; charset=utf-8')
|
|
413
478
|
return
|
|
414
479
|
}
|
|
415
480
|
|
|
416
481
|
if (headers === JSON_HEADER) {
|
|
417
|
-
this
|
|
482
|
+
this.#stageHeader('content-type', 'application/json; charset=utf-8')
|
|
418
483
|
return
|
|
419
484
|
}
|
|
420
485
|
|
|
421
486
|
if (headers === OCTET_STREAM_HEADER) {
|
|
422
|
-
this
|
|
487
|
+
this.#stageHeader('content-type', 'application/octet-stream')
|
|
423
488
|
return
|
|
424
489
|
}
|
|
425
490
|
|
|
426
491
|
for (const key in headers) {
|
|
427
492
|
const value = headers[key]
|
|
428
493
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
494
|
+
this.#stageHeader(key, value)
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* @param {Record<string, string> | null | undefined} headers
|
|
500
|
+
*/
|
|
501
|
+
#flushPendingHeaders(headers = null) {
|
|
502
|
+
if (!this.res) {
|
|
503
|
+
this.#pendingHeaders.clear()
|
|
504
|
+
return
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
if (headers) {
|
|
508
|
+
this.#stageHeaders(headers)
|
|
432
509
|
}
|
|
510
|
+
|
|
511
|
+
for (const [, [key, value]] of this.#pendingHeaders) {
|
|
512
|
+
this.res.writeHeader(key, value)
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
this.#pendingHeaders.clear()
|
|
433
516
|
}
|
|
434
517
|
|
|
435
518
|
/**
|
|
@@ -515,7 +598,7 @@ export default class HttpContext {
|
|
|
515
598
|
}
|
|
516
599
|
|
|
517
600
|
this.res.writeStatus(this.getStatus(status))
|
|
518
|
-
this
|
|
601
|
+
this.#flushPendingHeaders(headers)
|
|
519
602
|
|
|
520
603
|
if (body != null) {
|
|
521
604
|
this.res.end(body)
|
package/src/res-streamer.js
CHANGED
|
@@ -107,7 +107,7 @@ export default class ResStreamer {
|
|
|
107
107
|
|
|
108
108
|
res.cork(() => {
|
|
109
109
|
res.writeStatus(typeof status === 'string' ? status : this.#ctx.getStatus(status))
|
|
110
|
-
this.#ctx.
|
|
110
|
+
this.#ctx.flushHeaders(headers)
|
|
111
111
|
})
|
|
112
112
|
|
|
113
113
|
this.#started = true
|