@mattduffy/banner 1.1.1 → 1.2.1
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/.eslintrc.cjs +5 -3
- package/Readme.md +67 -2
- package/package.json +3 -2
- package/src/index.js +106 -63
- package/test/test.js +58 -24
package/.eslintrc.cjs
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const restrictedGlobals = require('eslint-restricted-globals')
|
|
2
|
+
|
|
1
3
|
module.exports = {
|
|
2
4
|
globals: {
|
|
3
5
|
window: true,
|
|
@@ -15,9 +17,9 @@ module.exports = {
|
|
|
15
17
|
extends: 'airbnb-base',
|
|
16
18
|
overrides: [
|
|
17
19
|
{
|
|
18
|
-
files: [
|
|
20
|
+
files: ['public/j/worker.js'],
|
|
19
21
|
rules: {
|
|
20
|
-
'no-restricted-globals': ['error', 'isFinite', 'isNaN'].concat(restrictedGlobals),
|
|
22
|
+
'no-restricted-globals': ['error', 'isFinite', 'isNaN'].concat(restrictedGlobals),
|
|
21
23
|
},
|
|
22
24
|
},
|
|
23
25
|
],
|
|
@@ -31,7 +33,7 @@ module.exports = {
|
|
|
31
33
|
'no-underscore-dangle': 'off',
|
|
32
34
|
'import/extensions': 'off',
|
|
33
35
|
'import/prefer-default-export': 'off',
|
|
34
|
-
'max-len': ['error', {
|
|
36
|
+
'max-len': ['error', { code: 100 }],
|
|
35
37
|
'new-cap': 'off',
|
|
36
38
|
},
|
|
37
39
|
}
|
package/Readme.md
CHANGED
|
@@ -3,11 +3,76 @@ This package exports a middleware function for Koajs app servers that displays u
|
|
|
3
3
|
information.
|
|
4
4
|
|
|
5
5
|
```javascript
|
|
6
|
-
import
|
|
6
|
+
import Banner from '@mattduffy/banner'
|
|
7
7
|
|
|
8
8
|
// to emit a startup banner in your app logs
|
|
9
|
+
const banner = new Banner({
|
|
10
|
+
name: <your_app_name>,
|
|
11
|
+
local: <your_local_dev_host>,
|
|
12
|
+
localPort: <your_local_dev_port>, // optional
|
|
13
|
+
public: <your_public_domain_name>,
|
|
14
|
+
})
|
|
9
15
|
banner.print()
|
|
10
|
-
|
|
16
|
+
/*
|
|
17
|
+
Emits to stdout (or where ever your logging goes).
|
|
18
|
+
#####################################################
|
|
19
|
+
# #
|
|
20
|
+
# Starting up: <your_app_name> #
|
|
21
|
+
# local: http://192.168.1.252:9876 #
|
|
22
|
+
# public: https://example.com #
|
|
23
|
+
# process: node v20.19.4 (Iron) #
|
|
24
|
+
# arch: x64 linux #
|
|
25
|
+
# #
|
|
26
|
+
#####################################################
|
|
27
|
+
*/
|
|
11
28
|
// To emit a banner at the start of each request
|
|
12
29
|
app.use(banner.use())
|
|
30
|
+
/*
|
|
31
|
+
Emits at the beginning of each client request.
|
|
32
|
+
#################################################################
|
|
33
|
+
# GET: https://dev.example.com/map/getToken?debug=verbose
|
|
34
|
+
# Referer: https://dev.example.com/?debug=verbose
|
|
35
|
+
# From IP: 192.168.1.254
|
|
36
|
+
#################################################################
|
|
37
|
+
*/
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The request banner uses a different ASCII text character depending on the value of
|
|
41
|
+
the ```ctx.request.method``` property. The supported request methods are ```GET```, ```PUT```,
|
|
42
|
+
```POST```, and ```DELETE```.
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
// GET
|
|
46
|
+
######################################################################
|
|
47
|
+
# GET: https://banner.test/a/really/long/url/to/a/special/page
|
|
48
|
+
# Referer: https://googoogle.com
|
|
49
|
+
# From IP: 192.168.1.250
|
|
50
|
+
######################################################################
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
// PUT
|
|
55
|
+
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|
|
56
|
+
& PUT: https://banner.test/a/really/long/url/to/a/special/page
|
|
57
|
+
& Referer: https://googoogle.com
|
|
58
|
+
& From IP: 192.168.1.250
|
|
59
|
+
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
// POST
|
|
64
|
+
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
65
|
+
@ POST: https://banner.test/a/really/long/url/to/a/special/page
|
|
66
|
+
@ Referer: https://googoogle.com
|
|
67
|
+
@ From IP: 192.168.1.250
|
|
68
|
+
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
// DELETE
|
|
73
|
+
**********************************************************************
|
|
74
|
+
* DELETE: https://banner.test/a/really/long/url/to/a/special/page
|
|
75
|
+
* Referer: https://googoogle.com
|
|
76
|
+
* From IP: 192.168.1.250
|
|
77
|
+
**********************************************************************
|
|
13
78
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mattduffy/banner",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Displays server start-up information.",
|
|
5
5
|
"author": "Matthew Duffy",
|
|
6
6
|
"license": "ISC",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"keywords": [],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"debug": "4.4.1"
|
|
31
|
+
"debug": "4.4.1",
|
|
32
|
+
"eslint-restricted-globals": "0.2.0"
|
|
32
33
|
}
|
|
33
34
|
}
|
package/src/index.js
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
import Debug from 'debug'
|
|
8
8
|
|
|
9
9
|
Debug.log = console.log.bind(console)
|
|
10
|
-
const log = Debug('banner')
|
|
11
|
-
const error = log.extend('ERROR')
|
|
10
|
+
// const log = Debug('banner')
|
|
11
|
+
// const error = log.extend('ERROR')
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* A class to create and emit a start-up banner of Koajs based apps.
|
|
@@ -18,33 +18,54 @@ const error = log.extend('ERROR')
|
|
|
18
18
|
*/
|
|
19
19
|
export class Banner {
|
|
20
20
|
#appName
|
|
21
|
+
|
|
21
22
|
#arch
|
|
23
|
+
|
|
22
24
|
#bannerText
|
|
25
|
+
|
|
23
26
|
#borderGlyphGET = '#'
|
|
27
|
+
|
|
24
28
|
#borderGlyphPUT = '&'
|
|
29
|
+
|
|
25
30
|
#borderGlyphPOST = '@'
|
|
31
|
+
|
|
26
32
|
#borderGlyphDELETE = '*'
|
|
33
|
+
|
|
34
|
+
#ipAddress
|
|
35
|
+
|
|
27
36
|
#lineStarts = []
|
|
37
|
+
|
|
28
38
|
#lines = []
|
|
39
|
+
|
|
29
40
|
#local
|
|
41
|
+
|
|
30
42
|
#localPort
|
|
43
|
+
|
|
31
44
|
#nodejs
|
|
45
|
+
|
|
32
46
|
#nodeLts
|
|
47
|
+
|
|
33
48
|
#nodeName
|
|
49
|
+
|
|
34
50
|
#nodeVersion
|
|
51
|
+
|
|
35
52
|
#platform
|
|
53
|
+
|
|
36
54
|
#public
|
|
55
|
+
|
|
37
56
|
#startingup
|
|
57
|
+
|
|
38
58
|
/**
|
|
39
59
|
* Create an instance of the Banner class.
|
|
40
60
|
* @param { object } [strings] - An object literal of strings to display in the banner.
|
|
41
|
-
* @param { string } strings.
|
|
42
|
-
* @param { string } strings.public - The public web address the app is accesssible at.
|
|
61
|
+
* @param { string } [strings.ip] - The ip address of the request.
|
|
43
62
|
* @param { string } strings.local - The local address the app is accessible at.
|
|
44
63
|
* @param { Number } [strings.localPort] - The local address port, if provided.
|
|
64
|
+
* @param { string } strings.name - The name of the app starting up.
|
|
65
|
+
* @param { string } strings.public - The public web address the app is accesssible at.
|
|
45
66
|
* @returns { Banner}
|
|
46
67
|
*/
|
|
47
|
-
constructor(strings=null) {
|
|
68
|
+
constructor(strings = null) {
|
|
48
69
|
this.#arch = process.arch
|
|
49
70
|
this.#nodeLts = process.release?.lts ?? null
|
|
50
71
|
this.#nodeName = process.release.name
|
|
@@ -61,7 +82,8 @@ export class Banner {
|
|
|
61
82
|
this.#appName = strings.name
|
|
62
83
|
this.#borderGlyphGET = strings?.borderGlyph ?? this.#borderGlyphGET
|
|
63
84
|
this.#localPort = strings?.localPort ?? null
|
|
64
|
-
this.#
|
|
85
|
+
this.#ipAddress = strings?.ip ?? null
|
|
86
|
+
this.#local = `${strings.local}${(this.#localPort) ? `: ${this.#localPort}` : ''}`
|
|
65
87
|
this.#public = strings.public
|
|
66
88
|
this.#startingup = strings.name
|
|
67
89
|
}
|
|
@@ -76,63 +98,62 @@ export class Banner {
|
|
|
76
98
|
* @throws { Error } - Throws an exception if name, public, local values are missing.
|
|
77
99
|
* @return { void }
|
|
78
100
|
*/
|
|
79
|
-
#compose
|
|
101
|
+
#compose() {
|
|
80
102
|
if (!this.#appName || !this.#local || !this.#public) {
|
|
81
103
|
throw new Error('Missing required inputs.')
|
|
82
104
|
}
|
|
83
105
|
this.startingupLine = `${this.startingupLabel}: ${this.#startingup}`
|
|
84
106
|
this.#lineStarts.push(this.startingupLine)
|
|
85
107
|
this.localLine = `${this.localLabel}: `
|
|
86
|
-
+ `${/^https?:\/\//.test(this.#local) ? this.#local :
|
|
108
|
+
+ `${/^https?:\/\//.test(this.#local) ? `${this.#local}` : `http://${this.#local}`}`
|
|
87
109
|
this.#lineStarts.push(this.localLine)
|
|
88
110
|
this.publicLine = `${this.publicLabel}: `
|
|
89
|
-
+ `${/^https?:\/\//.test(this.#public) ? this.#public :
|
|
111
|
+
+ `${/^https?:\/\//.test(this.#public) ? `${this.#public}` : `https://${this.#public}`}`
|
|
90
112
|
this.#lineStarts.push(this.publicLine)
|
|
91
113
|
this.archLine = `${this.archLabel}: ${this.#arch} ${this.#platform}`
|
|
92
114
|
this.#lineStarts.push(this.archLine)
|
|
93
115
|
this.nodejsLine = `${this.nodejsLabel}: ${this.#nodeName} ${this.#nodeVersion} `
|
|
94
|
-
+ `${(this.#nodeLts) ?
|
|
116
|
+
+ `${(this.#nodeLts) ? `(${this.#nodeLts})` : ''}`
|
|
95
117
|
this.#lineStarts.push(this.nodejsLine)
|
|
96
118
|
|
|
97
|
-
this.startingupLine = this.startingupLine
|
|
98
|
-
(this.longestLabel - this.startingupLine.indexOf(':'))
|
|
99
|
-
|
|
119
|
+
this.startingupLine = this.startingupLine
|
|
120
|
+
.padStart((this.longestLabel - this.startingupLine.indexOf(':'))
|
|
121
|
+
+ this.startingupLine.length, ' ')
|
|
100
122
|
this.#lines[0] = this.startingupLine
|
|
101
123
|
|
|
102
|
-
this.localLine = this.localLine
|
|
103
|
-
(this.longestLabel - this.localLine.indexOf(':'))
|
|
104
|
-
|
|
124
|
+
this.localLine = this.localLine
|
|
125
|
+
.padStart((this.longestLabel - this.localLine.indexOf(':'))
|
|
126
|
+
+ this.localLine.length, ' ')
|
|
105
127
|
this.#lines[1] = this.localLine
|
|
106
128
|
|
|
107
|
-
this.publicLine = this.publicLine
|
|
108
|
-
(this.longestLabel - this.publicLine.indexOf(':'))
|
|
109
|
-
|
|
129
|
+
this.publicLine = this.publicLine
|
|
130
|
+
.padStart((this.longestLabel - this.publicLine.indexOf(':'))
|
|
131
|
+
+ this.publicLine.length, ' ')
|
|
110
132
|
this.#lines[2] = this.publicLine
|
|
111
133
|
|
|
112
|
-
this.nodejsLine = this.nodejsLine
|
|
113
|
-
(this.longestLabel - this.nodejsLine.indexOf(':'))
|
|
114
|
-
|
|
134
|
+
this.nodejsLine = this.nodejsLine
|
|
135
|
+
.padStart((this.longestLabel - this.nodejsLine.indexOf(':'))
|
|
136
|
+
+ this.nodejsLine.length, ' ')
|
|
115
137
|
this.#lines[3] = this.nodejsLine
|
|
116
138
|
|
|
117
|
-
this.archLine = this.archLine
|
|
118
|
-
(this.longestLabel - this.archLine.indexOf(':'))
|
|
119
|
-
|
|
139
|
+
this.archLine = this.archLine
|
|
140
|
+
.padStart((this.longestLabel - this.archLine.indexOf(':'))
|
|
141
|
+
+ this.archLine.length, ' ')
|
|
120
142
|
this.#lines[4] = this.archLine
|
|
121
143
|
|
|
122
144
|
const g = this.#borderGlyphGET
|
|
123
|
-
this.#bannerText =
|
|
124
|
-
`${g}${g.padEnd(this.longestLine + 5, g)}${g}\n`
|
|
145
|
+
this.#bannerText = `${g}${g.padEnd(this.longestLine + 5, g)}${g}\n`
|
|
125
146
|
+ `${g} ${' '.padEnd(this.longestLine + 2, ' ')} ${g}\n`
|
|
126
|
-
+ `${g} ${this.startingupLine}${' '
|
|
127
|
-
(this.longestLine - this.startingupLine.length) + 3, ' ')} ${g}\n`
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
147
|
+
+ `${g} ${this.startingupLine}${' '
|
|
148
|
+
.padEnd((this.longestLine - this.startingupLine.length) + 3, ' ')} ${g}\n`
|
|
149
|
+
+ `${g} ${this.localLine}${' '
|
|
150
|
+
.padEnd((this.longestLine - this.localLine.length) + 3, ' ')} ${g}\n`
|
|
151
|
+
+ `${g} ${this.publicLine}${' '
|
|
152
|
+
.padEnd((this.longestLine - this.publicLine.length) + 3, ' ')} ${g}\n`
|
|
153
|
+
+ `${g} ${this.nodejsLine}${' '
|
|
154
|
+
.padEnd((this.longestLine - this.nodejsLine.length) + 3, ' ')} ${g}\n`
|
|
155
|
+
+ `${g} ${this.archLine}${' '
|
|
156
|
+
.padEnd((this.longestLine - this.archLine.length) + 3, ' ')} ${g}\n`
|
|
136
157
|
+ `${g} ${' '.padEnd(this.longestLine + 2, ' ')} ${g}\n`
|
|
137
158
|
+ `${g}${g.padEnd(this.longestLine + 5, g)}${g}\n`
|
|
138
159
|
}
|
|
@@ -163,13 +184,13 @@ export class Banner {
|
|
|
163
184
|
}
|
|
164
185
|
}
|
|
165
186
|
|
|
166
|
-
|
|
187
|
+
/**
|
|
167
188
|
* Set the local address displayed in the banner.
|
|
168
189
|
* @type { string }
|
|
169
190
|
* @param { string } local - The local address displayed in the banner.
|
|
170
191
|
*/
|
|
171
192
|
set local(local) {
|
|
172
|
-
this.#local = `${local}${(this.#localPort) ?
|
|
193
|
+
this.#local = `${local}${(this.#localPort) ? `:${this.#localPort}` : ''}`
|
|
173
194
|
if (this.#appName && this.#public) {
|
|
174
195
|
this.#compose()
|
|
175
196
|
}
|
|
@@ -251,24 +272,24 @@ export class Banner {
|
|
|
251
272
|
|
|
252
273
|
/**
|
|
253
274
|
* Create a middleware method that generates a banner for each request.
|
|
254
|
-
* @param { function } [
|
|
255
|
-
* @param { function } [
|
|
275
|
+
* @param { function } [Log] - an optional reference to the app level logging function.
|
|
276
|
+
* @param { function } [Error] - an optional reference to the app level error logging function.
|
|
256
277
|
* @returns { (ctx:object, next:function) => mixed } - Koa middleware function.
|
|
257
278
|
*/
|
|
258
|
-
use(
|
|
259
|
-
const _log =
|
|
260
|
-
const _error =
|
|
279
|
+
use(Log = null, Error = null) {
|
|
280
|
+
const _log = Log ?? console.log
|
|
281
|
+
// const _error = Error ?? console.error
|
|
261
282
|
_log('adding request banner to the app.')
|
|
262
283
|
const gGET = this.#borderGlyphGET
|
|
263
284
|
const gPUT = this.#borderGlyphPUT
|
|
264
285
|
const gPOST = this.#borderGlyphPOST
|
|
265
286
|
const gDEL = this.#borderGlyphDELETE
|
|
266
|
-
const n = this.#appName
|
|
267
|
-
return async function banner(ctx, next){
|
|
287
|
+
// const n = this.#appName
|
|
288
|
+
return async function banner(ctx, next = null) {
|
|
289
|
+
let _requestBanner
|
|
268
290
|
try {
|
|
269
|
-
// const _g = (/post/i.test(ctx.request.method)) ? '@' : g
|
|
270
291
|
let _g
|
|
271
|
-
switch(ctx.request.method.toLowerCase()) {
|
|
292
|
+
switch (ctx.request.method.toLowerCase()) {
|
|
272
293
|
case 'get':
|
|
273
294
|
_g = gGET
|
|
274
295
|
break
|
|
@@ -284,43 +305,65 @@ export class Banner {
|
|
|
284
305
|
default:
|
|
285
306
|
_g = gGET
|
|
286
307
|
}
|
|
287
|
-
|
|
288
|
-
|
|
308
|
+
if (!ctx) {
|
|
309
|
+
throw new Error('Missing required ctx object.')
|
|
310
|
+
}
|
|
311
|
+
if (!ctx.request.header.host) {
|
|
312
|
+
throw new Error('Missing required request header.host value.')
|
|
313
|
+
}
|
|
314
|
+
if (!ctx.request.method) {
|
|
315
|
+
throw new Error('Missing required request method value.')
|
|
316
|
+
}
|
|
317
|
+
if (!ctx.request.url) {
|
|
318
|
+
throw new Error('Missing required request url value.')
|
|
319
|
+
}
|
|
320
|
+
const _urlLabel = `${ctx.request.method}:`
|
|
289
321
|
const _url = `${ctx.request.protocol}://${ctx.request.header.host}${ctx.request.url}`
|
|
290
322
|
let _urlLine = `${_urlLabel} ${_url}`
|
|
291
323
|
const _refLabel = 'Referer:'
|
|
292
324
|
const _ref = ctx.request.header.referer ?? '<emtpy header field>'
|
|
293
325
|
let _refLine = `${_refLabel} ${_ref}`
|
|
294
|
-
const
|
|
326
|
+
const _ipLabel = 'From IP:'
|
|
327
|
+
const _ip = ctx.request.ip
|
|
328
|
+
let _ipLine = `${_ipLabel} ${_ip}`
|
|
329
|
+
const _longestLabel = [_urlLabel, _refLabel, _ipLabel].reduce((a, c) => {
|
|
295
330
|
if (a.length > (c.indexOf(':') + 1)) {
|
|
296
331
|
return a
|
|
297
332
|
}
|
|
298
333
|
return (c.indexOf(':') + 1)
|
|
299
334
|
}, '')
|
|
300
335
|
_refLine = _refLine.padStart(
|
|
301
|
-
(_longestLabel - _refLine.indexOf(':')) + _refLine.length,
|
|
336
|
+
(_longestLabel - _refLine.indexOf(':')) + _refLine.length,
|
|
337
|
+
' ',
|
|
302
338
|
)
|
|
303
339
|
_urlLine = _urlLine.padStart(
|
|
304
|
-
(_longestLabel - _urlLine.indexOf(':')) + _urlLine.length,
|
|
340
|
+
(_longestLabel - _urlLine.indexOf(':')) + _urlLine.length,
|
|
341
|
+
' ',
|
|
305
342
|
)
|
|
306
|
-
|
|
343
|
+
_ipLine = _ipLine.padStart(
|
|
344
|
+
(_longestLabel - _ipLine.indexOf(':')) + _ipLine.length,
|
|
345
|
+
' ',
|
|
346
|
+
)
|
|
347
|
+
const _longestLine = [_urlLine, _refLine, _ipLine].reduce((a, c) => {
|
|
307
348
|
if (a > c.length) return a
|
|
308
349
|
return c.length
|
|
309
350
|
}, '')
|
|
310
351
|
// _log('request banner _longestLine', _longestLine)
|
|
311
|
-
|
|
312
|
-
`${_g.padEnd(_longestLine + 5, _g)}\n`
|
|
352
|
+
_requestBanner = `${_g.padEnd(_longestLine + 5, _g)}\n`
|
|
313
353
|
+ `${_g} ${_urlLine}\n`
|
|
314
354
|
+ `${_g} ${_refLine}\n`
|
|
355
|
+
+ `${_g} ${_ipLine}\n`
|
|
315
356
|
+ `${_g.padEnd(_longestLine + 5, _g)}`
|
|
316
357
|
_log(_requestBanner)
|
|
317
|
-
|
|
318
|
-
|
|
358
|
+
if (next) {
|
|
359
|
+
await next(ctx.request.method)
|
|
360
|
+
}
|
|
319
361
|
} catch (e) {
|
|
320
|
-
_error('Failed after adding
|
|
321
|
-
_error(e)
|
|
322
|
-
ctx.throw(500,
|
|
362
|
+
// _error('Failed after adding the request banner.')
|
|
363
|
+
// _error(e)
|
|
364
|
+
ctx.throw(500, e)
|
|
323
365
|
}
|
|
324
|
-
|
|
325
|
-
|
|
366
|
+
return _requestBanner
|
|
367
|
+
} // end async closure function, Banner.use.banner()
|
|
368
|
+
} // end Banner.use()
|
|
326
369
|
}
|
package/test/test.js
CHANGED
|
@@ -8,8 +8,10 @@ import {
|
|
|
8
8
|
} from 'node:test'
|
|
9
9
|
import assert from 'node:assert/strict'
|
|
10
10
|
import fs from 'node:fs/promises'
|
|
11
|
+
import os from 'node:os'
|
|
11
12
|
import { Banner } from '../src/index.js'
|
|
12
13
|
const skip = { skip: true }
|
|
14
|
+
console.log(skip)
|
|
13
15
|
let cfg
|
|
14
16
|
let ctx
|
|
15
17
|
let ctx_POST
|
|
@@ -17,11 +19,30 @@ let ctx_GET
|
|
|
17
19
|
let ctx_PUT
|
|
18
20
|
let ctx_DEL
|
|
19
21
|
let next
|
|
20
|
-
console.log(skip)
|
|
21
22
|
describe('First test suite for banner package', async () => {
|
|
22
23
|
before(() => {
|
|
24
|
+
function getLocalIpAddress() {
|
|
25
|
+
const networkInterfaces = os.networkInterfaces();
|
|
26
|
+
let localIpAddress = null;
|
|
27
|
+
|
|
28
|
+
for (const interfaceName in networkInterfaces) {
|
|
29
|
+
const networkInterface = networkInterfaces[interfaceName];
|
|
30
|
+
for (const details of networkInterface) {
|
|
31
|
+
// Check for IPv4, not internal (loopback), and a valid address
|
|
32
|
+
if (details.family === 'IPv4' && !details.internal) {
|
|
33
|
+
localIpAddress = details.address;
|
|
34
|
+
break; // Found a suitable IPv4 address, exit inner loop
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (localIpAddress) {
|
|
38
|
+
break; // Found a suitable IPv4 address, exit outer loop
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return localIpAddress;
|
|
42
|
+
}
|
|
23
43
|
ctx = {
|
|
24
44
|
request: {
|
|
45
|
+
ip: getLocalIpAddress(),
|
|
25
46
|
protocol: 'https',
|
|
26
47
|
method: '',
|
|
27
48
|
url: '/a/really/long/url/to/a/special/page',
|
|
@@ -30,17 +51,10 @@ describe('First test suite for banner package', async () => {
|
|
|
30
51
|
referer: 'https://googoogle.com',
|
|
31
52
|
},
|
|
32
53
|
},
|
|
33
|
-
throw: (code, msg) => {
|
|
34
|
-
throw new Error(`Error code ${code}: ${msg}`)
|
|
35
|
-
}
|
|
36
54
|
}
|
|
37
|
-
|
|
38
|
-
ctx_PUT = { ...ctx }
|
|
39
|
-
ctx_POST = { ...ctx }
|
|
40
|
-
ctx_GET = { ...ctx }
|
|
41
|
-
next = async () => {
|
|
55
|
+
next = async (m) => {
|
|
42
56
|
setTimeout(() => {
|
|
43
|
-
console.log(
|
|
57
|
+
console.log(`the next(${m}) function`)
|
|
44
58
|
}, 1000)
|
|
45
59
|
}
|
|
46
60
|
cfg = {
|
|
@@ -68,44 +82,64 @@ describe('First test suite for banner package', async () => {
|
|
|
68
82
|
})
|
|
69
83
|
|
|
70
84
|
it('Should work as a koajs middleware function - POST method.', async () => {
|
|
71
|
-
ctx_POST = Object.assign(
|
|
85
|
+
ctx_POST = Object.assign({}, ctx)
|
|
72
86
|
ctx_POST.request.method = 'POST'
|
|
87
|
+
ctx_POST.throw = (code, err, {} = null) => {
|
|
88
|
+
throw new Error(`${code}, ${msg}`)
|
|
89
|
+
}
|
|
73
90
|
console.log(ctx_POST)
|
|
74
91
|
const post = new Banner(ctx_POST)
|
|
75
|
-
assert(await post.use()(
|
|
92
|
+
assert(await post.use()(ctx_POST, next))
|
|
76
93
|
})
|
|
77
94
|
|
|
78
95
|
it('Should work as a koajs middleware function - GET method.', async () => {
|
|
79
|
-
ctx_GET = Object.assign(
|
|
96
|
+
ctx_GET = Object.assign({}, ctx)
|
|
80
97
|
ctx_GET.request.method = 'GET'
|
|
98
|
+
ctx_GET.throw = (code, err, {} = null) => {
|
|
99
|
+
throw new Error(`${code}, ${msg}`)
|
|
100
|
+
}
|
|
81
101
|
console.log(ctx_GET)
|
|
82
102
|
const get = new Banner(ctx_GET)
|
|
83
|
-
assert(await get.use()(
|
|
103
|
+
assert(await get.use()(ctx_GET, next))
|
|
84
104
|
})
|
|
85
105
|
|
|
86
106
|
it('Should work as a koajs middleware function - PUT method.', async () => {
|
|
87
|
-
ctx_PUT = Object.assign(
|
|
107
|
+
ctx_PUT = Object.assign({}, ctx)
|
|
88
108
|
ctx_PUT.request.method = 'PUT'
|
|
109
|
+
ctx_PUT.throw = (code, err, {} = null) => {
|
|
110
|
+
throw new Error(`${code}, ${msg}`)
|
|
111
|
+
}
|
|
89
112
|
console.log(ctx_PUT)
|
|
90
113
|
const put = new Banner(ctx_PUT)
|
|
91
|
-
assert(await put.use()(
|
|
114
|
+
assert(await put.use()(ctx_PUT, next))
|
|
92
115
|
})
|
|
93
116
|
|
|
94
117
|
it('Should work as a koajs middleware function - DELETE method.', async () => {
|
|
95
|
-
ctx_DEL = Object.assign(
|
|
118
|
+
ctx_DEL = Object.assign({}, ctx)
|
|
96
119
|
ctx_DEL.request.method = 'DELETE'
|
|
120
|
+
ctx_DEL.throw = (code, err, {} = null) => {
|
|
121
|
+
throw new Error(`${code}, ${msg}`)
|
|
122
|
+
}
|
|
97
123
|
console.log(ctx_DEL)
|
|
98
124
|
const del = new Banner(ctx_DEL)
|
|
99
|
-
assert(await del.use()(
|
|
125
|
+
assert(await del.use()(ctx_DEL, next))
|
|
100
126
|
})
|
|
101
127
|
|
|
102
128
|
it('Should fail as a koajs middleware function, missing input parameters.', async () => {
|
|
103
|
-
ctx.
|
|
104
|
-
ctx.request.
|
|
105
|
-
ctx.
|
|
129
|
+
ctx.request.header.host = null
|
|
130
|
+
ctx.request.url = null
|
|
131
|
+
ctx.throw = (code, err) => {
|
|
132
|
+
// console.log(err.message)
|
|
133
|
+
throw err
|
|
134
|
+
}
|
|
106
135
|
console.log(ctx)
|
|
107
|
-
const
|
|
108
|
-
await
|
|
109
|
-
|
|
136
|
+
const req = new Banner()
|
|
137
|
+
const use = await req.use()
|
|
138
|
+
assert.rejects(
|
|
139
|
+
async () => {
|
|
140
|
+
await use(ctx)
|
|
141
|
+
},
|
|
142
|
+
Error,
|
|
143
|
+
)
|
|
110
144
|
})
|
|
111
145
|
})
|