@ikonintegration/ikapi 4.0.1 → 5.0.0

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 (236) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc.cjs +81 -0
  3. package/.github/workflows/npmpublish.yml +8 -19
  4. package/.github/workflows/prs.yml +12 -0
  5. package/README.md +89 -99
  6. package/dist/index.d.ts +16 -0
  7. package/dist/index.js +27 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/package-lock.json +11881 -0
  10. package/dist/package.json +81 -0
  11. package/dist/src/API/Request.d.ts +125 -0
  12. package/dist/src/API/Request.js +185 -0
  13. package/dist/src/API/Request.js.map +1 -0
  14. package/dist/src/API/Response.d.ts +188 -0
  15. package/dist/src/API/Response.js +270 -0
  16. package/dist/src/API/Response.js.map +1 -0
  17. package/dist/src/BaseEvent/DynamoTransaction.d.ts +70 -0
  18. package/dist/src/BaseEvent/DynamoTransaction.js +104 -0
  19. package/dist/src/BaseEvent/DynamoTransaction.js.map +1 -0
  20. package/dist/src/BaseEvent/EventProcessor.d.ts +58 -0
  21. package/dist/src/BaseEvent/EventProcessor.js +101 -0
  22. package/dist/src/BaseEvent/EventProcessor.js.map +1 -0
  23. package/dist/src/BaseEvent/Process.d.ts +50 -0
  24. package/dist/src/BaseEvent/Process.js +64 -0
  25. package/dist/src/BaseEvent/Process.js.map +1 -0
  26. package/dist/src/BaseEvent/StepTransaction.d.ts +23 -0
  27. package/dist/src/BaseEvent/StepTransaction.js +27 -0
  28. package/dist/src/BaseEvent/StepTransaction.js.map +1 -0
  29. package/dist/src/BaseEvent/Transaction.d.ts +149 -0
  30. package/dist/src/BaseEvent/Transaction.js +224 -0
  31. package/dist/src/BaseEvent/Transaction.js.map +1 -0
  32. package/dist/src/Cache/Redis.d.ts +29 -0
  33. package/dist/src/Cache/Redis.js +80 -0
  34. package/dist/src/Cache/Redis.js.map +1 -0
  35. package/dist/src/Cache/types.d.ts +31 -0
  36. package/dist/src/Cache/types.js +2 -0
  37. package/dist/src/Cache/types.js.map +1 -0
  38. package/dist/src/Config/Configuration.d.ts +123 -0
  39. package/dist/src/Config/Configuration.js +109 -0
  40. package/dist/src/Config/Configuration.js.map +1 -0
  41. package/dist/src/Config/EnvironmentVar.d.ts +74 -0
  42. package/dist/src/Config/EnvironmentVar.js +138 -0
  43. package/dist/src/Config/EnvironmentVar.js.map +1 -0
  44. package/dist/src/Crypto/Crypto.d.ts +45 -0
  45. package/dist/src/Crypto/Crypto.js +72 -0
  46. package/dist/src/Crypto/Crypto.js.map +1 -0
  47. package/dist/src/Database/Database.d.ts +21 -0
  48. package/dist/src/Database/Database.js +15 -0
  49. package/dist/src/Database/Database.js.map +1 -0
  50. package/dist/src/Database/DatabaseManager.d.ts +47 -0
  51. package/dist/src/Database/DatabaseManager.js +60 -0
  52. package/dist/src/Database/DatabaseManager.js.map +1 -0
  53. package/dist/src/Database/DatabaseTransaction.d.ts +101 -0
  54. package/dist/src/Database/DatabaseTransaction.js +126 -0
  55. package/dist/src/Database/DatabaseTransaction.js.map +1 -0
  56. package/dist/src/Database/index.d.ts +10 -0
  57. package/dist/src/Database/index.js +15 -0
  58. package/dist/src/Database/index.js.map +1 -0
  59. package/dist/src/Database/integrations/dynamo/DynamoDatabase.d.ts +35 -0
  60. package/dist/src/Database/integrations/dynamo/DynamoDatabase.js +59 -0
  61. package/dist/src/Database/integrations/dynamo/DynamoDatabase.js.map +1 -0
  62. package/dist/src/Database/integrations/kysely/KyselyDatabase.d.ts +66 -0
  63. package/dist/src/Database/integrations/kysely/KyselyDatabase.js +86 -0
  64. package/dist/src/Database/integrations/kysely/KyselyDatabase.js.map +1 -0
  65. package/dist/src/Database/integrations/kysely/KyselyTransaction.d.ts +70 -0
  66. package/dist/src/Database/integrations/kysely/KyselyTransaction.js +118 -0
  67. package/dist/src/Database/integrations/kysely/KyselyTransaction.js.map +1 -0
  68. package/dist/src/Database/integrations/pgsql/PostgresDatabase.d.ts +36 -0
  69. package/dist/src/Database/integrations/pgsql/PostgresDatabase.js +54 -0
  70. package/dist/src/Database/integrations/pgsql/PostgresDatabase.js.map +1 -0
  71. package/dist/src/Database/integrations/pgsql/PostgresTransaction.d.ts +63 -0
  72. package/dist/src/Database/integrations/pgsql/PostgresTransaction.js +61 -0
  73. package/dist/src/Database/integrations/pgsql/PostgresTransaction.js.map +1 -0
  74. package/dist/src/Database/types.d.ts +76 -0
  75. package/dist/src/Database/types.js +2 -0
  76. package/dist/src/Database/types.js.map +1 -0
  77. package/dist/src/Globals.d.ts +93 -0
  78. package/dist/src/Globals.js +99 -0
  79. package/dist/src/Globals.js.map +1 -0
  80. package/dist/src/Logger/Logger.d.ts +161 -0
  81. package/dist/src/Logger/Logger.js +299 -0
  82. package/dist/src/Logger/Logger.js.map +1 -0
  83. package/dist/src/Mailer/Mailer.d.ts +78 -0
  84. package/dist/src/Mailer/Mailer.js +182 -0
  85. package/dist/src/Mailer/Mailer.js.map +1 -0
  86. package/dist/src/Publisher/Publisher.d.ts +39 -0
  87. package/dist/src/Publisher/Publisher.js +77 -0
  88. package/dist/src/Publisher/Publisher.js.map +1 -0
  89. package/dist/src/Server/RouteResolver.d.ts +33 -0
  90. package/dist/src/Server/RouteResolver.js +100 -0
  91. package/dist/src/Server/RouteResolver.js.map +1 -0
  92. package/dist/src/Server/Router.d.ts +157 -0
  93. package/dist/src/Server/Router.js +32 -0
  94. package/dist/src/Server/Router.js.map +1 -0
  95. package/dist/src/Server/lib/ContainerServer.d.ts +42 -0
  96. package/dist/src/Server/lib/ContainerServer.js +66 -0
  97. package/dist/src/Server/lib/ContainerServer.js.map +1 -0
  98. package/dist/src/Server/lib/Server.d.ts +45 -0
  99. package/dist/src/Server/lib/Server.js +93 -0
  100. package/dist/src/Server/lib/Server.js.map +1 -0
  101. package/dist/src/Server/lib/container/GenericHandler.d.ts +9 -0
  102. package/dist/src/Server/lib/container/GenericHandler.js +82 -0
  103. package/dist/src/Server/lib/container/GenericHandler.js.map +1 -0
  104. package/dist/src/Server/lib/container/GenericHandlerEvent.d.ts +52 -0
  105. package/dist/src/Server/lib/container/GenericHandlerEvent.js +132 -0
  106. package/dist/src/Server/lib/container/GenericHandlerEvent.js.map +1 -0
  107. package/dist/src/Server/lib/container/HealthHandler.d.ts +9 -0
  108. package/dist/src/Server/lib/container/HealthHandler.js +19 -0
  109. package/dist/src/Server/lib/container/HealthHandler.js.map +1 -0
  110. package/dist/src/Server/lib/container/Proxy.d.ts +67 -0
  111. package/dist/src/Server/lib/container/Proxy.js +143 -0
  112. package/dist/src/Server/lib/container/Proxy.js.map +1 -0
  113. package/dist/src/Server/lib/container/Utils.d.ts +14 -0
  114. package/dist/src/Server/lib/container/Utils.js +37 -0
  115. package/dist/src/Server/lib/container/Utils.js.map +1 -0
  116. package/dist/src/Util/AsyncSingleton.d.ts +31 -0
  117. package/dist/src/Util/AsyncSingleton.js +83 -0
  118. package/dist/src/Util/AsyncSingleton.js.map +1 -0
  119. package/dist/src/Util/Utils.d.ts +61 -0
  120. package/dist/src/Util/Utils.js +147 -0
  121. package/dist/src/Util/Utils.js.map +1 -0
  122. package/dist/src/Validation/Validator.d.ts +17 -0
  123. package/dist/src/Validation/Validator.js +39 -0
  124. package/dist/src/Validation/Validator.js.map +1 -0
  125. package/dist/tsconfig.tsbuildinfo +1 -0
  126. package/index.ts +41 -0
  127. package/jest.config.ts +37 -0
  128. package/jest.smoke.config.ts +34 -0
  129. package/package.json +66 -22
  130. package/src/API/Request.ts +214 -0
  131. package/src/API/Response.ts +370 -0
  132. package/src/BaseEvent/DynamoTransaction.ts +175 -0
  133. package/src/BaseEvent/EventProcessor.ts +140 -0
  134. package/src/BaseEvent/Process.ts +78 -0
  135. package/src/BaseEvent/StepTransaction.ts +35 -0
  136. package/src/BaseEvent/Transaction.ts +323 -0
  137. package/src/Cache/Redis.ts +89 -0
  138. package/src/Cache/types.ts +33 -0
  139. package/src/Config/Configuration.ts +199 -0
  140. package/src/Config/EnvironmentVar.ts +142 -0
  141. package/src/Crypto/Crypto.ts +89 -0
  142. package/src/Database/Database.ts +22 -0
  143. package/src/Database/DatabaseManager.ts +67 -0
  144. package/src/Database/DatabaseTransaction.ts +170 -0
  145. package/src/Database/index.ts +27 -0
  146. package/src/Database/integrations/dynamo/DynamoDatabase.ts +58 -0
  147. package/src/Database/integrations/kysely/KyselyDatabase.ts +99 -0
  148. package/src/Database/integrations/kysely/KyselyTransaction.ts +172 -0
  149. package/src/Database/integrations/pgsql/PostgresDatabase.ts +56 -0
  150. package/src/Database/integrations/pgsql/PostgresTransaction.ts +87 -0
  151. package/src/Database/types.ts +85 -0
  152. package/src/Globals.ts +103 -0
  153. package/src/Logger/Logger.ts +363 -0
  154. package/src/Mailer/Mailer.ts +217 -0
  155. package/src/Publisher/Publisher.ts +96 -0
  156. package/src/Server/RouteResolver.ts +124 -0
  157. package/src/Server/Router.ts +200 -0
  158. package/src/Server/lib/ContainerServer.ts +65 -0
  159. package/src/Server/lib/Server.ts +109 -0
  160. package/src/Server/lib/container/GenericHandler.ts +76 -0
  161. package/src/Server/lib/container/GenericHandlerEvent.ts +154 -0
  162. package/src/Server/lib/container/HealthHandler.ts +11 -0
  163. package/src/Server/lib/container/Proxy.ts +172 -0
  164. package/src/Server/lib/container/Utils.ts +33 -0
  165. package/src/Util/AsyncSingleton.ts +86 -0
  166. package/src/Util/Utils.ts +131 -0
  167. package/src/Validation/Validator.ts +45 -0
  168. package/tests/API/Request.test.ts +273 -0
  169. package/tests/API/Response.test.ts +367 -0
  170. package/tests/BaseEvent/DynamoTransaction.test.ts +272 -0
  171. package/tests/BaseEvent/EventProcessor.test.ts +263 -0
  172. package/tests/BaseEvent/Process.test.ts +47 -0
  173. package/tests/BaseEvent/StepTransaction.test.ts +44 -0
  174. package/tests/BaseEvent/Transaction.test.ts +402 -0
  175. package/tests/Cache/Redis-client.test.ts +90 -0
  176. package/tests/Cache/Redis-cluster.test.ts +100 -0
  177. package/tests/Config/Config.test.ts +205 -0
  178. package/tests/Config/EnvironmentVar.test.ts +251 -0
  179. package/tests/Crypto/Crypto.test.ts +88 -0
  180. package/tests/Database/DatabaseManager.test.ts +79 -0
  181. package/tests/Database/integrations/dynamo/DynamoDatabase.test.ts +44 -0
  182. package/tests/Database/integrations/kysely/KyselyDatabase.test.ts +113 -0
  183. package/tests/Database/integrations/kysely/KyselyTransaction.test.ts +119 -0
  184. package/tests/Database/integrations/pg/PostgresDatabase.test.ts +76 -0
  185. package/tests/Database/integrations/pg/PostgresTransaction.test.ts +118 -0
  186. package/tests/Logger/Logger.test.ts +215 -0
  187. package/tests/Mailer/Mailer.test.ts +59 -0
  188. package/tests/Publisher/Publisher.test.ts +60 -0
  189. package/tests/Server/RouteResolver.test.ts +116 -0
  190. package/tests/Server/Router.test.ts +39 -0
  191. package/tests/Server/lib/ContainerServer.test.ts +531 -0
  192. package/tests/Server/lib/Server.test.ts +12 -0
  193. package/tests/Server/lib/container/GenericHandler.test.ts +131 -0
  194. package/tests/Server/lib/container/GenericHandlerEvent.test.ts +103 -0
  195. package/tests/Server/lib/container/HealthHandler.test.ts +30 -0
  196. package/tests/Server/lib/container/Proxy.test.ts +268 -0
  197. package/tests/Server/lib/container/Utils.test.ts +47 -0
  198. package/tests/Test.utils.ts +78 -0
  199. package/tests/Utils/Utils.test.ts +229 -0
  200. package/tests/Validation/Validator.test.ts +82 -0
  201. package/tsconfig.json +26 -0
  202. package/tsconfig.smoke.json +26 -0
  203. package/index.js +0 -88
  204. package/src/API/IKRequest.js +0 -52
  205. package/src/API/IKResponse.js +0 -119
  206. package/src/API/IKUtils.js +0 -51
  207. package/src/BaseEvent/IKProcess.js +0 -77
  208. package/src/BaseEvent/IKTransaction.js +0 -139
  209. package/src/Cache/Prototype/IKCache.js +0 -17
  210. package/src/Cache/Redis/IKRedis.js +0 -148
  211. package/src/Database/DDB/IKDB.js +0 -56
  212. package/src/Database/DDB/IKDBBaseExpression.js +0 -130
  213. package/src/Database/DDB/IKDBBaseQuery.js +0 -151
  214. package/src/Database/DDB/IKDBQueryBatchGet.js +0 -37
  215. package/src/Database/DDB/IKDBQueryBatchWrite.js +0 -64
  216. package/src/Database/DDB/IKDBQueryDelete.js +0 -34
  217. package/src/Database/DDB/IKDBQueryGet.js +0 -48
  218. package/src/Database/DDB/IKDBQueryPut.js +0 -87
  219. package/src/Database/DDB/IKDBQueryScan.js +0 -45
  220. package/src/Database/DDB/IKDBQueryTransactionalWrite.js +0 -69
  221. package/src/Database/DDB/IKDBQueryUpdate.js +0 -221
  222. package/src/Database/DDB/_IKDBQueryTransactionalRead.js +0 -46
  223. package/src/Database/PSQL/IKDB.js +0 -41
  224. package/src/Database/PSQL/IKDBBaseQuery.js +0 -26
  225. package/src/Database/Prototype/IKDB.js +0 -21
  226. package/src/Database/Prototype/IKDBBaseQuery.js +0 -14
  227. package/src/IKDynamoStream.js +0 -42
  228. package/src/IKEventProcessor.js +0 -42
  229. package/src/IKGlobals.js +0 -24
  230. package/src/IKRouter.js +0 -47
  231. package/src/IKStepTransaction.js +0 -14
  232. package/src/Logger/IKLogger.js +0 -136
  233. package/src/Mailer/IKMailer.js +0 -69
  234. package/src/Publisher/IKPublisher.js +0 -44
  235. package/src/Tracker/IKExecutionTracker.js +0 -79
  236. package/src/Validation/IKValidation.js +0 -76
@@ -0,0 +1,229 @@
1
+ import { expect as c_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
+ c_expect(v).to.be.a('boolean')
9
+ // this is done, so tests are reliable based on the testing .env
10
+ c_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
+ c_expect(v).to.be.a('boolean')
18
+ c_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
+ c_expect(v).to.be.a('boolean')
25
+ c_expect(v).to.be.false
26
+ })
27
+
28
+ test('Simple string is valid', () => {
29
+ const v = Utils.isValidString('abc')
30
+ c_expect(v).to.be.a('boolean')
31
+ c_expect(v).to.be.true
32
+ })
33
+ })
34
+
35
+ describe('parseIntNullIfNaN', () => {
36
+ test('Null if only chars', () => {
37
+ const v = Utils.parseIntNullIfNaN('abc')
38
+ c_expect(v).to.be.null
39
+ })
40
+
41
+ test('Null if chars with numbers', () => {
42
+ const v = Utils.parseIntNullIfNaN('abc123')
43
+ c_expect(v).to.be.null
44
+ })
45
+
46
+ test('Null if null', () => {
47
+ // @ts-ignore
48
+ const v = Utils.parseIntNullIfNaN(null)
49
+ c_expect(v).to.be.null
50
+ })
51
+
52
+ test('Not null if starts with numbers (js behavior)', () => {
53
+ const v = Utils.parseIntNullIfNaN('123abc')
54
+ c_expect(v).to.be.a('number')
55
+ c_expect(v).to.be.equals(123)
56
+ })
57
+
58
+ test('Not null if numbers', () => {
59
+ const v = Utils.parseIntNullIfNaN('123')
60
+ c_expect(v).to.be.a('number')
61
+ c_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
+ c_expect(v).to.be.a('number')
68
+ c_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
+ c_expect(v).to.be.null
76
+ })
77
+
78
+ test('Null if chars with numbers', () => {
79
+ const v = Utils.parseObjectNullIfEmpty('abc123')
80
+ c_expect(v).to.be.null
81
+ })
82
+
83
+ test('Null if null', () => {
84
+ // @ts-ignore
85
+ const v = Utils.parseObjectNullIfEmpty(null)
86
+ c_expect(v).to.be.null
87
+ })
88
+
89
+ test('Null if malformed object', () => {
90
+ const v = Utils.parseObjectNullIfEmpty('{d: 123}')
91
+ c_expect(v).to.be.null
92
+ })
93
+
94
+ test('Null if empty object', () => {
95
+ const v = Utils.parseObjectNullIfEmpty('{}')
96
+ c_expect(v).to.be.null
97
+ })
98
+
99
+ test('Not null if object with a key', () => {
100
+ const v = Utils.parseObjectNullIfEmpty('{"d": 123}')
101
+ c_expect(v).to.be.a('object')
102
+ c_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
+ c_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
+ c_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
+ c_expect(v).to.be.false
125
+ })
126
+
127
+ test('Valid number if numbers and chars after', () => {
128
+ const v = Utils.isValidNumber('123abc')
129
+ c_expect(v).to.be.true
130
+ })
131
+
132
+ test('Valid number if numbers', () => {
133
+ const v = Utils.isValidNumber('123')
134
+ c_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
+ c_expect(v).to.be.a('number')
142
+ c_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
+ c_expect(v).to.be.a('number')
148
+ c_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
+ c_expect(v).to.be.null
154
+ })
155
+
156
+ test('Fails gracefully for null object', () => {
157
+ const v = Utils.caseInsensitiveObjectForKey(null, 'abc')
158
+ c_expect(v).to.be.null
159
+ })
160
+
161
+ test('Fails gracefully for invalid object', () => {
162
+ const v = Utils.caseInsensitiveObjectForKey('', 'abc')
163
+ c_expect(v).to.be.null
164
+ })
165
+ })
166
+
167
+ describe('ddbMarshall', () => {
168
+ test('Marshalling of a simple object', () => {
169
+ const input = { key: 'value' }
170
+ const output = Utils.ddbMarshall(input)
171
+ expect(output).toEqual({ key: { S: 'value' } })
172
+ })
173
+
174
+ test('Marshalling of an array', () => {
175
+ const input = [1, 2, 3]
176
+ const output = Utils.ddbMarshall(input)
177
+ expect(output).toEqual({ L: [{ N: '1' }, { N: '2' }, { N: '3' }] })
178
+ })
179
+
180
+ test('Marshalling of a nested object', () => {
181
+ const input = { key: { nestedKey: 'nestedValue' } }
182
+ const output = Utils.ddbMarshall(input)
183
+ expect(output).toEqual({ key: { M: { nestedKey: { S: 'nestedValue' } } } })
184
+ })
185
+
186
+ test('Marshalling of a complex object with undefined values', () => {
187
+ const input = { key1: 'value1', key2: undefined, key3: null }
188
+ const output = Utils.ddbMarshall(input)
189
+ expect(output).toEqual({ key1: { S: 'value1' }, key3: { NULL: true } })
190
+ })
191
+
192
+ test('Marshalling of a primitive value', () => {
193
+ const input = 42
194
+ const output = Utils.ddbMarshall(input)
195
+ expect(output).toEqual({ N: '42' })
196
+ })
197
+ })
198
+
199
+ describe('ddbUnmarshall', () => {
200
+ test('Unmarshalling of a simple DynamoDB object', () => {
201
+ const input = { key: { S: 'value' } }
202
+ const output = Utils.ddbUnmarshall(input)
203
+ expect(output).toEqual({ key: 'value' })
204
+ })
205
+
206
+ test('Unmarshalling of a DynamoDB array', () => {
207
+ const input = { array: { L: [{ N: '1' }, { N: '2' }, { N: '3' }] } }
208
+ const output = Utils.ddbUnmarshall(input)
209
+ expect(output.array).toEqual([1, 2, 3])
210
+ })
211
+
212
+ test('Unmarshalling of a nested DynamoDB object', () => {
213
+ const input = { key: { M: { nestedKey: { S: 'nestedValue' } } } }
214
+ const output = Utils.ddbUnmarshall(input)
215
+ expect(output).toEqual({ key: { nestedKey: 'nestedValue' } })
216
+ })
217
+
218
+ test('Unmarshalling of a complex DynamoDB object with null values', () => {
219
+ const input = { key1: { S: 'value1' }, key3: { NULL: true } }
220
+ const output = Utils.ddbUnmarshall(input)
221
+ expect(output).toEqual({ key1: 'value1', key3: null })
222
+ })
223
+
224
+ test('Unmarshalling of a primitive value', () => {
225
+ const input = { key: { N: '42' } }
226
+ const output = Utils.ddbUnmarshall(input)
227
+ expect(output.key).toEqual(42)
228
+ })
229
+ })
@@ -0,0 +1,82 @@
1
+ import { expect } from 'chai'
2
+ import { z } from 'zod'
3
+
4
+ import Response from '../../src/API/Response.js'
5
+ import Globals from '../../src/Globals.js'
6
+ import Validator from '../../src/Validation/Validator.js'
7
+ import { ViewSchema } from '../Test.utils.js'
8
+
9
+ function expectFullFailure(validationResult, c = 4) {
10
+ expect(validationResult).to.be.an.instanceof(Response)
11
+ if (validationResult instanceof Response) {
12
+ expect(validationResult.getBody()).is.not.null
13
+ expect(validationResult.getBody()).to.have.property('err', Globals.ErrorResponseValidationFail)
14
+ expect(validationResult.getBody()).to.have.property('errCode', Globals.ErrorCode_InvalidInput)
15
+ expect(validationResult.getBody()).to.have.property('validationFailure')
16
+ expect(validationResult.getBody()['validationFailure']).to.have.lengthOf(c)
17
+ expect(validationResult.getCode()).is.equals(400)
18
+ }
19
+ }
20
+
21
+ describe('Validates unsuccessfully', () => {
22
+ test('Fails to validate async', () => {
23
+ const validationResult = Validator.validateSchema(async () => {}, ViewSchema)
24
+ expectFullFailure(validationResult, 1)
25
+ })
26
+
27
+ test('Fails to validate null', () => {
28
+ const validationResult = Validator.validateSchema(null, ViewSchema)
29
+ expectFullFailure(validationResult, 1)
30
+ })
31
+
32
+ test('Fails to validate empty string', () => {
33
+ const validationResult = Validator.validateSchema('', ViewSchema)
34
+ expectFullFailure(validationResult, 1)
35
+ })
36
+
37
+ test('Fails to validate empty object', () => {
38
+ const validationResult = Validator.validateSchema({}, ViewSchema)
39
+ expectFullFailure(validationResult)
40
+ })
41
+
42
+ test('Fails to validate object with wrong keys', () => {
43
+ const validationResult = Validator.validateSchema({ name: 'Joe' }, ViewSchema)
44
+ expectFullFailure(validationResult)
45
+ })
46
+
47
+ test('Fails to validate object with wrong key types', () => {
48
+ const validationResult = Validator.validateSchema({ id: 123 }, ViewSchema)
49
+ expectFullFailure(validationResult)
50
+ if (validationResult instanceof Response) {
51
+ console.log(validationResult.getBody()['validationFailure'])
52
+ expect(
53
+ validationResult.getBody()['validationFailure'].filter(f => {
54
+ return f.message == 'Expected string, received number'
55
+ })
56
+ ).to.have.lengthOf(1)
57
+ }
58
+ })
59
+ })
60
+
61
+ describe('Validates successfully', () => {
62
+ test('Succeeds to validate', () => {
63
+ const validationResult = Validator.validateSchema(
64
+ {
65
+ id: '123',
66
+ content: '123',
67
+ createdAt: new Date(),
68
+ updatedAt: new Date(),
69
+ },
70
+ ViewSchema
71
+ )
72
+ expect(validationResult).to.not.be.an.instanceof(Response)
73
+ expect(validationResult).to.be.true
74
+ })
75
+ test('Succeeds to validate null schema', () => {
76
+ const validationResult = Validator.validateSchema(null, ViewSchema.or(z.null()))
77
+ expect(validationResult).to.not.be.an.instanceof(Response)
78
+ expect(validationResult).to.be.true
79
+ })
80
+ })
81
+
82
+ export {}
package/tsconfig.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "exclude": ["**/*.test.*", "**/__mocks__/*", "**/__tests__/*", "**/tests/*", "./dist/**/*", "./smoke-tests/**/*", "./jest*", "./node_modules"],
3
+ "include": ["./**/*", "./package.json", "./package-lock.json"],
4
+ "compilerOptions": {
5
+ "lib": [
6
+ "es5",
7
+ "es6",
8
+ "dom"
9
+ ],
10
+ "module": "esnext",
11
+ "target": "es6",
12
+ "moduleResolution": "node",
13
+ "esModuleInterop": true,
14
+ "noImplicitAny": false,
15
+ "noEmitOnError": true,
16
+ "removeComments": false,
17
+ "downlevelIteration": true,
18
+ "resolveJsonModule": true,
19
+ "sourceMap": true,
20
+ "outDir": "dist",
21
+ "declaration": true,
22
+ "skipLibCheck": true,
23
+ "strictNullChecks": true,
24
+ "noErrorTruncation": true
25
+ }
26
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "exclude": ["./dist/**/*", "./smoke-tests/**/*", "./node_modules", "./**/Logger.test.*"],
3
+ "include": ["./**/*", "./package.json", "./package-lock.json"],
4
+ "compilerOptions": {
5
+ "lib": [
6
+ "es5",
7
+ "es6",
8
+ "dom"
9
+ ],
10
+ "module": "esnext",
11
+ "target": "es6",
12
+ "moduleResolution": "node",
13
+ "noImplicitAny": false,
14
+ "noEmitOnError": true,
15
+ "removeComments": false,
16
+ "downlevelIteration": true,
17
+ "resolveJsonModule": true,
18
+ "sourceMap": true,
19
+ "esModuleInterop": true,
20
+ "outDir": "smoke-tests",
21
+ "declaration": true,
22
+ "skipLibCheck": true,
23
+ "strictNullChecks": true,
24
+ "noErrorTruncation": true
25
+ }
26
+ }
package/index.js DELETED
@@ -1,88 +0,0 @@
1
- //Set defaults
2
- import Bluebird from "bluebird";
3
- global.Promise = Bluebird;
4
- //Base Events
5
- import IKTransaction from "./src/BaseEvent/IKTransaction.js";
6
- import IKProcess from "./src/BaseEvent/IKProcess.js";
7
- //Extra Events
8
- import IKRouter from "./src/IKRouter.js";
9
- import IKEventProcessor from "./src/IKEventProcessor.js";
10
- import IKDynamoStream from "./src/IKDynamoStream.js";
11
- import IKStepTransaction from "./src/IKStepTransaction.js";
12
- //Extra components
13
- import IKMailer from "./src/Mailer/IKMailer.js";
14
- import IKValidation from "./src/Validation/IKValidation.js";
15
- //Responses
16
- import * as IKResponse from "./src/API/IKResponse.js";
17
- //Helpers
18
- import Utils from "./src/API/IKUtils.js";
19
- //Cache
20
- //Redis
21
- import IKRedis from "./src/Cache/Redis/IKRedis.js";
22
- //Database
23
- //PSQL
24
- import IKDBPSQLQuery from "./src/Database/PSQL/IKDBBaseQuery.js";
25
- //DDB
26
- import IKDBQueryScan from "./src/Database/DDB/IKDBQueryScan.js";
27
- import IKDBQueryGet from "./src/Database/DDB/IKDBQueryGet.js";
28
- import IKDBQueryPut from "./src/Database/DDB/IKDBQueryPut.js";
29
- import IKDBQueryUpdate from "./src/Database/DDB/IKDBQueryUpdate.js";
30
- import IKDBQueryDelete from "./src/Database/DDB/IKDBQueryDelete.js";
31
- import IKDBQueryBatchWrite from "./src/Database/DDB/IKDBQueryBatchWrite.js";
32
- import IKDBQueryBatchGet from "./src/Database/DDB/IKDBQueryBatchGet.js";
33
- import IKDBQueryTransactionalWrite from "./src/Database/DDB/IKDBQueryTransactionalWrite.js";
34
- import { IKDBExpressionOperator } from "./src/Database/DDB/IKDBBaseExpression.js";
35
- //
36
- export default {
37
- //Base Events
38
- IKTransaction,
39
- IKProcess,
40
- //Extra Events
41
- IKRouter,
42
- IKEventProcessor,
43
- IKDynamoStream,
44
- IKStepTransaction,
45
- //Extra components
46
- IKMailer,
47
- IKValidation,
48
- //Responses
49
- IKResponse: IKResponse.default,
50
- IKBadRequestResponse: IKResponse.IKBadRequestResponse,
51
- IKUnauthorizedResponse: IKResponse.IKUnauthorizedResponse,
52
- IKMissingParamResponse: IKResponse.IKMissingParamResponse,
53
- IKMissingQueryResponse: IKResponse.IKMissingQueryResponse,
54
- IKSuccessResponse: IKResponse.IKSuccessResponse,
55
- IKSuccessStreamResponse: IKResponse.IKSuccessStreamResponse,
56
- IKSuccessNoContentResponse: IKResponse.IKSuccessNoContentResponse,
57
- IKBadRequestResponseWithRollback: IKResponse.IKBadRequestResponseWithRollback,
58
- IKStepFunctionResponse: IKResponse.IKStepFunctionResponse,
59
- IKSimpleResponse: IKResponse.IKSimpleResponse,
60
- //Helpers
61
- Utils,
62
- //Cache
63
- //Redis
64
- IKRedis,
65
- //Database
66
- //PSQL
67
- IKDBPSQLQuery,
68
- //DDB
69
- IKDBDDBQueryScan: IKDBQueryScan,
70
- IKDBDDBQueryGet: IKDBQueryGet,
71
- IKDBDDBQueryPut: IKDBQueryPut,
72
- IKDBDDBQueryUpdate: IKDBQueryUpdate,
73
- IKDBDDBQueryDelete: IKDBQueryDelete,
74
- IKDBDDBQueryBatchWrite: IKDBQueryBatchWrite,
75
- IKDBDDBQueryBatchGet: IKDBQueryBatchGet,
76
- IKDBDDBQueryTransactionalWrite: IKDBQueryTransactionalWrite,
77
- IKDBDDBExpressionOperator: IKDBExpressionOperator,
78
- //Legacy
79
- IKDBQueryScan,
80
- IKDBQueryGet,
81
- IKDBQueryPut,
82
- IKDBQueryUpdate,
83
- IKDBQueryDelete,
84
- IKDBQueryBatchWrite,
85
- IKDBQueryBatchGet,
86
- IKDBQueryTransactionalWrite,
87
- IKDBExpressionOperator,
88
- };
@@ -1,52 +0,0 @@
1
- /** Ikon Integration DynamoDB wrapper**/
2
- import Utils from "./IKUtils.js";
3
- //
4
- export default class IKRequest {
5
- constructor(request, context, transaction) {
6
- this.requestEvent = request;
7
- this.transaction = transaction;
8
- this.context = context;
9
- this.transaction.logger.debug("Request info:", JSON.stringify(request));
10
- this.transaction.logger.debug("Request context:", JSON.stringify(context));
11
- }
12
- //query
13
- containsQueryParam(paramName) {
14
- const val = this.getQueryParam(paramName);
15
- return (Utils.isValidString(val) || Utils.isValidNumber(val));
16
- }
17
- getQueryParam(paramName) { return Utils.caseInsensitiveObjectForKey(this.requestEvent.queryStringParameters, paramName); }
18
- //header
19
- getHeader(headerName) { return Utils.caseInsensitiveObjectForKey(this.requestEvent.headers, headerName); }
20
- //context params
21
- getContextParam(cxtParam) { return Utils.caseInsensitiveObjectForKey(this.requestEvent.requestContext, cxtParam); }
22
- //path param
23
- containsPathParam(paramName) {
24
- const val = this.getPathParam(paramName);
25
- return (Utils.isValidString(val) || Utils.isValidNumber(val));
26
- }
27
- getPathParam(paramName) { return Utils.caseInsensitiveObjectForKey(this.requestEvent.pathParameters, paramName); }
28
- //body
29
- getBody() {
30
- let b = null;
31
- try {
32
- b = this.requestEvent.body;
33
- if (typeof b === 'string' || b instanceof String) b = JSON.parse(b);
34
- } catch (e) {}
35
- return b;
36
- }
37
- getPath() { return this.requestEvent.path; }
38
- getMethod() { return this.requestEvent.httpMethod; }
39
- getPathParams() { return this.requestEvent.pathParameters; }
40
-
41
- //Shortcuts
42
- getAuthorizationHeader() { return this.getHeader('Authorization'); }
43
- getRequestID() {
44
- if (this.context.awsRequestId) return this.context.awsRequestId;
45
- return (this.requestEvent.requestContext ? this.requestEvent.requestContext.requestId : 'unknown');
46
- }
47
- getOriginIP() {
48
- const origin = this.getContextParam('identity').sourceIp;
49
- const hOrigin = this.getHeader('X-Forwarded-For');
50
- return (origin ? origin : (hOrigin ? hOrigin : 'unknow'));
51
- }
52
- }
@@ -1,119 +0,0 @@
1
- import IKGlobals from '../IKGlobals.js';
2
- //
3
- export default class IKResponse {
4
- constructor(statusCode, body) {
5
- this._statusCode = statusCode;
6
- this._body = body;
7
- //
8
- this._streamingOut = false; //internal -- flag to indicate streaming out has started and avoid double stream call
9
- //indeally it should be moved to initialization method as we dont' want them to be changed on the go and also give the false impression of getters with the current naming pattern
10
- this._isStream = false; //
11
- this._contextRawBody = false;
12
- this._throwOnErrors = false;
13
- this.disableTransactionID = false;
14
- //
15
- this._headers = {
16
- "Access-Control-Allow-Origin": "*",
17
- "Access-Control-Allow-Credentials": true,
18
- "Content-Type": "application/json"
19
- };
20
- }
21
- getCode() { return this._statusCode; }
22
- getBody() { return this._body; }
23
- appendIntoBody(key, value) { this._body[key] = value; }
24
- appendHeader(key, value) { this._headers[key] = value; }
25
- async build(context, transaction, doNotSucceed) {
26
- //Stream support
27
- if (this._streamingOut) return;
28
- if (this._isStream) return this._pipe(context);
29
-
30
- //append default fields
31
- if (transaction.request.getRequestID() && this._body && !this.disableTransactionID) this.appendIntoBody('transactionID', transaction.request.getRequestID()); //append transaction ID
32
- //Raw response support
33
- if (this._contextRawBody) return this.rawContext(context, transaction);
34
-
35
- //build response
36
- let b = {
37
- statusCode: this._statusCode, headers: this._headers,
38
- ...(this._body ? { body: JSON.stringify(this._body) } : {}),
39
- };
40
- //log response and respond to context
41
- transaction.logger.debug(b)
42
- //Check for transaction response proxy
43
- if (transaction.responseProxy) await transaction.responseProxy(b);
44
- //Batch does not succeed directly just on upper transaction (which will should be a batch)
45
- if (!doNotSucceed) context.succeed(b);
46
- }
47
- _pipe(context) {
48
- //Check if not streaming
49
- if (this._streamingOut) return;
50
- this._streamingOut = true;
51
- //build response
52
- let b = { statusCode: this._statusCode, body: this._body, headers: this._headers };
53
- //log response and respond to context
54
- context.succeed(b);
55
- }
56
- rawContext(context, transaction) {
57
- //log response and respond to context
58
- transaction.logger.debug(this._body)
59
- if (this.getCode() <= 200 && this.getCode() <= 299) context.succeed(this._body);
60
- else {
61
- //
62
- function CustomError(body) {
63
- this.name = body && body.error ? body.error : 'UnknownError';
64
- this.message = body && body.message ? body.message : 'Unknown error!';
65
- }
66
- CustomError.prototype = new Error();
67
- //
68
- if (!this._throwOnErrors) context.fail(new CustomError(this._body));
69
- else throw (new CustomError(this._body));
70
- }
71
- }
72
- }
73
-
74
-
75
- /* Shortcuts */
76
- export function IKMissingParamResponse(paramName) {
77
- console.warn(`Invalid request - Path parameter ${paramName} is missing.`);
78
- return (new IKResponse(400, { err: `Invalid request. Path parameter ${paramName} is missing.`, errCode: IKGlobals.ErrorCode_MissingParam }));
79
- }
80
- export function IKMissingQueryResponse(paramName) {
81
- console.warn(`Invalid request - Query parameter ${paramName} is missing.`);
82
- return (new IKResponse(400, { err: `Invalid request. Query parameter ${paramName} is missing.`, errCode: IKGlobals.ErrorCode_MissingParam }));
83
- }
84
- export function IKBadRequestResponse(msg, errCode, optBody) {
85
- console.warn(`Bad request - ${msg}`);
86
- return (new IKResponse(400, { err: msg, ...(errCode ? { errCode: errCode } : {}), ...(optBody || {}) }));
87
- }
88
- export function IKBadRequestResponseWithRollback(msg, errCode, optBody) {
89
- console.warn(`Bad request - ${msg}`);
90
- return (new IKResponse(400, { err: msg, rollback: true, ...(errCode ? { errCode: errCode } : {}), ...(optBody || {}) }));
91
- }
92
- export function IKUnauthorizedResponse(msg, errCode) {
93
- console.warn(`Denying request - ${msg}`);
94
- return (new IKResponse(401, { err: msg, ...(errCode ? { errCode: errCode } : {}) }));
95
- }
96
- export function IKSuccessResponse(msg) { return (new IKResponse(200, (msg ? msg : {}))); }
97
- export function IKRedirectResponse(url) {
98
- const resp = new IKResponse(302);
99
- resp.appendHeader('Location', url);
100
- return resp;
101
- }
102
- export function IKSuccessNoContentResponse() { return (new IKResponse(204, null)); }
103
- export function IKSuccessStreamResponse(stream, contentType) {
104
- const resp = new IKResponse(200, (stream ? stream : {}));
105
- resp._isStream = true;
106
- resp.appendHeader('Connection', 'keep-alive');
107
- if (contentType) resp.appendHeader('Content-type', contentType);
108
- return resp;
109
- }
110
- export function IKStepFunctionResponse(body, optionalCode) {
111
- const resp = new IKResponse(optionalCode || 200, body);
112
- resp._contextRawBody = true;
113
- resp._throwOnErrors = true;
114
- return resp;
115
- }
116
- export function IKSimpleResponse(body, optionalCode) {
117
- const resp = new IKResponse(optionalCode || 200, body);
118
- return resp;
119
- }
@@ -1,51 +0,0 @@
1
-
2
- import KSUID from 'ksuid';
3
- import { convertToAttr, marshall, unmarshall } from "@aws-sdk/util-dynamodb";
4
- //
5
- export default class IKUtils {}
6
- IKUtils.isOffline = function() { return process.env.IS_OFFLINE; }
7
- IKUtils.isHybridlessContainer = function() { return process.env.HYBRIDLESS_RUNTIME; }
8
- IKUtils.logLevel = function() { return process.env.LOG_LEVEL; }
9
-
10
- //formatting
11
- IKUtils.toDoubleDigit = function(str) { return String("0" + str).slice(-2); }
12
- IKUtils.isValidString = function(string) { return (string && string.length > 0 && !Array.isArray(string)); }
13
- IKUtils.isValidNumber = function(number) {
14
- let validNumb = NaN;
15
- try { validNumb = parseInt(number + ""); }
16
- catch (e) { }
17
- return !isNaN(validNumb) && !Array.isArray(number);
18
- }
19
- //
20
- IKUtils.caseInsensitiveObjectForKey = function(obj, key) {
21
- if (!obj) return null;
22
- const insensitiveKey = Object.keys(obj).find(k => k.toLowerCase() === key.toLowerCase());
23
- if (insensitiveKey && insensitiveKey != '') return obj[insensitiveKey];
24
- return null;
25
- }
26
- IKUtils.caseInsensitiveSetObjectForKey = function(obj, key, value) {
27
- if (!obj) return null;
28
- const insensitiveKey = Object.keys(obj).find(k => k.toLowerCase() === key.toLowerCase());
29
- if (insensitiveKey && insensitiveKey != '') obj[insensitiveKey] = value;
30
- }
31
- //DB
32
- IKUtils.encapsulateForDB = function(item) {
33
- if (Array.isArray(item)) return {L: item.map(_i => IKUtils.encapsulateForDB(_i))};
34
- else if (typeof item === 'object' && isNaN(parseInt(item))) {
35
- return {M: marshall(item, {removeUndefinedValues: true, convertClassInstanceToMap: true })};
36
- } else return convertToAttr(item, {removeUndefinedValues: true, convertClassInstanceToMap: true });
37
- }
38
- IKUtils.decapsulateForDB = function(item) {
39
- if (!item && item !== false) return null;
40
- if (Array.isArray(item)) {
41
- return item.map(_item => IKUtils.decapsulateForDB(_item));
42
- } else if (typeof item === 'object') {
43
- return unmarshall(item, {removeUndefinedValues: true, convertClassInstanceToMap: true });
44
- } return item;
45
- }
46
- //Threads
47
- IKUtils.sleep = async function(delay) {
48
- return new Promise((resolve) => setTimeout(resolve, delay));
49
- }
50
- //DB
51
- IKUtils.newUID = function() { return KSUID.randomSync().string; }