@creator.co/wapi 1.7.1-alpha4 → 1.7.2-alpha1

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 (151) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc.cjs +62 -0
  3. package/.github/workflows/npmpublish.yml +11 -0
  4. package/.github/workflows/prs.yml +13 -0
  5. package/dist/index.d.ts +14 -14
  6. package/dist/index.js +14 -14
  7. package/dist/index.js.map +1 -1
  8. package/dist/package-lock.json +2676 -454
  9. package/dist/package.json +2 -1
  10. package/dist/src/API/Request.d.ts +1 -1
  11. package/dist/src/API/Request.js +1 -1
  12. package/dist/src/API/Request.js.map +1 -1
  13. package/dist/src/API/Response.d.ts +1 -1
  14. package/dist/src/API/Response.js +1 -1
  15. package/dist/src/API/Response.js.map +1 -1
  16. package/dist/src/BaseEvent/EventProcessor.d.ts +2 -2
  17. package/dist/src/BaseEvent/EventProcessor.js +3 -3
  18. package/dist/src/BaseEvent/EventProcessor.js.map +1 -1
  19. package/dist/src/BaseEvent/Process.d.ts +3 -3
  20. package/dist/src/BaseEvent/Process.js +2 -2
  21. package/dist/src/BaseEvent/Process.js.map +1 -1
  22. package/dist/src/BaseEvent/Transaction.d.ts +5 -5
  23. package/dist/src/BaseEvent/Transaction.js +6 -6
  24. package/dist/src/BaseEvent/Transaction.js.map +1 -1
  25. package/dist/src/Cache/Redis.d.ts +1 -1
  26. package/dist/src/Cache/Redis.js +1 -1
  27. package/dist/src/Cache/Redis.js.map +1 -1
  28. package/dist/src/Cache/types.d.ts +1 -1
  29. package/dist/src/Config/Configuration.js +1 -1
  30. package/dist/src/Config/Configuration.js.map +1 -1
  31. package/dist/src/Database/Database.d.ts +2 -2
  32. package/dist/src/Database/DatabaseManager.d.ts +4 -4
  33. package/dist/src/Database/DatabaseManager.js +3 -3
  34. package/dist/src/Database/DatabaseManager.js.map +1 -1
  35. package/dist/src/Database/DatabaseTransaction.d.ts +1 -1
  36. package/dist/src/Database/index.d.ts +10 -10
  37. package/dist/src/Database/index.js +6 -6
  38. package/dist/src/Database/index.js.map +1 -1
  39. package/dist/src/Database/integrations/knex/KnexDatabase.d.ts +3 -3
  40. package/dist/src/Database/integrations/knex/KnexDatabase.js +2 -2
  41. package/dist/src/Database/integrations/knex/KnexDatabase.js.map +1 -1
  42. package/dist/src/Database/integrations/knex/KnexTransaction.d.ts +3 -3
  43. package/dist/src/Database/integrations/knex/KnexTransaction.js +1 -1
  44. package/dist/src/Database/integrations/knex/KnexTransaction.js.map +1 -1
  45. package/dist/src/Database/integrations/kysely/KyselyDatabase.d.ts +3 -3
  46. package/dist/src/Database/integrations/kysely/KyselyDatabase.js +2 -2
  47. package/dist/src/Database/integrations/kysely/KyselyDatabase.js.map +1 -1
  48. package/dist/src/Database/integrations/kysely/KyselyTransaction.d.ts +3 -3
  49. package/dist/src/Database/integrations/kysely/KyselyTransaction.js +1 -1
  50. package/dist/src/Database/integrations/kysely/KyselyTransaction.js.map +1 -1
  51. package/dist/src/Database/integrations/pgsql/PostgresDatabase.d.ts +3 -3
  52. package/dist/src/Database/integrations/pgsql/PostgresDatabase.js +2 -2
  53. package/dist/src/Database/integrations/pgsql/PostgresDatabase.js.map +1 -1
  54. package/dist/src/Database/integrations/pgsql/PostgresTransaction.d.ts +3 -3
  55. package/dist/src/Database/integrations/pgsql/PostgresTransaction.js +1 -1
  56. package/dist/src/Database/integrations/pgsql/PostgresTransaction.js.map +1 -1
  57. package/dist/src/Database/types.d.ts +5 -5
  58. package/dist/src/Globals.js +1 -1
  59. package/dist/src/Globals.js.map +1 -1
  60. package/dist/src/Logger/Logger.js +1 -1
  61. package/dist/src/Logger/Logger.js.map +1 -1
  62. package/dist/src/Server/RouteResolver.d.ts +2 -2
  63. package/dist/src/Server/Router.d.ts +3 -3
  64. package/dist/src/Server/Router.js +3 -3
  65. package/dist/src/Server/Router.js.map +1 -1
  66. package/dist/src/Server/lib/ContainerServer.d.ts +3 -3
  67. package/dist/src/Server/lib/ContainerServer.js +2 -2
  68. package/dist/src/Server/lib/ContainerServer.js.map +1 -1
  69. package/dist/src/Server/lib/Server.d.ts +2 -2
  70. package/dist/src/Server/lib/Server.js +4 -4
  71. package/dist/src/Server/lib/Server.js.map +1 -1
  72. package/dist/src/Server/lib/container/GenericHandler.d.ts +1 -1
  73. package/dist/src/Server/lib/container/GenericHandler.js +3 -3
  74. package/dist/src/Server/lib/container/GenericHandler.js.map +1 -1
  75. package/dist/src/Server/lib/container/GenericHandlerEvent.d.ts +1 -1
  76. package/dist/src/Server/lib/container/GenericHandlerEvent.js +2 -2
  77. package/dist/src/Server/lib/container/GenericHandlerEvent.js.map +1 -1
  78. package/dist/src/Server/lib/container/Proxy.d.ts +2 -2
  79. package/dist/src/Server/lib/container/Proxy.js +4 -4
  80. package/dist/src/Server/lib/container/Proxy.js.map +1 -1
  81. package/dist/src/Validation/Validator.d.ts +1 -1
  82. package/dist/src/Validation/Validator.js +2 -2
  83. package/dist/src/Validation/Validator.js.map +1 -1
  84. package/index.ts +14 -14
  85. package/jest.config.ts +37 -0
  86. package/jest.smoke.config.ts +34 -0
  87. package/package.json +2 -1
  88. package/src/API/Request.ts +2 -2
  89. package/src/API/Response.ts +2 -2
  90. package/src/BaseEvent/EventProcessor.ts +3 -3
  91. package/src/BaseEvent/Process.ts +3 -3
  92. package/src/BaseEvent/Transaction.ts +8 -8
  93. package/src/Cache/Redis.ts +2 -2
  94. package/src/Cache/types.ts +1 -1
  95. package/src/Config/Configuration.ts +1 -1
  96. package/src/Database/Database.ts +2 -2
  97. package/src/Database/DatabaseManager.ts +4 -4
  98. package/src/Database/DatabaseTransaction.ts +1 -1
  99. package/src/Database/index.ts +10 -10
  100. package/src/Database/integrations/knex/KnexDatabase.ts +3 -3
  101. package/src/Database/integrations/knex/KnexTransaction.ts +3 -3
  102. package/src/Database/integrations/kysely/KyselyDatabase.ts +3 -3
  103. package/src/Database/integrations/kysely/KyselyTransaction.ts +3 -3
  104. package/src/Database/integrations/pgsql/PostgresDatabase.ts +3 -3
  105. package/src/Database/integrations/pgsql/PostgresTransaction.ts +3 -3
  106. package/src/Database/types.ts +5 -5
  107. package/src/Globals.ts +1 -1
  108. package/src/Logger/Logger.ts +1 -1
  109. package/src/Server/RouteResolver.ts +2 -2
  110. package/src/Server/Router.ts +6 -6
  111. package/src/Server/lib/ContainerServer.ts +3 -3
  112. package/src/Server/lib/Server.ts +6 -6
  113. package/src/Server/lib/container/GenericHandler.ts +4 -4
  114. package/src/Server/lib/container/GenericHandlerEvent.ts +3 -3
  115. package/src/Server/lib/container/Proxy.ts +6 -6
  116. package/src/Validation/Validator.ts +2 -2
  117. package/tests/API/Request.test.ts +273 -0
  118. package/tests/API/Response.test.ts +367 -0
  119. package/tests/API/Utils.test.ts +167 -0
  120. package/tests/BaseEvent/EventProcessor.test.ts +261 -0
  121. package/tests/BaseEvent/Process.test.ts +49 -0
  122. package/tests/BaseEvent/Transaction.test.ts +408 -0
  123. package/tests/Cache/Redis-client.test.ts +90 -0
  124. package/tests/Cache/Redis-cluster.test.ts +100 -0
  125. package/tests/Config/Config.test.ts +205 -0
  126. package/tests/Config/EnvironmentVar.test.ts +250 -0
  127. package/tests/Crypto/Crypto.test.ts +88 -0
  128. package/tests/Crypto/JWT.test.ts +92 -0
  129. package/tests/Database/DatabaseManager.test.ts +71 -0
  130. package/tests/Database/integrations/knex/KnexDatabase.test.ts +76 -0
  131. package/tests/Database/integrations/knex/KnexTransaction.test.ts +149 -0
  132. package/tests/Database/integrations/kysely/KyselyDatabase.test.ts +113 -0
  133. package/tests/Database/integrations/kysely/KyselyTransaction.test.ts +119 -0
  134. package/tests/Database/integrations/pg/PostgresDatabase.test.ts +76 -0
  135. package/tests/Database/integrations/pg/PostgresTransaction.test.ts +118 -0
  136. package/tests/Logger/Logger.test.ts +219 -0
  137. package/tests/Mailer/Mailer.test.ts +59 -0
  138. package/tests/Publisher/Publisher.test.ts +94 -0
  139. package/tests/Server/RouteResolver.test.ts +102 -0
  140. package/tests/Server/Router.test.ts +39 -0
  141. package/tests/Server/lib/ContainerServer.test.ts +531 -0
  142. package/tests/Server/lib/Server.test.ts +12 -0
  143. package/tests/Server/lib/container/GenericHandler.test.ts +131 -0
  144. package/tests/Server/lib/container/GenericHandlerEvent.test.ts +103 -0
  145. package/tests/Server/lib/container/HealthHandler.test.ts +30 -0
  146. package/tests/Server/lib/container/Proxy.test.ts +268 -0
  147. package/tests/Server/lib/container/Utils.test.ts +47 -0
  148. package/tests/Test.utils.ts +74 -0
  149. package/tests/Validation/Validator.test.ts +76 -0
  150. package/tsconfig.json +26 -0
  151. package/tsconfig.smoke.json +26 -0
@@ -0,0 +1,367 @@
1
+ import { jest } from '@jest/globals'
2
+ import { APIGatewayEvent, Context } from 'aws-lambda'
3
+ import { expect as c_expect } from 'chai'
4
+
5
+ import Response from '../../src/API/Response.js'
6
+ import Transaction from '../../src/BaseEvent/Transaction.js'
7
+ import Globals from '../../src/Globals.js'
8
+ import { observableTransaction, defaultHeaders } from '../Test.utils.js'
9
+
10
+ async function testResponse(r: Response<any>, body: any, optCode?: number, optHeaders?: any) {
11
+ const t = observableTransaction()
12
+ const context = t['context']
13
+ const buildR = await r.build(context, t, false)
14
+ c_expect(buildR).to.be.undefined
15
+ expect(t.responseProxy).toBeCalledTimes(1)
16
+ expect(context.fail).not.toBeCalled()
17
+ expect(context.done).not.toBeCalled()
18
+ expect(context.succeed).toHaveBeenCalledWith({
19
+ statusCode: optCode || 400,
20
+ headers: {
21
+ ...defaultHeaders,
22
+ ...(optHeaders || {}),
23
+ },
24
+ ...(body
25
+ ? {
26
+ body: JSON.stringify({
27
+ ...body,
28
+ transactionID: 'unknown',
29
+ }),
30
+ }
31
+ : {}),
32
+ })
33
+ }
34
+
35
+ describe('Response basics', () => {
36
+ test('Null body', () => {
37
+ const r = new Response<null>(200, null)
38
+ c_expect(r.getCode()).to.be.equals(200)
39
+ c_expect(r.getBody()).to.be.null
40
+ })
41
+
42
+ test('String body', () => {
43
+ const r = new Response<string>(200, 'abc')
44
+ c_expect(r.getCode()).to.be.equals(200)
45
+ c_expect(r.getBody()).to.be.equals('abc')
46
+ })
47
+
48
+ test('Generic body', () => {
49
+ const r = new Response<any>(200, { name: 'abc' })
50
+ r.appendIntoBody('name2', '123')
51
+ c_expect(r.getCode()).to.be.equals(200)
52
+ c_expect(r.getBody().name).to.be.equals('abc')
53
+ c_expect(r.getBody().name2).to.be.equals('123')
54
+ })
55
+
56
+ test('Append/validate header', () => {
57
+ const r = new Response<any>(200, {})
58
+ r.appendHeader('name2', '123')
59
+ c_expect(r['headers']['name2']).to.be.equals('123')
60
+ })
61
+ })
62
+
63
+ describe('Response build', () => {
64
+ test('Succeeds to transaction context', async () => {
65
+ const b = { name: 'abc' }
66
+ const r = new Response<any>(200, b)
67
+ r.appendHeader('abc', '123')
68
+ // do not use default, so we dont use proxy response for once
69
+ const t = new Transaction(
70
+ <APIGatewayEvent>(<unknown>{}),
71
+ <Context>(<unknown>{
72
+ done: jest.fn(),
73
+ fail: jest.fn(),
74
+ succeed: jest.fn(),
75
+ })
76
+ )
77
+ const context = t['context']
78
+ const buildR = await r.build(context, t, false)
79
+ c_expect(buildR).to.be.undefined
80
+ expect(context.fail).not.toBeCalled()
81
+ expect(context.done).not.toBeCalled()
82
+ expect(context.succeed).toHaveBeenCalledWith({
83
+ statusCode: 200,
84
+ headers: {
85
+ ...defaultHeaders,
86
+ abc: '123',
87
+ },
88
+ body: JSON.stringify({
89
+ ...b,
90
+ transactionID: 'unknown',
91
+ }),
92
+ })
93
+ })
94
+
95
+ test('Succeeds with no context call', async () => {
96
+ const b = { name: 'abc' }
97
+ const r = new Response<any>(200, b)
98
+ const t = observableTransaction()
99
+ const context = t['context']
100
+ const buildR = await r.build(context, t, true)
101
+ c_expect(buildR).to.be.undefined
102
+ expect(context.fail).not.toBeCalled()
103
+ expect(context.done).not.toBeCalled()
104
+ expect(context.succeed).not.toBeCalled()
105
+ })
106
+
107
+ test('Succeeds to transaction context as RAW', async () => {
108
+ const b = { name: 'abc' }
109
+ const r = new Response<any>(200, b, {
110
+ rawBody: true,
111
+ })
112
+ const t = observableTransaction()
113
+ const context = t['context']
114
+ const buildR = await r.build(context, t, false)
115
+ c_expect(buildR).to.be.undefined
116
+ expect(context.fail).not.toBeCalled()
117
+ expect(context.done).not.toBeCalled()
118
+ expect(context.succeed).toHaveBeenCalledWith({
119
+ ...b,
120
+ transactionID: 'unknown',
121
+ })
122
+ })
123
+
124
+ test('Succeeds to transaction piping', async () => {
125
+ const b = { name: 'abc' }
126
+ const r = new Response<any>(200, b, {
127
+ shouldStream: true,
128
+ })
129
+ const t = observableTransaction()
130
+ const context = t['context']
131
+ const buildR = await r.build(context, t, false)
132
+ await r.build(context, t, false) //pipe twice, should not affect
133
+ c_expect(buildR).to.be.undefined
134
+ expect(context.fail).not.toBeCalled()
135
+ expect(context.done).not.toBeCalled()
136
+ expect(context.succeed).toHaveBeenCalledTimes(1)
137
+ expect(context.succeed).toHaveBeenCalledWith({
138
+ statusCode: 200,
139
+ headers: {
140
+ ...defaultHeaders,
141
+ },
142
+ body: {
143
+ ...b,
144
+ },
145
+ })
146
+ })
147
+
148
+ test('Failure to transaction context as RAW', async () => {
149
+ const b = { name: 'abc' }
150
+ const r = new Response<any>(400, b, {
151
+ rawBody: true,
152
+ })
153
+ const t = observableTransaction()
154
+ const context = t['context']
155
+ const buildR = await r.build(context, t, false)
156
+ c_expect(buildR).to.be.undefined
157
+ expect(context.done).not.toBeCalled()
158
+ expect(context.succeed).not.toBeCalled()
159
+ expect(context.fail).toHaveBeenCalledTimes(1)
160
+ })
161
+
162
+ test('Failure exception to transaction context as RAW', async () => {
163
+ const b = { name: 'abc' }
164
+ const r = new Response<any>(400, b, {
165
+ rawBody: true,
166
+ throwOnErrors: true,
167
+ })
168
+ const t = observableTransaction()
169
+ const context = t['context']
170
+ let buildR: any = null,
171
+ exception = null
172
+ try {
173
+ buildR = await r.build(context, t, false)
174
+ } catch (e) {
175
+ exception = e
176
+ }
177
+ c_expect(buildR).to.be.null
178
+ c_expect(exception).to.not.be.null
179
+ expect(context.done).not.toBeCalled()
180
+ expect(context.succeed).not.toBeCalled()
181
+ expect(context.fail).not.toBeCalled()
182
+ })
183
+
184
+ test('Failure exception to transaction context as RAW and null body', async () => {
185
+ const b = null
186
+ const r = new Response<any>(400, b, {
187
+ rawBody: true,
188
+ throwOnErrors: true,
189
+ })
190
+ const t = observableTransaction()
191
+ const context = t['context']
192
+ let buildR: any = null,
193
+ exception = null
194
+ try {
195
+ buildR = await r.build(context, t, false)
196
+ } catch (e) {
197
+ exception = e
198
+ }
199
+ c_expect(buildR).to.be.null
200
+ c_expect(exception).to.not.be.null
201
+ expect(context.done).not.toBeCalled()
202
+ expect(context.succeed).not.toBeCalled()
203
+ expect(context.fail).not.toBeCalled()
204
+ })
205
+
206
+ test('Failure exception to transaction context as RAW and custom ero', async () => {
207
+ const b = { message: 'abc', error: 'error 123' }
208
+ const r = new Response<any>(400, b, {
209
+ rawBody: true,
210
+ throwOnErrors: true,
211
+ })
212
+ const t = observableTransaction()
213
+ const context = t['context']
214
+ let buildR: any = null,
215
+ exception = null
216
+ try {
217
+ buildR = await r.build(context, t, false)
218
+ } catch (e) {
219
+ exception = e
220
+ }
221
+ c_expect(buildR).to.be.null
222
+ c_expect(exception).to.not.be.null
223
+ expect(context.done).not.toBeCalled()
224
+ expect(context.succeed).not.toBeCalled()
225
+ expect(context.fail).not.toBeCalled()
226
+ })
227
+ })
228
+
229
+ describe('Response shortcuts', () => {
230
+ test('MissingParamResponse', async () => {
231
+ const pName = 'abc'
232
+ const r = Response.MissingParamResponse(pName)
233
+ await testResponse(r, {
234
+ err: `Invalid request. Path parameter ${pName} is missing.`,
235
+ errCode: Globals.ErrorCode_MissingParam,
236
+ })
237
+ })
238
+
239
+ test('MissingQueryResponse', async () => {
240
+ const pName = 'abc'
241
+ const r = Response.MissingQueryResponse(pName)
242
+ await testResponse(r, {
243
+ err: `Invalid request. Query parameter ${pName} is missing.`,
244
+ errCode: Globals.ErrorCode_MissingParam,
245
+ })
246
+ })
247
+
248
+ test('BadRequestResponse', async () => {
249
+ const message = 'abc'
250
+ const code = 'CODE'
251
+ const optBody = { additional: 123 }
252
+ const r = Response.BadRequestResponse(message, code, optBody)
253
+ await testResponse(r, {
254
+ err: message,
255
+ errCode: code,
256
+ ...optBody,
257
+ })
258
+ })
259
+
260
+ test('BadRequestResponse no opts', async () => {
261
+ const message = 'abc'
262
+ const r = Response.BadRequestResponse(message)
263
+ await testResponse(r, {
264
+ err: message,
265
+ })
266
+ })
267
+
268
+ test('BadRequestResponseWithRollback', async () => {
269
+ const message = 'abc'
270
+ const code = 'CODE'
271
+ const optBody = { additional: 123 }
272
+ const r = Response.BadRequestResponseWithRollback(message, code, optBody)
273
+ await testResponse(r, {
274
+ err: message,
275
+ rollback: true,
276
+ errCode: code,
277
+ ...optBody,
278
+ })
279
+ })
280
+
281
+ test('BadRequestResponseWithRollback no opts', async () => {
282
+ const message = 'abc'
283
+ const r = Response.BadRequestResponseWithRollback(message)
284
+ await testResponse(r, {
285
+ err: message,
286
+ rollback: true,
287
+ })
288
+ })
289
+
290
+ test('UnauthorizedResponse', async () => {
291
+ const message = 'abc'
292
+ const code = 'CODE'
293
+ const r = Response.UnauthorizedResponse(message, code)
294
+ await testResponse(
295
+ r,
296
+ {
297
+ err: message,
298
+ errCode: code,
299
+ },
300
+ 401
301
+ )
302
+ })
303
+
304
+ test('UnauthorizedResponse no code', async () => {
305
+ const message = 'abc'
306
+ const r = Response.UnauthorizedResponse(message)
307
+ await testResponse(r, { err: message }, 401)
308
+ })
309
+
310
+ test('SuccessResponse', async () => {
311
+ const body = { additional: 123 }
312
+ const r = Response.SuccessResponse(body)
313
+ await testResponse(r, body, 200)
314
+ })
315
+
316
+ test('SuccessResponse null body', async () => {
317
+ const r = Response.SuccessResponse(null)
318
+ await testResponse(r, {}, 200)
319
+ })
320
+
321
+ test('SuccessNoContentResponse', async () => {
322
+ const r = Response.SuccessNoContentResponse()
323
+ await testResponse(r, null, 204)
324
+ })
325
+
326
+ test('SimpleResponse', async () => {
327
+ const r = Response.SimpleResponse(null)
328
+ await testResponse(r, null, 200)
329
+ })
330
+
331
+ test('SimpleResponse override statuscode', async () => {
332
+ const r = Response.SimpleResponse(null, 203)
333
+ await testResponse(r, null, 203)
334
+ })
335
+
336
+ test('RedirectResponse', async () => {
337
+ const url = 'https://google.com'
338
+ const r = Response.RedirectResponse(url)
339
+ await testResponse(r, null, 302, { Location: url })
340
+ })
341
+
342
+ test('SuccessStreamResponse', async () => {
343
+ const b = { name: 'abc' }
344
+ const r = Response.SuccessStreamResponse(b, 'test-stream')
345
+ const t = observableTransaction()
346
+ const context = t['context']
347
+ const buildR = await r.build(context, t, false)
348
+ await r.build(context, t, false) //pipe twice, should not affect
349
+ c_expect(buildR).to.be.undefined
350
+ expect(context.fail).not.toBeCalled()
351
+ expect(context.done).not.toBeCalled()
352
+ expect(context.succeed).toHaveBeenCalledTimes(1)
353
+ expect(context.succeed).toHaveBeenCalledWith({
354
+ statusCode: 200,
355
+ headers: {
356
+ ...defaultHeaders,
357
+ 'Content-Type': 'test-stream',
358
+ Connection: 'keep-alive',
359
+ },
360
+ body: {
361
+ ...b,
362
+ },
363
+ })
364
+ })
365
+ })
366
+
367
+ export {}
@@ -0,0 +1,167 @@
1
+ import { expect } from 'chai'
2
+
3
+ import Utils from '../../src/Util/Utils.js'
4
+
5
+ describe('isHybridlessContainer', () => {
6
+ test('Simple isHybridlessContainer test', () => {
7
+ const v = Utils.isHybridlessContainer()
8
+ expect(v).to.be.a('boolean')
9
+ // this is done, so tests are reliable based on the testing .env
10
+ expect(v).to.be[process.env.HYBRIDLESS_RUNTIME ? 'true' : 'false']
11
+ })
12
+ })
13
+
14
+ describe('isValidString', () => {
15
+ test('Empty string is not valid', () => {
16
+ const v = Utils.isValidString('')
17
+ expect(v).to.be.a('boolean')
18
+ expect(v).to.be.false
19
+ })
20
+
21
+ test('Number is not a valid string', () => {
22
+ // @ts-ignore
23
+ const v = Utils.isValidString(12)
24
+ expect(v).to.be.a('boolean')
25
+ expect(v).to.be.false
26
+ })
27
+
28
+ test('Simple string is valid', () => {
29
+ const v = Utils.isValidString('abc')
30
+ expect(v).to.be.a('boolean')
31
+ expect(v).to.be.true
32
+ })
33
+ })
34
+
35
+ describe('parseIntNullIfNaN', () => {
36
+ test('Null if only chars', () => {
37
+ const v = Utils.parseIntNullIfNaN('abc')
38
+ expect(v).to.be.null
39
+ })
40
+
41
+ test('Null if chars with numbers', () => {
42
+ const v = Utils.parseIntNullIfNaN('abc123')
43
+ expect(v).to.be.null
44
+ })
45
+
46
+ test('Null if null', () => {
47
+ // @ts-ignore
48
+ const v = Utils.parseIntNullIfNaN(null)
49
+ expect(v).to.be.null
50
+ })
51
+
52
+ test('Not null if starts with numbers (js behavior)', () => {
53
+ const v = Utils.parseIntNullIfNaN('123abc')
54
+ expect(v).to.be.a('number')
55
+ expect(v).to.be.equals(123)
56
+ })
57
+
58
+ test('Not null if numbers', () => {
59
+ const v = Utils.parseIntNullIfNaN('123')
60
+ expect(v).to.be.a('number')
61
+ expect(v).to.be.equals(123)
62
+ })
63
+
64
+ test('Not null if number type', () => {
65
+ // @ts-ignore
66
+ const v = Utils.parseIntNullIfNaN(123)
67
+ expect(v).to.be.a('number')
68
+ expect(v).to.be.equals(123)
69
+ })
70
+ })
71
+
72
+ describe('parseObjectNullIfEmpty', () => {
73
+ test('Null if only chars', () => {
74
+ const v = Utils.parseObjectNullIfEmpty('abc')
75
+ expect(v).to.be.null
76
+ })
77
+
78
+ test('Null if chars with numbers', () => {
79
+ const v = Utils.parseObjectNullIfEmpty('abc123')
80
+ expect(v).to.be.null
81
+ })
82
+
83
+ test('Null if null', () => {
84
+ // @ts-ignore
85
+ const v = Utils.parseObjectNullIfEmpty(null)
86
+ expect(v).to.be.null
87
+ })
88
+
89
+ test('Null if malformed object', () => {
90
+ const v = Utils.parseObjectNullIfEmpty('{d: 123}')
91
+ expect(v).to.be.null
92
+ })
93
+
94
+ test('Null if empty object', () => {
95
+ const v = Utils.parseObjectNullIfEmpty('{}')
96
+ expect(v).to.be.null
97
+ })
98
+
99
+ test('Not null if object with a key', () => {
100
+ const v = Utils.parseObjectNullIfEmpty('{"d": 123}')
101
+ expect(v).to.be.a('object')
102
+ expect(v?.['d']).to.be.equals(123)
103
+ })
104
+ })
105
+
106
+ describe('isValidNumber', () => {
107
+ test('Not a valid number if only chars', () => {
108
+ const v = Utils.isValidNumber('abc')
109
+ expect(v).to.be.false
110
+ })
111
+
112
+ test('Not a valid number if only chars and numbers', () => {
113
+ const v = Utils.isValidNumber('abc123')
114
+ expect(v).to.be.false
115
+ })
116
+
117
+ test('Not a valid number if causes a crash on conversion', () => {
118
+ // @ts-ignore
119
+ const v = Utils.isValidNumber({
120
+ toString: () => {
121
+ throw new Error('Evil object')
122
+ },
123
+ })
124
+ expect(v).to.be.false
125
+ })
126
+
127
+ test('Valid number if numbers and chars after', () => {
128
+ const v = Utils.isValidNumber('123abc')
129
+ expect(v).to.be.true
130
+ })
131
+
132
+ test('Valid number if numbers', () => {
133
+ const v = Utils.isValidNumber('123')
134
+ expect(v).to.be.true
135
+ })
136
+ })
137
+
138
+ describe('caseInsensitiveObjectForKey', () => {
139
+ test('Get a key that is lowercase, asking uppercase', () => {
140
+ const v = Utils.caseInsensitiveObjectForKey({ abc: 123 }, 'ABC')
141
+ expect(v).to.be.a('number')
142
+ expect(v).to.be.equals(123)
143
+ })
144
+
145
+ test('Get a key that is uppercase, asking lowercase', () => {
146
+ const v = Utils.caseInsensitiveObjectForKey({ ABC: 123 }, 'abc')
147
+ expect(v).to.be.a('number')
148
+ expect(v).to.be.equals(123)
149
+ })
150
+
151
+ test('Fails gracefully if key is not found', () => {
152
+ const v = Utils.caseInsensitiveObjectForKey({ ABC: 123 }, 'asd')
153
+ expect(v).to.be.null
154
+ })
155
+
156
+ test('Fails gracefully for null object', () => {
157
+ const v = Utils.caseInsensitiveObjectForKey(null, 'abc')
158
+ expect(v).to.be.null
159
+ })
160
+
161
+ test('Fails gracefully for invalid object', () => {
162
+ const v = Utils.caseInsensitiveObjectForKey('', 'abc')
163
+ expect(v).to.be.null
164
+ })
165
+ })
166
+
167
+ export {}