tdrpa.tdworker 1.1.9.3__py39-none-win_amd64.whl

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.
Files changed (97) hide show
  1. tdrpa/_tdxlwings/__init__.py +193 -0
  2. tdrpa/_tdxlwings/__pycache__/__init__.cpython-311.pyc +0 -0
  3. tdrpa/_tdxlwings/__pycache__/__init__.cpython-38.pyc +0 -0
  4. tdrpa/_tdxlwings/__pycache__/_win32patch.cpython-311.pyc +0 -0
  5. tdrpa/_tdxlwings/__pycache__/_win32patch.cpython-38.pyc +0 -0
  6. tdrpa/_tdxlwings/__pycache__/_xlwindows.cpython-311.pyc +0 -0
  7. tdrpa/_tdxlwings/__pycache__/_xlwindows.cpython-38.pyc +0 -0
  8. tdrpa/_tdxlwings/__pycache__/apps.cpython-311.pyc +0 -0
  9. tdrpa/_tdxlwings/__pycache__/apps.cpython-38.pyc +0 -0
  10. tdrpa/_tdxlwings/__pycache__/base_classes.cpython-311.pyc +0 -0
  11. tdrpa/_tdxlwings/__pycache__/base_classes.cpython-38.pyc +0 -0
  12. tdrpa/_tdxlwings/__pycache__/com_server.cpython-311.pyc +0 -0
  13. tdrpa/_tdxlwings/__pycache__/com_server.cpython-38.pyc +0 -0
  14. tdrpa/_tdxlwings/__pycache__/constants.cpython-311.pyc +0 -0
  15. tdrpa/_tdxlwings/__pycache__/constants.cpython-38.pyc +0 -0
  16. tdrpa/_tdxlwings/__pycache__/expansion.cpython-311.pyc +0 -0
  17. tdrpa/_tdxlwings/__pycache__/expansion.cpython-38.pyc +0 -0
  18. tdrpa/_tdxlwings/__pycache__/main.cpython-311.pyc +0 -0
  19. tdrpa/_tdxlwings/__pycache__/main.cpython-38.pyc +0 -0
  20. tdrpa/_tdxlwings/__pycache__/udfs.cpython-311.pyc +0 -0
  21. tdrpa/_tdxlwings/__pycache__/udfs.cpython-38.pyc +0 -0
  22. tdrpa/_tdxlwings/__pycache__/utils.cpython-311.pyc +0 -0
  23. tdrpa/_tdxlwings/__pycache__/utils.cpython-38.pyc +0 -0
  24. tdrpa/_tdxlwings/_win32patch.py +90 -0
  25. tdrpa/_tdxlwings/_xlmac.py +2240 -0
  26. tdrpa/_tdxlwings/_xlwindows.py +2518 -0
  27. tdrpa/_tdxlwings/addin/Dictionary.cls +474 -0
  28. tdrpa/_tdxlwings/addin/IWebAuthenticator.cls +71 -0
  29. tdrpa/_tdxlwings/addin/WebClient.cls +772 -0
  30. tdrpa/_tdxlwings/addin/WebHelpers.bas +3203 -0
  31. tdrpa/_tdxlwings/addin/WebRequest.cls +875 -0
  32. tdrpa/_tdxlwings/addin/WebResponse.cls +453 -0
  33. tdrpa/_tdxlwings/addin/xlwings.xlam +0 -0
  34. tdrpa/_tdxlwings/apps.py +35 -0
  35. tdrpa/_tdxlwings/base_classes.py +1092 -0
  36. tdrpa/_tdxlwings/cli.py +1306 -0
  37. tdrpa/_tdxlwings/com_server.py +385 -0
  38. tdrpa/_tdxlwings/constants.py +3080 -0
  39. tdrpa/_tdxlwings/conversion/__init__.py +103 -0
  40. tdrpa/_tdxlwings/conversion/framework.py +147 -0
  41. tdrpa/_tdxlwings/conversion/numpy_conv.py +34 -0
  42. tdrpa/_tdxlwings/conversion/pandas_conv.py +184 -0
  43. tdrpa/_tdxlwings/conversion/standard.py +321 -0
  44. tdrpa/_tdxlwings/expansion.py +83 -0
  45. tdrpa/_tdxlwings/ext/__init__.py +3 -0
  46. tdrpa/_tdxlwings/ext/sql.py +73 -0
  47. tdrpa/_tdxlwings/html/xlwings-alert.html +71 -0
  48. tdrpa/_tdxlwings/js/xlwings.js +577 -0
  49. tdrpa/_tdxlwings/js/xlwings.ts +729 -0
  50. tdrpa/_tdxlwings/mac_dict.py +6399 -0
  51. tdrpa/_tdxlwings/main.py +5205 -0
  52. tdrpa/_tdxlwings/mistune/__init__.py +63 -0
  53. tdrpa/_tdxlwings/mistune/block_parser.py +366 -0
  54. tdrpa/_tdxlwings/mistune/inline_parser.py +216 -0
  55. tdrpa/_tdxlwings/mistune/markdown.py +84 -0
  56. tdrpa/_tdxlwings/mistune/renderers.py +220 -0
  57. tdrpa/_tdxlwings/mistune/scanner.py +121 -0
  58. tdrpa/_tdxlwings/mistune/util.py +41 -0
  59. tdrpa/_tdxlwings/pro/__init__.py +40 -0
  60. tdrpa/_tdxlwings/pro/_xlcalamine.py +536 -0
  61. tdrpa/_tdxlwings/pro/_xlofficejs.py +146 -0
  62. tdrpa/_tdxlwings/pro/_xlremote.py +1293 -0
  63. tdrpa/_tdxlwings/pro/custom_functions_code.js +150 -0
  64. tdrpa/_tdxlwings/pro/embedded_code.py +60 -0
  65. tdrpa/_tdxlwings/pro/udfs_officejs.py +549 -0
  66. tdrpa/_tdxlwings/pro/utils.py +199 -0
  67. tdrpa/_tdxlwings/quickstart.xlsm +0 -0
  68. tdrpa/_tdxlwings/quickstart_addin.xlam +0 -0
  69. tdrpa/_tdxlwings/quickstart_addin_ribbon.xlam +0 -0
  70. tdrpa/_tdxlwings/quickstart_fastapi/main.py +47 -0
  71. tdrpa/_tdxlwings/quickstart_fastapi/requirements.txt +3 -0
  72. tdrpa/_tdxlwings/quickstart_standalone.xlsm +0 -0
  73. tdrpa/_tdxlwings/reports.py +12 -0
  74. tdrpa/_tdxlwings/rest/__init__.py +1 -0
  75. tdrpa/_tdxlwings/rest/api.py +368 -0
  76. tdrpa/_tdxlwings/rest/serializers.py +103 -0
  77. tdrpa/_tdxlwings/server.py +14 -0
  78. tdrpa/_tdxlwings/udfs.py +775 -0
  79. tdrpa/_tdxlwings/utils.py +777 -0
  80. tdrpa/_tdxlwings/xlwings-0.31.6.applescript +30 -0
  81. tdrpa/_tdxlwings/xlwings.bas +2061 -0
  82. tdrpa/_tdxlwings/xlwings_custom_addin.bas +2042 -0
  83. tdrpa/_tdxlwings/xlwingslib.cp38-win_amd64.pyd +0 -0
  84. tdrpa/tdworker/__init__.pyi +8 -0
  85. tdrpa/tdworker/_excel.pyi +703 -0
  86. tdrpa/tdworker/_img.pyi +173 -0
  87. tdrpa/tdworker/_os.pyi +46 -0
  88. tdrpa/tdworker/_w.pyi +129 -0
  89. tdrpa/tdworker/_web.pyi +248 -0
  90. tdrpa/tdworker/_winE.pyi +246 -0
  91. tdrpa/tdworker/_winK.pyi +74 -0
  92. tdrpa/tdworker/_winM.pyi +117 -0
  93. tdrpa/tdworker.cp39-win_amd64.pyd +0 -0
  94. tdrpa.tdworker-1.1.9.3.dist-info/METADATA +25 -0
  95. tdrpa.tdworker-1.1.9.3.dist-info/RECORD +97 -0
  96. tdrpa.tdworker-1.1.9.3.dist-info/WHEEL +5 -0
  97. tdrpa.tdworker-1.1.9.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,875 @@
1
+ VERSION 1.0 CLASS
2
+ BEGIN
3
+ MultiUse = -1 'True
4
+ END
5
+ Attribute VB_Name = "WebRequest"
6
+ Attribute VB_GlobalNameSpace = False
7
+ Attribute VB_Creatable = False
8
+ Attribute VB_PredeclaredId = False
9
+ Attribute VB_Exposed = True
10
+ ''
11
+ ' WebRequest v4.1.6
12
+ ' (c) Tim Hall - https://github.com/VBA-tools/VBA-Web
13
+ '
14
+ ' `WebRequest` is used to create detailed requests
15
+ ' (including formatting, querystrings, headers, cookies, and much more).
16
+ '
17
+ ' Usage:
18
+ ' ```VB.net
19
+ ' Dim Request As New WebRequest
20
+ ' Request.Resource = "users/{Id}"
21
+ '
22
+ ' Request.Method = WebMethod.HttpPut
23
+ ' Request.RequestFormat = WebFormat.UrlEncoded
24
+ ' Request.ResponseFormat = WebFormat.Json
25
+ '
26
+ ' Dim Body As New Dictionary
27
+ ' Body.Add "name", "Tim"
28
+ ' Body.Add "project", "VBA-Web"
29
+ ' Set Request.Body = Body
30
+ '
31
+ ' Request.AddUrlSegment "Id", 123
32
+ ' Request.AddQuerystringParam "api_key", "abcd"
33
+ ' Request.AddHeader "Authorization", "Token ..."
34
+ '
35
+ ' ' -> PUT (Client.BaseUrl)users/123?api_key=abcd
36
+ ' ' Authorization: Token ...
37
+ ' '
38
+ ' ' name=Tim&project=VBA-Web
39
+ ' ```
40
+ '
41
+ ' Errors:
42
+ ' 11020 / 80042b0c / -2147210484 - Cannot add body parameter to non-Dictionary
43
+ '
44
+ ' @class WebRequest
45
+ ' @author tim.hall.engr@gmail.com
46
+ ' @license MIT (http://www.opensource.org/licenses/mit-license.php)
47
+ '' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ '
48
+ Option Explicit
49
+
50
+ ' --------------------------------------------- '
51
+ ' Constants and Private Variables
52
+ ' --------------------------------------------- '
53
+
54
+ Private web_pRequestFormat As WebFormat
55
+ Private web_pResponseFormat As WebFormat
56
+ Private web_pCustomRequestFormat As String
57
+ Private web_pCustomResponseFormat As String
58
+ Private web_pBody As Variant
59
+ Private web_pConvertedBody As Variant
60
+ Private web_pContentType As String
61
+ Private web_pAccept As String
62
+ Private web_pContentLength As Long
63
+ Private web_pId As String
64
+
65
+ ' --------------------------------------------- '
66
+ ' Properties
67
+ ' --------------------------------------------- '
68
+
69
+ ''
70
+ ' Set the request's portion of the url to be appended to the client's BaseUrl.
71
+ ' Can include Url Segments for dynamic values
72
+ ' and Querystring parameters are smart enough to be appended to existing querystring
73
+ ' (or added to resource if there isn't an existing querystring).
74
+ '
75
+ ' @example
76
+ ' ```VB.net
77
+ ' Dim Client As New WebClient
78
+ ' Client.BaseUrl = "https://api.example.com/"
79
+ '
80
+ ' Dim Request As New WebRequest
81
+ ' Request.Resource = "messages"
82
+ '
83
+ ' ' -> Url: https://api.example.com/messages
84
+ '
85
+ ' Request.Resource = "messages/{id}?a=1"
86
+ ' Request.AddUrlSegment "id", 123
87
+ ' Request.AddQuerystringParam "b", 2
88
+ '
89
+ ' ' -> Url: https://api.example.com/messages/123?a=1&b=2
90
+ ' ```
91
+ '
92
+ ' @property Resource
93
+ ' @type String
94
+ ''
95
+ Public Resource As String
96
+
97
+ ''
98
+ ' Set the HTTP method to be used for the request:
99
+ ' GET, POST, PUT, PATCH, DELETE
100
+ '
101
+ ' @example
102
+ ' ```VB.net
103
+ ' Dim Request As New WebRequest
104
+ ' Request.Method = WebMethod.HttpGet
105
+ ' Request.Method = WebMethod.HttpPost
106
+ ' ' or HttpPut / HttpPatch / HttpDelete
107
+ ' ```
108
+ '
109
+ ' @property Method
110
+ ' @type WebMethod
111
+ ''
112
+ Public Method As WebMethod
113
+
114
+ ''
115
+ ' _Note_ To add headers, use [`AddHeader`](#/WebRequest/AddHeader).
116
+ '
117
+ ' `Collection` of Headers to include with request,
118
+ ' stored as `KeyValue` (`Dictionary: {Key: "...", Value: "..."}`).
119
+ '
120
+ ' @property Headers
121
+ ' @type Collection
122
+ ''
123
+ Public headers As Collection
124
+
125
+ ''
126
+ ' _Note_ To add querystring parameters, use [`AddQuerystringParam`](#/WebRequest/AddQuerystringParam).
127
+ '
128
+ ' `Collection` of querystring parameters to include with request,
129
+ ' stored as `KeyValue` (`Dictionary: {Key: "...", Value: "..."}`).
130
+ '
131
+ ' @property QuerystringParams
132
+ ' @type Collection
133
+ ''
134
+ Public QuerystringParams As Collection
135
+
136
+ ''
137
+ ' _Note_ To add Url Segments, use [`AddUrlSegment`](#/WebRequest/AddUrlSegment)
138
+ '
139
+ ' Url Segments are used to easily add dynamic values to `Resource`.
140
+ ' Create a Url Segement in `Resource` with curly brackets and then
141
+ ' replace with dynamic value with [`AddUrlSegment`](#AddUrlSegment).
142
+ '
143
+ ' @example
144
+ ' ```VB.net
145
+ ' Dim Request As New WebRequest
146
+ '
147
+ ' Dim User As String
148
+ ' Dim Id As Long
149
+ ' User = "Tim"
150
+ ' Id = 123
151
+ '
152
+ ' ' OK: Use string concatenation for dynamic values
153
+ ' Request.Resource = User & "/messages/" & Id
154
+ '
155
+ ' ' BETTER: Use Url Segments for dynamic values
156
+ ' Request.Resource = "{User}/messages/{Id}"
157
+ ' Request.AddUrlSegment "User", User
158
+ ' Request.AddUrlSegment "Id", Id
159
+ '
160
+ ' Request.FormattedResource ' = "Tim/messages/123"
161
+ ' ```
162
+ '
163
+ ' @property UrlSegments
164
+ ' @type Dictionary
165
+ ''
166
+ Public UrlSegments As Dictionary
167
+
168
+ ''
169
+ ' _Note_ To add cookies, use [`AddCookie`](#/WebRequest/AddCookie).
170
+ '
171
+ ' `Collection` of cookies to include with request,
172
+ ' stored as `KeyValue` (`Dictionary: {Key: "...", Value: "..."}`).
173
+ '
174
+ ' @property Cookies
175
+ ' @type Collection
176
+ ''
177
+ Public Cookies As Collection
178
+
179
+ ''
180
+ ' User agent to use with request
181
+ '
182
+ ' @example
183
+ ' ```VB.net
184
+ ' Dim Request As New WebRequest
185
+ ' Request.UserAgent = "Mozilla/5.0"
186
+ '
187
+ ' ' -> (Header) User-Agent: Mozilla/5.0
188
+ ' ```
189
+ '
190
+ ' @property UserAgent
191
+ ' @type String
192
+ ' @default "VBA-Web v#.#.# (https://github.com/VBA-tools/VBA-Web)"
193
+ ''
194
+ Public UserAgent As String
195
+
196
+ ''
197
+ ' Set `RequestFormat`, `ResponseFormat`, and `Content-Type` and `Accept`
198
+ ' headers for the `WebRequest`
199
+ '
200
+ ' @example
201
+ ' ```VB.net
202
+ ' Dim Request As New WebRequest
203
+ ' Request.Format = WebFormat.Json
204
+ ' ' -> Request.RequestFormat = WebFormat.Json
205
+ ' ' Request.ResponseFormat = WebFormat.Json
206
+ ' ' (Header) Content-Type: application/json
207
+ ' ' (Header) Accept: application/json
208
+ ' ```
209
+ '
210
+ ' @property Format
211
+ ' @type WebFormat
212
+ ''
213
+ Public Property Get Format() As WebFormat
214
+ Format = RequestFormat
215
+ End Property
216
+ Public Property Let Format(Value As WebFormat)
217
+ Me.RequestFormat = Value
218
+ Me.ResponseFormat = Value
219
+ End Property
220
+
221
+ ''
222
+ ' Set the format to use for converting the response `Body` to string and for the `Content-Type` header
223
+ '
224
+ ' _Note_ If `WebFormat.Custom` is used, the [`CustomRequestFormat`](#/WebRequest/CustomRequestFormat) must be set.
225
+ '
226
+ ' @example
227
+ ' ```VB.net
228
+ ' Dim Request As New WebRequest
229
+ ' Request.Body = Array("A", "B", "C")
230
+ '
231
+ ' Request.RequestFormat = WebFormat.Json
232
+ '
233
+ ' ' -> (Header) Content-Type: application/json
234
+ ' ' -> Convert Body to JSON string
235
+ ' Request.Body ' = "["A","B","C"]"
236
+ ' ```
237
+ '
238
+ ' @property RequestFormat
239
+ ' @type WebFormat
240
+ ' @default WebFormat.Json
241
+ ''
242
+ Public Property Get RequestFormat() As WebFormat
243
+ RequestFormat = web_pRequestFormat
244
+ End Property
245
+ Public Property Let RequestFormat(Value As WebFormat)
246
+ If Value <> web_pRequestFormat Then
247
+ web_pRequestFormat = Value
248
+
249
+ ' Clear cached converted body
250
+ web_pConvertedBody = Empty
251
+ End If
252
+ End Property
253
+
254
+ ''
255
+ ' Set the format to use for converting the response `Content` to `Data` and for the `Accept` header
256
+ '
257
+ ' _Note_ If `WebFormat.Custom` is used, the [`CustomResponseFormat`](#/WebRequest/CustomResponseFormat) must be set.
258
+ '
259
+ ' @example
260
+ ' ```VB.net
261
+ ' Dim Request As New WebRequest
262
+ ' Request.ResponseFormat = WebFormat.Json
263
+ '
264
+ ' ' -> (Header) Accept: application/json
265
+ '
266
+ ' Dim Response As WebResponse
267
+ ' ' ... from Execute
268
+ ' Response.Content = "{""message"":""Howdy!""}"
269
+ '
270
+ ' ' -> Parse Content to JSON Dictionary
271
+ ' Debug.Print Response.Data("message") ' -> "Howdy!"
272
+ ' ```
273
+ '
274
+ ' @property ResponseFormat
275
+ ' @type WebFormat
276
+ ' @default WebFormat.Json
277
+ ''
278
+ Public Property Get ResponseFormat() As WebFormat
279
+ ResponseFormat = web_pResponseFormat
280
+ End Property
281
+ Public Property Let ResponseFormat(Value As WebFormat)
282
+ If Value <> web_pResponseFormat Then
283
+ web_pResponseFormat = Value
284
+
285
+ ' Clear cached converted body
286
+ web_pConvertedBody = Empty
287
+ End If
288
+ End Property
289
+
290
+ ''
291
+ ' Use converter registered with [`WebHelpers.RegisterConverter`](#/WebHelpers/RegisterConverter)
292
+ ' to convert `Body` to string and set `Content-Type` header.
293
+ '
294
+ ' (Automatically sets `RequestFormat` to `WebFormat.Custom`)
295
+ '
296
+ ' @example
297
+ ' ```VB.net
298
+ ' WebHelpers.RegisterConverter "csv", "text/csv", "Module.ConvertToCsv", "Module.ParseCsv"
299
+ '
300
+ ' Dim Request As New WebRequest
301
+ ' Request.CustomRequestFormat = "csv"
302
+ '
303
+ ' ' -> (Header) Content-Type: text/csv
304
+ ' ' -> Body converted to string with Module.ConvertToCsv
305
+ ' ```
306
+ '
307
+ ' @property CustomRequestFormat
308
+ ' @type String
309
+ ''
310
+ Public Property Get CustomRequestFormat() As String
311
+ CustomRequestFormat = web_pCustomRequestFormat
312
+ End Property
313
+ Public Property Let CustomRequestFormat(Value As String)
314
+ If Value <> web_pCustomRequestFormat Then
315
+ web_pCustomRequestFormat = Value
316
+
317
+ ' Clear cached converted body
318
+ web_pConvertedBody = Empty
319
+
320
+ If Value <> "" Then
321
+ web_pRequestFormat = WebFormat.Custom
322
+ End If
323
+ End If
324
+ End Property
325
+
326
+ ''
327
+ ' Use converter registered with [`WebHelpers.RegisterConverter`](#/WebHelpers/RegisterConverter)
328
+ ' to convert the response `Content` to `Data` and set `Accept` header.
329
+ '
330
+ ' (Automatically sets `ResponseFormat` to `WebFormat.Custom`)
331
+ '
332
+ ' @example
333
+ ' ```VB.net
334
+ ' WebHelpers.RegisterConverter "csv", "text/csv", "Module.ConvertToCsv", "Module.ParseCsv"
335
+ '
336
+ ' Dim Request As New WebRequest
337
+ ' Request.CustomResponseFormat = "csv"
338
+ '
339
+ ' ' -> (Header) Accept: text/csv
340
+ ' ' -> WebResponse Content converted Data with Module.ParseCsv
341
+ ' ```
342
+ '
343
+ ' @property CustomResponseFormat
344
+ ' @type String
345
+ ''
346
+ Public Property Get CustomResponseFormat() As String
347
+ CustomResponseFormat = web_pCustomResponseFormat
348
+ End Property
349
+ Public Property Let CustomResponseFormat(Value As String)
350
+ If Value <> web_pCustomResponseFormat Then
351
+ web_pCustomResponseFormat = Value
352
+
353
+ ' Clear cached converted body
354
+ web_pConvertedBody = Empty
355
+
356
+ If Value <> "" Then
357
+ ResponseFormat = WebFormat.Custom
358
+ End If
359
+ End If
360
+ End Property
361
+
362
+ ''
363
+ ' Set automatically from `RequestFormat` or `CustomRequestFormat`,
364
+ ' but can be overriden to set `Content-Type` header for request.
365
+ '
366
+ ' @example
367
+ ' ```VB.net
368
+ ' Dim Request As New WebRequest
369
+ ' Request.ContentType = "text/csv"
370
+ '
371
+ ' ' -> (Header) Content-Type: text/csv
372
+ ' ```
373
+ '
374
+ ' @property ContentType
375
+ ' @type String
376
+ ' @default Media-type of request format
377
+ ''
378
+ Public Property Get ContentType() As String
379
+ If web_pContentType <> "" Then
380
+ ContentType = web_pContentType
381
+ Else
382
+ ContentType = WebHelpers.FormatToMediaType(Me.RequestFormat, Me.CustomRequestFormat)
383
+ End If
384
+ End Property
385
+ Public Property Let ContentType(Value As String)
386
+ web_pContentType = Value
387
+ End Property
388
+
389
+ ''
390
+ ' Set automatically from `ResponseFormat` or `CustomResponseFormat`,
391
+ ' but can be overriden to set `Accept` header for request.
392
+ '
393
+ ' @example
394
+ ' ```VB.net
395
+ ' Dim Request As New WebRequest
396
+ ' Request.Accept = "text/csv"
397
+ '
398
+ ' ' -> (Header) Accept: text/csv
399
+ ' ```
400
+ '
401
+ ' @property Accept
402
+ ' @type String
403
+ ' @default Media-type of response format
404
+ ''
405
+ Public Property Get Accept() As String
406
+ If web_pAccept <> "" Then
407
+ Accept = web_pAccept
408
+ Else
409
+ Accept = WebHelpers.FormatToMediaType(Me.ResponseFormat, Me.CustomResponseFormat)
410
+ End If
411
+ End Property
412
+ Public Property Let Accept(Value As String)
413
+ web_pAccept = Value
414
+ End Property
415
+
416
+ ''
417
+ ' Set automatically by length of `Body`,
418
+ ' but can be overriden to set `Content-Length` header for request.
419
+ '
420
+ ' @example
421
+ ' ```VB.net
422
+ ' Dim Request As New WebRequest
423
+ ' Request.ContentLength = 200
424
+ '
425
+ ' ' -> (Header) Content-Length: 200
426
+ ' ```
427
+ '
428
+ ' @property ContentLength
429
+ ' @type Long
430
+ ' @default Length of `Body`
431
+ ''
432
+ Public Property Get ContentLength() As Long
433
+ If web_pContentLength >= 0 Then
434
+ ContentLength = web_pContentLength
435
+ Else
436
+ ContentLength = Len(Me.Body)
437
+ End If
438
+ End Property
439
+ Public Property Let ContentLength(Value As Long)
440
+ web_pContentLength = Value
441
+ End Property
442
+
443
+ ''
444
+ ' - Get: Body value converted to string using `RequestFormat` or `CustomRequestFormat`
445
+ ' - Let: Use `String` or `Array` for Body
446
+ ' - Set: Use `Collection`, `Dictionary`, or `Object` for Body
447
+ '
448
+ ' @example
449
+ ' ```VB.net
450
+ ' Dim Request As New WebRequest
451
+ ' Request.RequestFormat = WebFormat.Json
452
+ '
453
+ ' ' Let: String|Array
454
+ ' Request.Body = "text"
455
+ ' Debug.Print Request.Body ' -> "text"
456
+ '
457
+ ' Request.Body = Array("A", "B", "C")
458
+ ' Debug.Print Request.Body ' -> "["A","B","C"]"
459
+ '
460
+ ' ' Set: Collection|Dictionary|Object
461
+ ' Dim Body As Object
462
+ ' Set Body = New Collection
463
+ ' Body.Add "Howdy!"
464
+ ' Set Request.Body = Body
465
+ ' Debug.Print Request.Body ' -> "["Howdy!"]"
466
+ '
467
+ ' Set Body = New Dictionary
468
+ ' Body.Add "a", 123
469
+ ' Body.Add "b", 456
470
+ ' Set Request.Body = Body
471
+ ' Debug.Print Request.Body ' -> "{"a":123,"b":456}"
472
+ ' ```
473
+ '
474
+ ' @property Body
475
+ ' @type String|Array|Collection|Dictionary|Variant
476
+ ''
477
+ Public Property Get Body() As Variant
478
+ If Not VBA.IsEmpty(web_pBody) Then
479
+ If VBA.VarType(web_pBody) = vbString Then
480
+ Body = web_pBody
481
+ ElseIf IsEmpty(web_pConvertedBody) Then
482
+ ' Convert body and cache
483
+ Body = WebHelpers.ConvertToFormat(web_pBody, Me.RequestFormat, Me.CustomRequestFormat)
484
+ web_pConvertedBody = Body
485
+ Else
486
+ Body = web_pConvertedBody
487
+ End If
488
+ End If
489
+ End Property
490
+ Public Property Let Body(Value As Variant)
491
+ web_pConvertedBody = Empty
492
+ web_pBody = Value
493
+ End Property
494
+ Public Property Set Body(Value As Variant)
495
+ web_pConvertedBody = Empty
496
+ Set web_pBody = Value
497
+ End Property
498
+
499
+ ''
500
+ ' Get `Resource` with Url Segments replaced and Querystring added.
501
+ '
502
+ ' @example
503
+ ' ```VB.net
504
+ ' Dim Request As New WebRequest
505
+ ' Request.Resource = "examples/{Id}"
506
+ ' Request.AddUrlSegment "Id", 123
507
+ ' Request.AddQuerystringParam "message", "Hello"
508
+ '
509
+ ' Debug.Print Request.FormattedResource ' -> "examples/123?message=Hello"
510
+ ' ```
511
+ '
512
+ ' @property FormattedResource
513
+ ' @type String
514
+ ''
515
+ Public Property Get FormattedResource() As String
516
+ Dim web_Segment As Variant
517
+ Dim web_Encoding As UrlEncodingMode
518
+
519
+ FormattedResource = Me.Resource
520
+
521
+ ' Replace url segments
522
+ For Each web_Segment In Me.UrlSegments.Keys
523
+ FormattedResource = VBA.Replace(FormattedResource, "{" & web_Segment & "}", WebHelpers.UrlEncode(Me.UrlSegments(web_Segment)))
524
+ Next web_Segment
525
+
526
+ ' Add querystring
527
+ If Me.QuerystringParams.Count > 0 Then
528
+ If VBA.InStr(FormattedResource, "?") <= 0 Then
529
+ FormattedResource = FormattedResource & "?"
530
+ Else
531
+ FormattedResource = FormattedResource & "&"
532
+ End If
533
+
534
+ ' For querystrings, W3C defines form-urlencoded as the required encoding,
535
+ ' but the treatment of space -> "+" (rather than "%20") can cause issues
536
+ '
537
+ ' If the request format is explicitly form-urlencoded, use FormUrlEncoding (space -> "+")
538
+ ' otherwise, use subset of RFC 3986 and form-urlencoded that should work for both cases (space -> "%20")
539
+ If Me.RequestFormat = WebFormat.FormUrlEncoded Then
540
+ web_Encoding = UrlEncodingMode.FormUrlEncoding
541
+ Else
542
+ web_Encoding = UrlEncodingMode.QueryUrlEncoding
543
+ End If
544
+ FormattedResource = FormattedResource & WebHelpers.ConvertToUrlEncoded(Me.QuerystringParams, EncodingMode:=web_Encoding)
545
+ End If
546
+ End Property
547
+
548
+ ''
549
+ ' @internal
550
+ ' @property Id
551
+ ' @type String
552
+ ''
553
+ Public Property Get Id() As String
554
+ If web_pId = "" Then: web_pId = WebHelpers.CreateNonce
555
+ Id = web_pId
556
+ End Property
557
+
558
+ ' ============================================= '
559
+ ' Public Methods
560
+ ' ============================================= '
561
+
562
+ ''
563
+ ' Add header to be sent with request.
564
+ '
565
+ ' @example
566
+ ' ```VB.net
567
+ ' Dim Request As New WebRequest
568
+ ' Request.AddHeader "Authentication", "Bearer ..."
569
+ '
570
+ ' ' -> (Header) Authorization: Bearer ...
571
+ ' ```
572
+ '
573
+ ' @method AddHeader
574
+ ' @param {String} Key
575
+ ' @param {Variant} Value
576
+ ''
577
+ Public Sub AddHeader(Key As String, Value As Variant)
578
+ Me.headers.Add WebHelpers.CreateKeyValue(Key, Value)
579
+ End Sub
580
+
581
+ ''
582
+ ' Add/replace header to be sent with request.
583
+ ' `SetHeader` should be used for headers that can only be included once with a request
584
+ ' (e.g. Authorization, Content-Type, etc.).
585
+ '
586
+ ' @example
587
+ ' ```VB.net
588
+ ' Dim Request As New WebRequest
589
+ ' Request.AddHeader "Authorization", "A..."
590
+ ' Request.AddHeader "Authorization", "B..."
591
+ '
592
+ ' ' -> Headers:
593
+ ' ' Authorization: A...
594
+ ' ' Authorization: B...
595
+ '
596
+ ' Request.SetHeader "Authorization", "C..."
597
+ '
598
+ ' ' -> Headers:
599
+ ' ' Authorization: C...
600
+ ' ```
601
+ '
602
+ ' @method SetHeader
603
+ ' @param {String} Key
604
+ ' @param {Variant} Value
605
+ ''
606
+ Public Sub SetHeader(Key As String, Value As Variant)
607
+ WebHelpers.AddOrReplaceInKeyValues Me.headers, Key, Value
608
+ End Sub
609
+
610
+ ''
611
+ ' Url Segments are used to easily add dynamic values to `Resource`.
612
+ ' Create a Url Segement in `Resource` with curly brackets and then
613
+ ' replace with dynamic value with `AddUrlSegment`.
614
+ '
615
+ ' @example
616
+ ' ```VB.net
617
+ ' Dim Request As New WebRequest
618
+ ' Dim User As String
619
+ ' Dim Id As Long
620
+ '
621
+ ' User = "Tim"
622
+ ' Id = 123
623
+ '
624
+ ' ' OK: Use string concatenation for dynamic values
625
+ ' Request.Resource = User & "/messages/" & Id
626
+ '
627
+ ' ' BETTER: Use Url Segments for dynamic values
628
+ ' Request.Resource = "{User}/messages/{Id}"
629
+ ' Request.AddUrlSegment "User", User
630
+ ' Request.AddUrlSegment "Id", Id
631
+ '
632
+ ' Debug.Print Request.FormattedResource ' > "Tim/messages/123"
633
+ ' ```
634
+ '
635
+ ' @method AddUrlSegment
636
+ ' @param {String} Key
637
+ ' @param {String} Value
638
+ ''
639
+ Public Sub AddUrlSegment(Segment As String, Value As Variant)
640
+ Me.UrlSegments.Item(Segment) = Value
641
+ End Sub
642
+
643
+ ''
644
+ ' Add querysting parameter to be used in `FormattedResource` for request.
645
+ '
646
+ ' @example
647
+ ' ```VB.net
648
+ ' Dim Request As New WebRequest
649
+ ' Request.Resource = "messages"
650
+ ' Request.AddQuerystringParam "from", "Tim"
651
+ '
652
+ ' Request.FormattedResource ' = "messages?from=Tim"
653
+ ' ```
654
+ '
655
+ ' @method AddQuerystringParam
656
+ ' @param {String} Key
657
+ ' @param {Variant} Value
658
+ ''
659
+ Public Sub AddQuerystringParam(Key As String, Value As Variant)
660
+ Me.QuerystringParams.Add WebHelpers.CreateKeyValue(Key, Value)
661
+ End Sub
662
+
663
+ ''
664
+ ' Add cookie to be sent with request.
665
+ '
666
+ ' @example
667
+ ' ```VB.net
668
+ ' Dim Request As New WebRequest
669
+ ' Request.AddCookie "a", "abc"
670
+ ' Request.AddCookie "b", 123
671
+ '
672
+ ' ' -> (Header) Cookie: a=abc; b=123;
673
+ ' ```
674
+ '
675
+ ' @method AddCookie
676
+ ' @param {String} Key
677
+ ' @param {Variant} Value
678
+ ''
679
+ Public Sub AddCookie(Key As String, Value As Variant)
680
+ Me.Cookies.Add WebHelpers.CreateKeyValue( _
681
+ web_EncodeCookieName(Key), _
682
+ WebHelpers.UrlEncode(Value, EncodingMode:=UrlEncodingMode.CookieUrlEncoding) _
683
+ )
684
+ End Sub
685
+
686
+ ''
687
+ ' Add `Key-Value` to `Body`.
688
+ ' `Body` must be a `Dictionary` (if it's an `Array` or `Collection` an error is thrown)
689
+ '
690
+ ' @example
691
+ ' ```VB.net
692
+ ' Dim Request As New WebRequest
693
+ ' Request.Format = WebFormat.Json
694
+ '
695
+ ' Request.AddBodyParameter "a", 123
696
+ ' Debug.Print Request.Body ' -> "{"a":123}"
697
+ '
698
+ ' ' Can add parameters to existing Dictionary
699
+ ' Dim Body As New Dictionary
700
+ ' Body.Add "a", 123
701
+ '
702
+ ' Set Request.Body = Body
703
+ ' Request.AddBodyParameter "b", 456
704
+ '
705
+ ' Debug.Print Request.Body ' -> "{"a":123,"b":456}"
706
+ ' ```
707
+ '
708
+ ' @method AddBodyParameter
709
+ ' @param {Variant} Key
710
+ ' @param {Variant} Value
711
+ ' @throws 11020 / 80042b0c / -2147210484 - Cannot add body parameter to non-Dictionary
712
+ ''
713
+ Public Sub AddBodyParameter(Key As Variant, Value As Variant)
714
+ If VBA.IsEmpty(web_pBody) Then
715
+ Set web_pBody = New Dictionary
716
+ ElseIf Not TypeOf web_pBody Is Dictionary Then
717
+ Dim web_ErrorDescription As String
718
+ web_ErrorDescription = "Cannot add body parameter to non-Dictionary Body (existing Body must be of type Dictionary)"
719
+
720
+ WebHelpers.LogError web_ErrorDescription, "WebRequest.AddBodyParameter", 11020 + vbObjectError
721
+ Err.Raise 11020 + vbObjectError, "WebRequest.AddBodyParameter", web_ErrorDescription
722
+ End If
723
+
724
+ If VBA.IsObject(Value) Then
725
+ Set web_pBody(Key) = Value
726
+ Else
727
+ web_pBody(Key) = Value
728
+ End If
729
+
730
+ ' Clear cached converted body
731
+ web_pConvertedBody = Empty
732
+ End Sub
733
+
734
+ ''
735
+ ' Prepare request for execution
736
+ '
737
+ ' @internal
738
+ ' @method Prepare
739
+ ''
740
+ Public Sub Prepare()
741
+ ' Add/replace general headers for request
742
+ SetHeader "User-Agent", Me.UserAgent
743
+ SetHeader "Accept", Me.Accept
744
+ If Me.Method <> WebMethod.HttpGet Then
745
+ SetHeader "Content-Type", Me.ContentType
746
+ SetHeader "Content-Length", VBA.CStr(Me.ContentLength)
747
+ End If
748
+ End Sub
749
+
750
+ ''
751
+ ' Clone request
752
+ '
753
+ ' @internal
754
+ ' @method Clone
755
+ ' @return {WebRequest}
756
+ ''
757
+ Public Function Clone() As WebRequest
758
+ Set Clone = New WebRequest
759
+
760
+ ' Note: Clone underlying for properties with default values
761
+ Clone.Resource = Me.Resource
762
+ Clone.Method = Me.Method
763
+ Clone.UserAgent = Me.UserAgent
764
+ Clone.Accept = web_pAccept
765
+ Clone.ContentType = web_pContentType
766
+ Clone.ContentLength = web_pContentLength
767
+ Clone.RequestFormat = Me.RequestFormat
768
+ Clone.ResponseFormat = Me.ResponseFormat
769
+ Clone.CustomRequestFormat = Me.CustomRequestFormat
770
+ Clone.CustomResponseFormat = Me.CustomResponseFormat
771
+
772
+ Set Clone.headers = WebHelpers.CloneCollection(Me.headers)
773
+ Set Clone.QuerystringParams = WebHelpers.CloneCollection(Me.QuerystringParams)
774
+ Set Clone.UrlSegments = WebHelpers.CloneDictionary(Me.UrlSegments)
775
+ Set Clone.Cookies = WebHelpers.CloneCollection(Me.Cookies)
776
+
777
+ If VBA.IsObject(web_pBody) Then
778
+ Set Clone.Body = web_pBody
779
+ Else
780
+ Clone.Body = web_pBody
781
+ End If
782
+ End Function
783
+
784
+ ''
785
+ ' Create WebRequest from options
786
+ '
787
+ ' @method CreateFromOptions
788
+ ' @param {Dictionary} Options
789
+ ' @param {Collection} [Options.Headers] Collection of `KeyValue`
790
+ ' @param {Collection} [Options.Cookies] Collection of `KeyValue`
791
+ ' @param {Collection} [Options.QuerystringParams] Collection of `KeyValue`
792
+ ' @param {Dictionary} [Options.UrlSegments]
793
+ ''
794
+ Public Sub CreateFromOptions(Options As Dictionary)
795
+ If Not Options Is Nothing Then
796
+ If Options.Exists("Headers") Then
797
+ Set Me.headers = Options("Headers")
798
+ End If
799
+ If Options.Exists("Cookies") Then
800
+ Set Me.Cookies = Options("Cookies")
801
+ End If
802
+ If Options.Exists("QuerystringParams") Then
803
+ Set Me.QuerystringParams = Options("QuerystringParams")
804
+ End If
805
+ If Options.Exists("UrlSegments") Then
806
+ Set Me.UrlSegments = Options("UrlSegments")
807
+ End If
808
+ End If
809
+ End Sub
810
+
811
+ ' ============================================= '
812
+ ' Private Functions
813
+ ' ============================================= '
814
+
815
+ ' Encode cookie name
816
+ '
817
+ ' References:
818
+ ' - RFC 6265 https://tools.ietf.org/html/rfc6265
819
+ Private Function web_EncodeCookieName(web_CookieName As Variant) As String
820
+ Dim web_CookieVal As String
821
+ Dim web_StringLen As Long
822
+
823
+ web_CookieVal = VBA.CStr(web_CookieName)
824
+ web_StringLen = VBA.Len(web_CookieVal)
825
+
826
+ If web_StringLen > 0 Then
827
+ Dim web_Result() As String
828
+ Dim web_i As Long
829
+ Dim web_CharCode As Integer
830
+ Dim web_Char As String
831
+ ReDim web_Result(web_StringLen)
832
+
833
+ ' ALPHA / DIGIT / "!" / "#" / "$" / "&" / "'" / "*" / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
834
+ ' Note: "%" is allowed in spec, but is currently excluded due to parsing issues
835
+
836
+ ' Loop through string characters
837
+ For web_i = 1 To web_StringLen
838
+ ' Get character and ascii code
839
+ web_Char = VBA.Mid$(web_CookieVal, web_i, 1)
840
+ web_CharCode = VBA.Asc(web_Char)
841
+
842
+ Select Case web_CharCode
843
+ Case 65 To 90, 97 To 122
844
+ ' ALPHA
845
+ web_Result(web_i) = web_Char
846
+ Case 48 To 57
847
+ ' DIGIT
848
+ web_Result(web_i) = web_Char
849
+ Case 33, 35, 36, 38, 39, 42, 43, 45, 46, 94, 95, 96, 124, 126
850
+ ' "!" / "#" / "$" / "&" / "'" / "*" / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
851
+ web_Result(web_i) = web_Char
852
+
853
+ Case 0 To 15
854
+ web_Result(web_i) = "%0" & VBA.Hex(web_CharCode)
855
+ Case Else
856
+ web_Result(web_i) = "%" & VBA.Hex(web_CharCode)
857
+ End Select
858
+ Next web_i
859
+
860
+ web_EncodeCookieName = VBA.Join$(web_Result, "")
861
+ End If
862
+ End Function
863
+
864
+ Private Sub Class_Initialize()
865
+ ' Set default values
866
+ Me.RequestFormat = WebFormat.Json
867
+ Me.ResponseFormat = WebFormat.Json
868
+ Me.UserAgent = WebUserAgent
869
+
870
+ Set Me.headers = New Collection
871
+ Set Me.QuerystringParams = New Collection
872
+ Set Me.UrlSegments = New Dictionary
873
+ Set Me.Cookies = New Collection
874
+ Me.ContentLength = -1
875
+ End Sub