presidium 1.4.4 → 1.4.6

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/HTTP.js CHANGED
@@ -2,6 +2,7 @@ const http = require('http')
2
2
  const https = require('https')
3
3
  const path = require('path')
4
4
  const stream = require('stream')
5
+ const httpConfigure = require('./internal/httpConfigure')
5
6
 
6
7
  /**
7
8
  * @name HTTP
@@ -52,35 +53,15 @@ const stream = require('stream')
52
53
  */
53
54
  class HTTP {
54
55
  constructor(baseUrl, requestOptions = {}) {
55
- if (typeof baseUrl == 'string') {
56
- this.baseUrl = new URL(baseUrl)
57
- }
58
- else if (baseUrl == null) {
59
- throw new TypeError('baseUrl invalid')
60
- }
61
- else if (typeof baseUrl.toString == 'function') {
62
- this.baseUrl = new URL(baseUrl)
63
- }
64
- else if (baseUrl.constructor == URL) {
65
- this.baseUrl = baseUrl
56
+ if (
57
+ typeof baseUrl == 'string'
58
+ || typeof baseUrl?.toString == 'function'
59
+ || baseUrl?.constructor == URL
60
+ ) {
61
+ httpConfigure.call(this, baseUrl, requestOptions)
66
62
  } else {
67
- throw new TypeError('baseUrl invalid')
68
- }
69
-
70
- this.client = this.baseUrl.protocol == 'https:' ? https : http
71
- this.requestOptions = {
72
- hostname: this.baseUrl.hostname,
73
- protocol: this.baseUrl.protocol,
74
- ...requestOptions,
75
- }
76
-
77
- this.requestHeaders = {}
78
-
79
- if (this.baseUrl.username && this.baseUrl.password) {
80
- const { username, password } = this.baseUrl
81
- const credentials = `${username}:${password}`
82
- const encodedCredentials = Buffer.from(credentials).toString('base64')
83
- this.requestHeaders['Authorization'] = `Basic ${encodedCredentials}`
63
+ this.client = undefined
64
+ this.requestOptions = {}
84
65
  }
85
66
 
86
67
  this._sockets = new Set()
@@ -89,7 +70,8 @@ class HTTP {
89
70
  request(options) {
90
71
  const { body, ...requestOptions } = options
91
72
  return new Promise((resolve, reject) => {
92
- const request = this.client.request(requestOptions, response => {
73
+ const client = requestOptions.protocol == 'https:' ? https : http
74
+ const request = client.request(requestOptions, response => {
93
75
  response.status = response.statusCode
94
76
  response.ok = response.statusCode >= 200 && response.statusCode <= 299
95
77
 
@@ -178,6 +160,81 @@ class HTTP {
178
160
  })
179
161
  }
180
162
 
163
+ /**
164
+ * @name _requestMethod
165
+ *
166
+ * @docs
167
+ * ```coffeescript [specscript]
168
+ * module http 'https://nodejs.org/docs/latest-v24.x/api/http.html'
169
+ *
170
+ * type RequestOptions = {
171
+ * agent: http.Agent,
172
+ * auth: string,
173
+ * createConnection: function,
174
+ * defaultPort: number,
175
+ * family: number,
176
+ * headers: object,
177
+ * hints: number,
178
+ * host: string,
179
+ * hostname: string,
180
+ * insecureHTTPParser: boolean,
181
+ * joinDuplicateHeaders: boolean,
182
+ * localAddress: string,
183
+ * localPort: number,
184
+ * lookup: function,
185
+ * maxHeaderSize: number,
186
+ * method: string,
187
+ * path: string,
188
+ * port: number,
189
+ * protocol: string,
190
+ * setDefaultHeaders: boolean,
191
+ * setHost: boolean,
192
+ * signal: AbortSignal,
193
+ * socketPath: string,
194
+ * timeout: number,
195
+ * uniqueHeaders: Array<string>,
196
+ * }
197
+ *
198
+ * _requestMethod(
199
+ * method string,
200
+ * relativeUrl string,
201
+ * options RequestOptions
202
+ * ) -> response http.ServerResponse
203
+ * ```
204
+ */
205
+ _requestMethod(method, relativeUrl, options = {}) {
206
+ if (relativeUrl.startsWith('http')) {
207
+ const url_ = new URL(relativeUrl)
208
+ const requestOptions = {
209
+ hostname: url_.hostname,
210
+ protocol: url_.protocol,
211
+ port: url_.port,
212
+ path: url_.pathname,
213
+ method,
214
+ headers: {
215
+ ...options.headers,
216
+ },
217
+ body: options.body,
218
+ }
219
+ return this.request(requestOptions)
220
+ }
221
+
222
+ const requestOptions = {
223
+ ...this.requestOptions,
224
+ hostname: this.baseUrl.hostname,
225
+ protocol: this.baseUrl.protocol,
226
+ port: this.baseUrl.port,
227
+ path: path.join(this.baseUrl.pathname, relativeUrl),
228
+ method,
229
+ headers: {
230
+ ...this.requestHeaders,
231
+ ...options.headers
232
+ },
233
+ body: options.body,
234
+ }
235
+ return this.request(requestOptions)
236
+ }
237
+
181
238
  /**
182
239
  * @name get
183
240
  *
@@ -232,20 +289,7 @@ class HTTP {
232
289
  * ```
233
290
  */
234
291
  get(relativeUrl, options = {}) {
235
- const requestOptions = {
236
- ...this.requestOptions,
237
- hostname: this.baseUrl.hostname,
238
- protocol: this.baseUrl.protocol,
239
- port: this.baseUrl.port,
240
- path: path.join(this.baseUrl.pathname, relativeUrl),
241
- method: 'GET',
242
- headers: {
243
- ...this.requestHeaders,
244
- ...options.headers
245
- },
246
- body: options.body,
247
- }
248
- return this.request(requestOptions)
292
+ return this._requestMethod('GET', relativeUrl, options)
249
293
  }
250
294
 
251
295
  /**
@@ -301,8 +345,8 @@ class HTTP {
301
345
  * const response = await http.GET('/todos/1')
302
346
  * ```
303
347
  */
304
- GET(...args) {
305
- return this.get(...args)
348
+ GET(relativeUrl, options = {}) {
349
+ return this._requestMethod('GET', relativeUrl, options)
306
350
  }
307
351
 
308
352
  /**
@@ -359,20 +403,7 @@ class HTTP {
359
403
  * ```
360
404
  */
361
405
  head(relativeUrl, options = {}) {
362
- const requestOptions = {
363
- ...this.requestOptions,
364
- hostname: this.baseUrl.hostname,
365
- protocol: this.baseUrl.protocol,
366
- port: this.baseUrl.port,
367
- path: path.join(this.baseUrl.pathname, relativeUrl),
368
- method: 'HEAD',
369
- headers: {
370
- ...this.requestHeaders,
371
- ...options.headers
372
- },
373
- body: options.body,
374
- }
375
- return this.request(requestOptions)
406
+ return this._requestMethod('HEAD', relativeUrl, options)
376
407
  }
377
408
 
378
409
  /**
@@ -428,8 +459,8 @@ class HTTP {
428
459
  * const response = await http.HEAD('/todos/1')
429
460
  * ```
430
461
  */
431
- HEAD(...args) {
432
- return this.head(...args)
462
+ HEAD(relativeUrl, options = {}) {
463
+ return this._requestMethod('HEAD', relativeUrl, options)
433
464
  }
434
465
 
435
466
  /**
@@ -486,20 +517,7 @@ class HTTP {
486
517
  * ```
487
518
  */
488
519
  post(relativeUrl, options = {}) {
489
- const requestOptions = {
490
- ...this.requestOptions,
491
- hostname: this.baseUrl.hostname,
492
- protocol: this.baseUrl.protocol,
493
- port: this.baseUrl.port,
494
- path: path.join(this.baseUrl.pathname, relativeUrl),
495
- method: 'POST',
496
- headers: {
497
- ...this.requestHeaders,
498
- ...options.headers
499
- },
500
- body: options.body,
501
- }
502
- return this.request(requestOptions)
520
+ return this._requestMethod('POST', relativeUrl, options)
503
521
  }
504
522
 
505
523
  /**
@@ -555,8 +573,8 @@ class HTTP {
555
573
  * const response = await http.POST('/todos/1')
556
574
  * ```
557
575
  */
558
- POST(...args) {
559
- return this.post(...args)
576
+ POST(relativeUrl, options = {}) {
577
+ return this._requestMethod('POST', relativeUrl, options)
560
578
  }
561
579
 
562
580
  /**
@@ -612,20 +630,7 @@ class HTTP {
612
630
  * ```
613
631
  */
614
632
  put(relativeUrl, options = {}) {
615
- const requestOptions = {
616
- ...this.requestOptions,
617
- hostname: this.baseUrl.hostname,
618
- protocol: this.baseUrl.protocol,
619
- port: this.baseUrl.port,
620
- path: path.join(this.baseUrl.pathname, relativeUrl),
621
- method: 'PUT',
622
- headers: {
623
- ...this.requestHeaders,
624
- ...options.headers
625
- },
626
- body: options.body,
627
- }
628
- return this.request(requestOptions)
633
+ return this._requestMethod('PUT', relativeUrl, options)
629
634
  }
630
635
 
631
636
  /**
@@ -681,8 +686,8 @@ class HTTP {
681
686
  * const response = await http.PUT('/todos/1')
682
687
  * ```
683
688
  */
684
- PUT(...args) {
685
- return this.put(...args)
689
+ PUT(relativeUrl, options = {}) {
690
+ return this._requestMethod('PUT', relativeUrl, options)
686
691
  }
687
692
 
688
693
  /**
@@ -739,20 +744,7 @@ class HTTP {
739
744
  * ```
740
745
  */
741
746
  patch(relativeUrl, options = {}) {
742
- const requestOptions = {
743
- ...this.requestOptions,
744
- hostname: this.baseUrl.hostname,
745
- protocol: this.baseUrl.protocol,
746
- port: this.baseUrl.port,
747
- path: path.join(this.baseUrl.pathname, relativeUrl),
748
- method: 'PATCH',
749
- headers: {
750
- ...this.requestHeaders,
751
- ...options.headers
752
- },
753
- body: options.body,
754
- }
755
- return this.request(requestOptions)
747
+ return this._requestMethod('PATCH', relativeUrl, options)
756
748
  }
757
749
 
758
750
  /**
@@ -808,8 +800,8 @@ class HTTP {
808
800
  * const response = await http.PATCH('/todos/1')
809
801
  * ```
810
802
  */
811
- PATCH(...args) {
812
- return this.patch(...args)
803
+ PATCH(relativeUrl, options = {}) {
804
+ return this._requestMethod('PATCH', relativeUrl, options)
813
805
  }
814
806
 
815
807
  /**
@@ -866,20 +858,7 @@ class HTTP {
866
858
  * ```
867
859
  */
868
860
  delete(relativeUrl, options = {}) {
869
- const requestOptions = {
870
- ...this.requestOptions,
871
- hostname: this.baseUrl.hostname,
872
- protocol: this.baseUrl.protocol,
873
- port: this.baseUrl.port,
874
- path: path.join(this.baseUrl.pathname, relativeUrl),
875
- method: 'DELETE',
876
- headers: {
877
- ...this.requestHeaders,
878
- ...options.headers
879
- },
880
- body: options.body,
881
- }
882
- return this.request(requestOptions)
861
+ return this._requestMethod('DELETE', relativeUrl, options)
883
862
  }
884
863
 
885
864
  /**
@@ -935,8 +914,8 @@ class HTTP {
935
914
  * const response = await http.DELETE('/todos/1')
936
915
  * ```
937
916
  */
938
- DELETE(...args) {
939
- return this.delete(...args)
917
+ DELETE(relativeUrl, options = {}) {
918
+ return this._requestMethod('DELETE', relativeUrl, options)
940
919
  }
941
920
 
942
921
  /**
@@ -1117,20 +1096,7 @@ class HTTP {
1117
1096
  * ```
1118
1097
  */
1119
1098
  options(relativeUrl, options2 = {}) {
1120
- const requestOptions = {
1121
- ...this.requestOptions,
1122
- hostname: this.baseUrl.hostname,
1123
- protocol: this.baseUrl.protocol,
1124
- port: this.baseUrl.port,
1125
- path: path.join(this.baseUrl.pathname, relativeUrl),
1126
- method: 'OPTIONS',
1127
- headers: {
1128
- ...this.requestHeaders,
1129
- ...options2.headers
1130
- },
1131
- body: options2.body,
1132
- }
1133
- return this.request(requestOptions)
1099
+ return this._requestMethod('OPTIONS', relativeUrl, options2)
1134
1100
  }
1135
1101
 
1136
1102
  /**
@@ -1186,8 +1152,8 @@ class HTTP {
1186
1152
  * const response = await http.OPTIONS('/todos/1')
1187
1153
  * ```
1188
1154
  */
1189
- OPTIONS(...args) {
1190
- return this.options(...args)
1155
+ OPTIONS(relativeUrl, options = {}) {
1156
+ return this._requestMethod('OPTIONS', relativeUrl, options)
1191
1157
  }
1192
1158
 
1193
1159
  /**
@@ -1244,20 +1210,7 @@ class HTTP {
1244
1210
  * ```
1245
1211
  */
1246
1212
  trace(relativeUrl, options = {}) {
1247
- const requestOptions = {
1248
- ...this.requestOptions,
1249
- hostname: this.baseUrl.hostname,
1250
- protocol: this.baseUrl.protocol,
1251
- port: this.baseUrl.port,
1252
- path: path.join(this.baseUrl.pathname, relativeUrl),
1253
- method: 'TRACE',
1254
- headers: {
1255
- ...this.requestHeaders,
1256
- ...options.headers
1257
- },
1258
- body: options.body,
1259
- }
1260
- return this.request(requestOptions)
1213
+ return this._requestMethod('TRACE', relativeUrl, options)
1261
1214
  }
1262
1215
 
1263
1216
  /**
@@ -1313,8 +1266,8 @@ class HTTP {
1313
1266
  * const response = await http.TRACE('/todos/1')
1314
1267
  * ```
1315
1268
  */
1316
- TRACE(...args) {
1317
- return this.trace(...args)
1269
+ TRACE(relativeUrl, options = {}) {
1270
+ return this._requestMethod('TRACE', relativeUrl, options)
1318
1271
  }
1319
1272
 
1320
1273
  /**
@@ -0,0 +1,72 @@
1
+ const http = require('http')
2
+ const https = require('https')
3
+
4
+ /**
5
+ * @name httpConfigure
6
+ *
7
+ * @docs
8
+ * ```coffeescript [specscript]
9
+ * type RequestOptions = {
10
+ * agent: http.Agent,
11
+ * auth: string,
12
+ * createConnection: function,
13
+ * defaultPort: number,
14
+ * family: number,
15
+ * headers: object,
16
+ * hints: number,
17
+ * host: string,
18
+ * hostname: string,
19
+ * insecureHTTPParser: boolean,
20
+ * joinDuplicateHeaders: boolean,
21
+ * localAddress: string,
22
+ * localPort: number,
23
+ * lookup: function,
24
+ * maxHeaderSize: number,
25
+ * method: string,
26
+ * path: string,
27
+ * port: number,
28
+ * protocol: string,
29
+ * setDefaultHeaders: boolean,
30
+ * setHost: boolean,
31
+ * signal: AbortSignal,
32
+ * socketPath: string,
33
+ * timeout: number,
34
+ * uniqueHeaders: Array<string>,
35
+ * }
36
+ *
37
+ * httpConfigure(baseUrl string|URL, requestOptions RequestOptions) -> undefined
38
+ * ```
39
+ */
40
+ function httpConfigure(baseUrl, requestOptions) {
41
+ if (typeof baseUrl == 'string') {
42
+ this.baseUrl = new URL(baseUrl)
43
+ }
44
+ else if (typeof baseUrl?.toString == 'function') {
45
+ this.baseUrl = new URL(baseUrl)
46
+ }
47
+ else if (baseUrl?.constructor == URL) {
48
+ this.baseUrl = baseUrl
49
+ }
50
+ else {
51
+ throw new TypeError('Invalid baseUrl')
52
+ }
53
+
54
+ this.client = this.baseUrl.protocol == 'https:' ? https : http
55
+
56
+ this.requestOptions = {
57
+ hostname: this.baseUrl.hostname,
58
+ protocol: this.baseUrl.protocol,
59
+ ...requestOptions,
60
+ }
61
+
62
+ this.requestHeaders = {}
63
+
64
+ if (this.baseUrl.username && this.baseUrl.password) {
65
+ const { username, password } = this.baseUrl
66
+ const credentials = `${username}:${password}`
67
+ const encodedCredentials = Buffer.from(credentials).toString('base64')
68
+ this.requestHeaders['Authorization'] = `Basic ${encodedCredentials}`
69
+ }
70
+ }
71
+
72
+ module.exports = httpConfigure
@@ -0,0 +1,44 @@
1
+ const assert = require('assert')
2
+ const Test = require('thunk-test')
3
+ const httpConfigure = require('./httpConfigure')
4
+
5
+ const test1 = new Test('httpConfigure', httpConfigure)
6
+ test1.case('http://localhost:7357', function baseUrlString() {
7
+ assert.equal(this.baseUrl.constructor, URL)
8
+ })
9
+
10
+ const test2 = new Test('httpConfigure', httpConfigure)
11
+ test2.case({ toString: () => 'http://localhost:7357' }, function baseUrlToString() {
12
+ assert.equal(this.baseUrl.constructor, URL)
13
+ })
14
+
15
+ const test3 = new Test('httpConfigure', httpConfigure)
16
+ test3.throws(undefined, new TypeError('Invalid baseUrl'))
17
+ test3.throws(1, new TypeError('Invalid URL'))
18
+
19
+ const test4 = new Test('httpConfigure', httpConfigure)
20
+ test4.case('http://username:password@localhost:7357', function baseUrlStringWithUsernamePassword() {
21
+ assert.equal(this.baseUrl.constructor, URL)
22
+ assert.equal(this.baseUrl.username, 'username')
23
+ assert.equal(this.baseUrl.password, 'password')
24
+ })
25
+
26
+ const test5 = new Test('httpConfigure', httpConfigure)
27
+ test5.case('https://localhost:7357', function baseUrlString() {
28
+ assert.equal(this.baseUrl.constructor, URL)
29
+ assert.equal(this.baseUrl.protocol, 'https:')
30
+ })
31
+
32
+ const test = Test.all([
33
+ test1,
34
+ test2,
35
+ test3,
36
+ test4,
37
+ test5,
38
+ ])
39
+
40
+ if (process.argv[1] == __filename) {
41
+ test()
42
+ }
43
+
44
+ module.exports = test
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "presidium",
3
- "version": "1.4.4",
3
+ "version": "1.4.6",
4
4
  "description": "A library for creating web services",
5
5
  "author": "Richard Tong",
6
6
  "license": "MIT",