@kravc/dos 1.12.5 → 2.0.0-alpha.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 (497) hide show
  1. package/README.md +31 -994
  2. package/dist/Component/Component.d.ts +43 -0
  3. package/dist/Component/Component.d.ts.map +1 -0
  4. package/dist/Component/Component.js +99 -0
  5. package/dist/Component/Component.js.map +1 -0
  6. package/dist/Component/index.d.ts +4 -0
  7. package/dist/Component/index.d.ts.map +1 -0
  8. package/dist/Component/index.js +10 -0
  9. package/dist/Component/index.js.map +1 -0
  10. package/dist/Context/Context.d.ts +86 -0
  11. package/dist/Context/Context.d.ts.map +1 -0
  12. package/dist/Context/Context.js +148 -0
  13. package/dist/Context/Context.js.map +1 -0
  14. package/dist/Context/Request.d.ts +35 -0
  15. package/dist/Context/Request.d.ts.map +1 -0
  16. package/dist/Context/Request.js +3 -0
  17. package/dist/Context/Request.js.map +1 -0
  18. package/dist/Context/__tests__/__helpers.d.ts +14 -0
  19. package/dist/Context/__tests__/__helpers.d.ts.map +1 -0
  20. package/dist/Context/__tests__/__helpers.js +69 -0
  21. package/dist/Context/__tests__/__helpers.js.map +1 -0
  22. package/dist/Context/getHttpMethod.d.ts +6 -0
  23. package/dist/Context/getHttpMethod.d.ts.map +1 -0
  24. package/dist/Context/getHttpMethod.js +16 -0
  25. package/dist/Context/getHttpMethod.js.map +1 -0
  26. package/dist/Context/getHttpPath.d.ts +6 -0
  27. package/dist/Context/getHttpPath.d.ts.map +1 -0
  28. package/dist/Context/getHttpPath.js +25 -0
  29. package/dist/Context/getHttpPath.js.map +1 -0
  30. package/dist/Context/getMutationParameters.d.ts +8 -0
  31. package/dist/Context/getMutationParameters.d.ts.map +1 -0
  32. package/dist/Context/getMutationParameters.js +25 -0
  33. package/dist/Context/getMutationParameters.js.map +1 -0
  34. package/dist/Context/getOperationId.d.ts +6 -0
  35. package/dist/Context/getOperationId.d.ts.map +1 -0
  36. package/dist/Context/getOperationId.js +21 -0
  37. package/dist/Context/getOperationId.js.map +1 -0
  38. package/dist/Context/getQueryParameters.d.ts +5 -0
  39. package/dist/Context/getQueryParameters.d.ts.map +1 -0
  40. package/dist/Context/getQueryParameters.js +33 -0
  41. package/dist/Context/getQueryParameters.js.map +1 -0
  42. package/dist/Context/index.d.ts +7 -0
  43. package/dist/Context/index.d.ts.map +1 -0
  44. package/dist/Context/index.js +12 -0
  45. package/dist/Context/index.js.map +1 -0
  46. package/dist/Context/withSafeAttributes.d.ts +23 -0
  47. package/dist/Context/withSafeAttributes.d.ts.map +1 -0
  48. package/dist/Context/withSafeAttributes.js +39 -0
  49. package/dist/Context/withSafeAttributes.js.map +1 -0
  50. package/dist/Document/Document.d.ts +114 -0
  51. package/dist/Document/Document.d.ts.map +1 -0
  52. package/dist/Document/Document.js +285 -0
  53. package/dist/Document/Document.js.map +1 -0
  54. package/dist/Document/MemoryDocument.d.ts +34 -0
  55. package/dist/Document/MemoryDocument.d.ts.map +1 -0
  56. package/dist/Document/MemoryDocument.js +103 -0
  57. package/dist/Document/MemoryDocument.js.map +1 -0
  58. package/dist/Document/__tests__/__helpers.d.ts +18 -0
  59. package/dist/Document/__tests__/__helpers.d.ts.map +1 -0
  60. package/dist/Document/__tests__/__helpers.js +28 -0
  61. package/dist/Document/__tests__/__helpers.js.map +1 -0
  62. package/dist/Document/index.d.ts +5 -0
  63. package/dist/Document/index.d.ts.map +1 -0
  64. package/dist/Document/index.js +11 -0
  65. package/dist/Document/index.js.map +1 -0
  66. package/dist/Operation/Operation.d.ts +95 -0
  67. package/dist/Operation/Operation.d.ts.map +1 -0
  68. package/dist/Operation/Operation.js +301 -0
  69. package/dist/Operation/Operation.js.map +1 -0
  70. package/dist/Operation/errors/AccessDeniedError.d.ts +22 -0
  71. package/dist/Operation/errors/AccessDeniedError.d.ts.map +1 -0
  72. package/dist/Operation/errors/AccessDeniedError.js +29 -0
  73. package/dist/Operation/errors/AccessDeniedError.js.map +1 -0
  74. package/dist/Operation/errors/CommonError.d.ts +30 -0
  75. package/dist/Operation/errors/CommonError.d.ts.map +1 -0
  76. package/dist/Operation/errors/CommonError.js +39 -0
  77. package/dist/Operation/errors/CommonError.js.map +1 -0
  78. package/dist/Operation/errors/DocumentExistsError.d.ts +27 -0
  79. package/dist/Operation/errors/DocumentExistsError.d.ts.map +1 -0
  80. package/dist/Operation/errors/DocumentExistsError.js +35 -0
  81. package/dist/Operation/errors/DocumentExistsError.js.map +1 -0
  82. package/dist/Operation/errors/DocumentNotFoundError.d.ts +28 -0
  83. package/dist/Operation/errors/DocumentNotFoundError.d.ts.map +1 -0
  84. package/dist/Operation/errors/DocumentNotFoundError.js +36 -0
  85. package/dist/Operation/errors/DocumentNotFoundError.js.map +1 -0
  86. package/dist/Operation/errors/InvalidParametersError.d.ts +27 -0
  87. package/dist/Operation/errors/InvalidParametersError.d.ts.map +1 -0
  88. package/dist/Operation/errors/InvalidParametersError.js +34 -0
  89. package/dist/Operation/errors/InvalidParametersError.js.map +1 -0
  90. package/dist/Operation/errors/UnauthorizedError.d.ts +25 -0
  91. package/dist/Operation/errors/UnauthorizedError.d.ts.map +1 -0
  92. package/dist/Operation/errors/UnauthorizedError.js +32 -0
  93. package/dist/Operation/errors/UnauthorizedError.js.map +1 -0
  94. package/dist/Operation/errors/UnprocessibleConditionError.d.ts +29 -0
  95. package/dist/Operation/errors/UnprocessibleConditionError.d.ts.map +1 -0
  96. package/dist/Operation/errors/UnprocessibleConditionError.js +36 -0
  97. package/dist/Operation/errors/UnprocessibleConditionError.js.map +1 -0
  98. package/dist/Operation/errors/index.d.ts +9 -0
  99. package/dist/Operation/errors/index.d.ts.map +1 -0
  100. package/dist/Operation/errors/index.js +21 -0
  101. package/dist/Operation/errors/index.js.map +1 -0
  102. package/dist/Operation/helpers/index.d.ts +4 -0
  103. package/dist/Operation/helpers/index.d.ts.map +1 -0
  104. package/dist/Operation/helpers/index.js +9 -0
  105. package/dist/Operation/helpers/index.js.map +1 -0
  106. package/dist/Operation/helpers/withActivity.d.ts +16 -0
  107. package/dist/Operation/helpers/withActivity.d.ts.map +1 -0
  108. package/dist/Operation/helpers/withActivity.js +23 -0
  109. package/dist/Operation/helpers/withActivity.js.map +1 -0
  110. package/dist/Operation/index.d.ts +14 -0
  111. package/dist/Operation/index.d.ts.map +1 -0
  112. package/dist/Operation/index.js +40 -0
  113. package/dist/Operation/index.js.map +1 -0
  114. package/dist/Operation/operations/Create.d.ts +5 -0
  115. package/dist/Operation/operations/Create.d.ts.map +1 -0
  116. package/dist/Operation/operations/Create.js +44 -0
  117. package/dist/Operation/operations/Create.js.map +1 -0
  118. package/dist/Operation/operations/Delete.d.ts +5 -0
  119. package/dist/Operation/operations/Delete.d.ts.map +1 -0
  120. package/dist/Operation/operations/Delete.js +58 -0
  121. package/dist/Operation/operations/Delete.js.map +1 -0
  122. package/dist/Operation/operations/Index.d.ts +11 -0
  123. package/dist/Operation/operations/Index.d.ts.map +1 -0
  124. package/dist/Operation/operations/Index.js +128 -0
  125. package/dist/Operation/operations/Index.js.map +1 -0
  126. package/dist/Operation/operations/List.d.ts +5 -0
  127. package/dist/Operation/operations/List.d.ts.map +1 -0
  128. package/dist/Operation/operations/List.js +48 -0
  129. package/dist/Operation/operations/List.js.map +1 -0
  130. package/dist/Operation/operations/Read.d.ts +5 -0
  131. package/dist/Operation/operations/Read.d.ts.map +1 -0
  132. package/dist/Operation/operations/Read.js +50 -0
  133. package/dist/Operation/operations/Read.js.map +1 -0
  134. package/dist/Operation/operations/Update.d.ts +5 -0
  135. package/dist/Operation/operations/Update.d.ts.map +1 -0
  136. package/dist/Operation/operations/Update.js +54 -0
  137. package/dist/Operation/operations/Update.js.map +1 -0
  138. package/dist/Operation/security/JwtAuthorization.d.ts +67 -0
  139. package/dist/Operation/security/JwtAuthorization.d.ts.map +1 -0
  140. package/dist/Operation/security/JwtAuthorization.js +148 -0
  141. package/dist/Operation/security/JwtAuthorization.js.map +1 -0
  142. package/dist/Operation/security/LambdaAuthorization.d.ts +30 -0
  143. package/dist/Operation/security/LambdaAuthorization.d.ts.map +1 -0
  144. package/dist/Operation/security/LambdaAuthorization.js +77 -0
  145. package/dist/Operation/security/LambdaAuthorization.js.map +1 -0
  146. package/dist/Operation/security/index.d.ts +8 -0
  147. package/dist/Operation/security/index.d.ts.map +1 -0
  148. package/dist/Operation/security/index.js +17 -0
  149. package/dist/Operation/security/index.js.map +1 -0
  150. package/dist/Operation/security/systemAuthorization.d.ts +5 -0
  151. package/dist/Operation/security/systemAuthorization.d.ts.map +1 -0
  152. package/dist/Operation/security/systemAuthorization.js +24 -0
  153. package/dist/Operation/security/systemAuthorization.js.map +1 -0
  154. package/dist/Operation/security/userAuthorization.d.ts +11 -0
  155. package/dist/Operation/security/userAuthorization.d.ts.map +1 -0
  156. package/dist/Operation/security/userAuthorization.js +36 -0
  157. package/dist/Operation/security/userAuthorization.js.map +1 -0
  158. package/dist/Operation/security/verifyToken.d.ts +6 -0
  159. package/dist/Operation/security/verifyToken.d.ts.map +1 -0
  160. package/dist/Operation/security/verifyToken.js +15 -0
  161. package/dist/Operation/security/verifyToken.js.map +1 -0
  162. package/dist/Service/Service.d.ts +62 -0
  163. package/dist/Service/Service.d.ts.map +1 -0
  164. package/dist/Service/Service.js +213 -0
  165. package/dist/Service/Service.js.map +1 -0
  166. package/dist/Service/authorize.d.ts +26 -0
  167. package/dist/Service/authorize.d.ts.map +1 -0
  168. package/dist/Service/authorize.js +40 -0
  169. package/dist/Service/authorize.js.map +1 -0
  170. package/dist/Service/errors/InvalidInputError.d.ts +29 -0
  171. package/dist/Service/errors/InvalidInputError.d.ts.map +1 -0
  172. package/dist/Service/errors/InvalidInputError.js +36 -0
  173. package/dist/Service/errors/InvalidInputError.js.map +1 -0
  174. package/dist/Service/errors/InvalidOutputError.d.ts +29 -0
  175. package/dist/Service/errors/InvalidOutputError.d.ts.map +1 -0
  176. package/dist/Service/errors/InvalidOutputError.js +36 -0
  177. package/dist/Service/errors/InvalidOutputError.js.map +1 -0
  178. package/dist/Service/errors/OperationError.d.ts +30 -0
  179. package/dist/Service/errors/OperationError.d.ts.map +1 -0
  180. package/dist/Service/errors/OperationError.js +61 -0
  181. package/dist/Service/errors/OperationError.js.map +1 -0
  182. package/dist/Service/errors/OperationNotFoundError.d.ts +38 -0
  183. package/dist/Service/errors/OperationNotFoundError.d.ts.map +1 -0
  184. package/dist/Service/errors/OperationNotFoundError.js +45 -0
  185. package/dist/Service/errors/OperationNotFoundError.js.map +1 -0
  186. package/dist/Service/errors/index.d.ts +8 -0
  187. package/dist/Service/errors/index.d.ts.map +1 -0
  188. package/dist/Service/errors/index.js +15 -0
  189. package/dist/Service/errors/index.js.map +1 -0
  190. package/dist/Service/errors/logOperationError.d.ts +35 -0
  191. package/dist/Service/errors/logOperationError.d.ts.map +1 -0
  192. package/dist/Service/errors/logOperationError.js +47 -0
  193. package/dist/Service/errors/logOperationError.js.map +1 -0
  194. package/dist/Service/errors/maskSecrets.d.ts +13 -0
  195. package/dist/Service/errors/maskSecrets.d.ts.map +1 -0
  196. package/dist/Service/errors/maskSecrets.js +57 -0
  197. package/dist/Service/errors/maskSecrets.js.map +1 -0
  198. package/dist/Service/index.d.ts +5 -0
  199. package/dist/Service/index.d.ts.map +1 -0
  200. package/dist/Service/index.js +25 -0
  201. package/dist/Service/index.js.map +1 -0
  202. package/dist/Service/logRequest.d.ts +5 -0
  203. package/dist/Service/logRequest.d.ts.map +1 -0
  204. package/dist/Service/logRequest.js +26 -0
  205. package/dist/Service/logRequest.js.map +1 -0
  206. package/dist/Service/spec/createSpec.d.ts +7 -0
  207. package/dist/Service/spec/createSpec.d.ts.map +1 -0
  208. package/dist/Service/spec/createSpec.js +56 -0
  209. package/dist/Service/spec/createSpec.js.map +1 -0
  210. package/dist/Service/spec/getErrorResponseDescription.d.ts +8 -0
  211. package/dist/Service/spec/getErrorResponseDescription.d.ts.map +1 -0
  212. package/dist/Service/spec/getErrorResponseDescription.js +15 -0
  213. package/dist/Service/spec/getErrorResponseDescription.js.map +1 -0
  214. package/dist/Service/spec/getHttpMethod.d.ts +4 -0
  215. package/dist/Service/spec/getHttpMethod.d.ts.map +1 -0
  216. package/dist/Service/spec/getHttpMethod.js +21 -0
  217. package/dist/Service/spec/getHttpMethod.js.map +1 -0
  218. package/dist/Service/spec/getOperation.d.ts +6 -0
  219. package/dist/Service/spec/getOperation.d.ts.map +1 -0
  220. package/dist/Service/spec/getOperation.js +71 -0
  221. package/dist/Service/spec/getOperation.js.map +1 -0
  222. package/dist/Service/spec/getOperationParameters.d.ts +6 -0
  223. package/dist/Service/spec/getOperationParameters.d.ts.map +1 -0
  224. package/dist/Service/spec/getOperationParameters.js +32 -0
  225. package/dist/Service/spec/getOperationParameters.js.map +1 -0
  226. package/dist/Service/spec/getServiceDefinitions.d.ts +6 -0
  227. package/dist/Service/spec/getServiceDefinitions.d.ts.map +1 -0
  228. package/dist/Service/spec/getServiceDefinitions.js +18 -0
  229. package/dist/Service/spec/getServiceDefinitions.js.map +1 -0
  230. package/dist/Service/spec/getServiceInfo.d.ts +7 -0
  231. package/dist/Service/spec/getServiceInfo.d.ts.map +1 -0
  232. package/dist/Service/spec/getServiceInfo.js +15 -0
  233. package/dist/Service/spec/getServiceInfo.js.map +1 -0
  234. package/dist/Service/spec/getServiceSecurityDefinitions.d.ts +6 -0
  235. package/dist/Service/spec/getServiceSecurityDefinitions.d.ts.map +1 -0
  236. package/dist/Service/spec/getServiceSecurityDefinitions.js +21 -0
  237. package/dist/Service/spec/getServiceSecurityDefinitions.js.map +1 -0
  238. package/dist/Service/spec/getServiceTags.d.ts +7 -0
  239. package/dist/Service/spec/getServiceTags.d.ts.map +1 -0
  240. package/dist/Service/spec/getServiceTags.js +19 -0
  241. package/dist/Service/spec/getServiceTags.js.map +1 -0
  242. package/dist/Service/spec/getSuccessStatusCode.d.ts +4 -0
  243. package/dist/Service/spec/getSuccessStatusCode.d.ts.map +1 -0
  244. package/dist/Service/spec/getSuccessStatusCode.js +14 -0
  245. package/dist/Service/spec/getSuccessStatusCode.js.map +1 -0
  246. package/dist/Service/spec/index.d.ts +3 -0
  247. package/dist/Service/spec/index.d.ts.map +1 -0
  248. package/dist/Service/spec/index.js +9 -0
  249. package/dist/Service/spec/index.js.map +1 -0
  250. package/dist/Service/spec/validateSpec.d.ts +5 -0
  251. package/dist/Service/spec/validateSpec.d.ts.map +1 -0
  252. package/dist/Service/spec/validateSpec.js +21 -0
  253. package/dist/Service/spec/validateSpec.js.map +1 -0
  254. package/dist/Service/test/createAccessToken.d.ts +9 -0
  255. package/dist/Service/test/createAccessToken.d.ts.map +1 -0
  256. package/dist/Service/test/createAccessToken.js +16 -0
  257. package/dist/Service/test/createAccessToken.js.map +1 -0
  258. package/dist/Service/test/ensureItem.d.ts +5 -0
  259. package/dist/Service/test/ensureItem.d.ts.map +1 -0
  260. package/dist/Service/test/ensureItem.js +13 -0
  261. package/dist/Service/test/ensureItem.js.map +1 -0
  262. package/dist/Service/test/ensureNoItem.d.ts +5 -0
  263. package/dist/Service/test/ensureNoItem.d.ts.map +1 -0
  264. package/dist/Service/test/ensureNoItem.js +13 -0
  265. package/dist/Service/test/ensureNoItem.js.map +1 -0
  266. package/dist/Service/test/execute.d.ts +44 -0
  267. package/dist/Service/test/execute.d.ts.map +1 -0
  268. package/dist/Service/test/execute.js +65 -0
  269. package/dist/Service/test/execute.js.map +1 -0
  270. package/dist/Service/test/findItem.d.ts +7 -0
  271. package/dist/Service/test/findItem.d.ts.map +1 -0
  272. package/dist/Service/test/findItem.js +16 -0
  273. package/dist/Service/test/findItem.js.map +1 -0
  274. package/dist/Service/test/firstItemGet.d.ts +5 -0
  275. package/dist/Service/test/firstItemGet.d.ts.map +1 -0
  276. package/dist/Service/test/firstItemGet.js +15 -0
  277. package/dist/Service/test/firstItemGet.js.map +1 -0
  278. package/dist/Service/test/index.d.ts +10 -0
  279. package/dist/Service/test/index.d.ts.map +1 -0
  280. package/dist/Service/test/index.js +36 -0
  281. package/dist/Service/test/index.js.map +1 -0
  282. package/dist/Service/test/keys.d.ts +5 -0
  283. package/dist/Service/test/keys.d.ts.map +1 -0
  284. package/dist/Service/test/keys.js +74 -0
  285. package/dist/Service/test/keys.js.map +1 -0
  286. package/dist/Service/test/wait.d.ts +4 -0
  287. package/dist/Service/test/wait.d.ts.map +1 -0
  288. package/dist/Service/test/wait.js +6 -0
  289. package/dist/Service/test/wait.js.map +1 -0
  290. package/dist/Service/useComposerMiddleware.d.ts +11 -0
  291. package/dist/Service/useComposerMiddleware.d.ts.map +1 -0
  292. package/dist/Service/useComposerMiddleware.js +41 -0
  293. package/dist/Service/useComposerMiddleware.js.map +1 -0
  294. package/dist/Service/useOasMiddleware.d.ts +16 -0
  295. package/dist/Service/useOasMiddleware.d.ts.map +1 -0
  296. package/dist/Service/useOasMiddleware.js +53 -0
  297. package/dist/Service/useOasMiddleware.js.map +1 -0
  298. package/dist/index.d.ts +11 -0
  299. package/dist/index.d.ts.map +1 -0
  300. package/dist/index.js +25 -0
  301. package/dist/index.js.map +1 -0
  302. package/eslint.config.mjs +32 -52
  303. package/example/documents/Profile/Profile.ts +8 -0
  304. package/example/documents/Profile/Profile.yaml +6 -0
  305. package/example/documents/Profile/ProfileAttributes.d.ts +5 -0
  306. package/example/documents/Profile/index.ts +3 -0
  307. package/example/documents/index.ts +5 -0
  308. package/example/index.ts +38 -0
  309. package/example/lib/createActivity.ts +28 -0
  310. package/example/lib/index.ts +24 -0
  311. package/example/operations/Profile/CreateProfile.ts +9 -0
  312. package/example/operations/Profile/DeleteProfile.ts +9 -0
  313. package/example/operations/Profile/IndexProfiles.ts +9 -0
  314. package/example/operations/Profile/ReadProfile.ts +9 -0
  315. package/example/operations/Profile/ReadProfileSystem.ts +9 -0
  316. package/example/operations/Profile/UpdateProfile.ts +9 -0
  317. package/example/operations/Service/Health.ts +11 -0
  318. package/example/operations/index.ts +22 -0
  319. package/example/security/index.ts +25 -0
  320. package/jest.config.mjs +7 -0
  321. package/package.json +34 -24
  322. package/src/Component/Component.ts +120 -0
  323. package/src/Component/__tests__/Component.test.ts +161 -0
  324. package/src/Component/index.ts +7 -0
  325. package/src/Context/Context.ts +217 -0
  326. package/src/Context/Request.ts +41 -0
  327. package/src/Context/__tests__/Context.test.ts +271 -0
  328. package/src/Context/__tests__/__helpers.ts +86 -0
  329. package/src/Context/getHttpMethod.ts +21 -0
  330. package/src/Context/getHttpPath.ts +34 -0
  331. package/src/Context/getMutationParameters.ts +35 -0
  332. package/src/Context/getOperationId.ts +23 -0
  333. package/src/Context/getQueryParameters.ts +45 -0
  334. package/src/Context/index.ts +12 -0
  335. package/src/Context/withSafeAttributes.ts +39 -0
  336. package/src/Document/Document.ts +448 -0
  337. package/src/Document/MemoryDocument.ts +152 -0
  338. package/src/Document/__tests__/MemoryDocument.test.ts +406 -0
  339. package/src/Document/__tests__/__helpers.ts +40 -0
  340. package/src/Document/index.ts +11 -0
  341. package/src/Operation/Operation.ts +401 -0
  342. package/src/Operation/__tests__/Operation.test.ts +142 -0
  343. package/src/Operation/errors/AccessDeniedError.ts +25 -0
  344. package/src/Operation/errors/CommonError.ts +41 -0
  345. package/src/Operation/errors/DocumentExistsError.ts +33 -0
  346. package/src/Operation/errors/DocumentNotFoundError.ts +34 -0
  347. package/src/Operation/errors/InvalidParametersError.ts +30 -0
  348. package/src/Operation/errors/UnauthorizedError.ts +28 -0
  349. package/src/Operation/errors/UnprocessibleConditionError.ts +32 -0
  350. package/src/Operation/errors/__tests__/InvalidParametersError.test.ts +20 -0
  351. package/src/Operation/errors/__tests__/UnprocessibleConditionError.test.ts +20 -0
  352. package/src/Operation/errors/index.ts +17 -0
  353. package/src/Operation/helpers/index.ts +9 -0
  354. package/src/Operation/helpers/withActivity.ts +43 -0
  355. package/src/Operation/index.ts +29 -0
  356. package/src/Operation/operations/Create.ts +49 -0
  357. package/src/Operation/operations/Delete.ts +65 -0
  358. package/src/Operation/operations/Index.ts +164 -0
  359. package/src/Operation/operations/List.ts +62 -0
  360. package/src/Operation/operations/Read.ts +55 -0
  361. package/src/Operation/operations/Update.ts +60 -0
  362. package/src/Operation/operations/__tests__/Create.test.ts +153 -0
  363. package/src/Operation/operations/__tests__/Delete.test.ts +163 -0
  364. package/src/Operation/operations/__tests__/Index.test.ts +209 -0
  365. package/src/Operation/operations/__tests__/List.test.ts +146 -0
  366. package/src/Operation/operations/__tests__/Read.test.ts +152 -0
  367. package/src/Operation/operations/__tests__/Update.test.ts +158 -0
  368. package/src/Operation/security/JwtAuthorization.ts +247 -0
  369. package/src/Operation/security/LambdaAuthorization.ts +103 -0
  370. package/src/Operation/security/__tests__/JwtAuthorization.test.ts +230 -0
  371. package/src/Operation/security/__tests__/LambdaAuthorization.test.ts +63 -0
  372. package/src/Operation/security/__tests__/userAuthorization.test.ts +42 -0
  373. package/src/Operation/security/index.ts +15 -0
  374. package/src/Operation/security/systemAuthorization.ts +23 -0
  375. package/src/Operation/security/userAuthorization.ts +47 -0
  376. package/src/Operation/security/verifyToken.ts +22 -0
  377. package/src/Service/Service.ts +317 -0
  378. package/src/Service/__tests__/Service.test.ts +229 -0
  379. package/src/Service/authorize.ts +80 -0
  380. package/src/Service/errors/InvalidInputError.ts +40 -0
  381. package/src/Service/errors/InvalidOutputError.ts +40 -0
  382. package/src/Service/errors/OperationError.ts +74 -0
  383. package/src/{errors → Service/errors}/OperationError.yaml +7 -10
  384. package/src/Service/errors/OperationErrorAttributes.d.ts +12 -0
  385. package/src/Service/errors/OperationNotFoundError.ts +45 -0
  386. package/src/Service/errors/__tests__/OperationError.test.ts +17 -0
  387. package/src/Service/errors/__tests__/maskSecrets.test.ts +92 -0
  388. package/src/Service/errors/index.ts +18 -0
  389. package/src/Service/errors/logOperationError.ts +72 -0
  390. package/src/Service/errors/maskSecrets.ts +65 -0
  391. package/src/Service/index.ts +9 -0
  392. package/src/Service/logRequest.ts +50 -0
  393. package/src/Service/spec/__tests__/validateSpec.test.ts +10 -0
  394. package/src/Service/spec/createSpec.ts +68 -0
  395. package/src/Service/spec/getErrorResponseDescription.ts +20 -0
  396. package/src/Service/spec/getHttpMethod.ts +20 -0
  397. package/src/Service/spec/getOperation.ts +99 -0
  398. package/src/Service/spec/getOperationParameters.ts +43 -0
  399. package/src/Service/spec/getServiceDefinitions.ts +23 -0
  400. package/src/Service/spec/getServiceInfo.ts +18 -0
  401. package/src/Service/spec/getServiceSecurityDefinitions.ts +26 -0
  402. package/src/Service/spec/getServiceTags.ts +23 -0
  403. package/src/Service/spec/getSuccessStatusCode.ts +15 -0
  404. package/src/Service/spec/index.ts +5 -0
  405. package/src/Service/spec/validateSpec.ts +22 -0
  406. package/src/Service/test/__tests__/createAccessToken.test.ts +104 -0
  407. package/src/Service/test/__tests__/ensureItem.test.ts +41 -0
  408. package/src/Service/test/__tests__/ensureNoItem.test.ts +49 -0
  409. package/src/Service/test/__tests__/execute.test.ts +125 -0
  410. package/src/Service/test/__tests__/findItem.test.ts +45 -0
  411. package/src/Service/test/__tests__/firstItemGet.test.ts +50 -0
  412. package/src/Service/test/__tests__/wait.test.ts +66 -0
  413. package/src/Service/test/createAccessToken.ts +28 -0
  414. package/src/Service/test/ensureItem.ts +9 -0
  415. package/src/Service/test/ensureNoItem.ts +9 -0
  416. package/src/Service/test/execute.ts +112 -0
  417. package/src/Service/test/findItem.ts +22 -0
  418. package/src/Service/test/firstItemGet.ts +18 -0
  419. package/src/Service/test/index.ts +19 -0
  420. package/src/Service/test/keys.ts +75 -0
  421. package/src/Service/test/wait.ts +5 -0
  422. package/src/Service/useComposerMiddleware.ts +56 -0
  423. package/src/Service/useOasMiddleware.ts +69 -0
  424. package/src/index.ts +12 -0
  425. package/tsconfig.json +26 -0
  426. package/examples/CreateProfile.js +0 -40
  427. package/examples/DeleteProfile.js +0 -6
  428. package/examples/Health.js +0 -8
  429. package/examples/IndexProfiles.js +0 -6
  430. package/examples/Profile.js +0 -8
  431. package/examples/Profile.yaml +0 -4
  432. package/examples/ReadProfile.js +0 -18
  433. package/examples/UpdateProfile.js +0 -25
  434. package/examples/index.js +0 -29
  435. package/src/Component.js +0 -59
  436. package/src/Component.spec.js +0 -65
  437. package/src/Document.js +0 -310
  438. package/src/Document.spec.js +0 -331
  439. package/src/Operation.js +0 -258
  440. package/src/Operation.spec.js +0 -474
  441. package/src/Service.js +0 -207
  442. package/src/Service.spec.js +0 -388
  443. package/src/errors/AccessDeniedError.js +0 -11
  444. package/src/errors/CommonError.js +0 -19
  445. package/src/errors/DocumentExistsError.js +0 -15
  446. package/src/errors/DocumentNotFoundError.js +0 -15
  447. package/src/errors/InvalidInputError.js +0 -19
  448. package/src/errors/InvalidOutputError.js +0 -20
  449. package/src/errors/InvalidParametersError.js +0 -11
  450. package/src/errors/OperationError.js +0 -44
  451. package/src/errors/OperationNotFoundError.js +0 -16
  452. package/src/errors/UnauthorizedError.js +0 -11
  453. package/src/errors/UnprocessibleConditionError.js +0 -11
  454. package/src/errors/index.js +0 -11
  455. package/src/helpers/asSafeClass.js +0 -22
  456. package/src/helpers/authorize.js +0 -44
  457. package/src/helpers/createContext.js +0 -96
  458. package/src/helpers/createSchemasMap.js +0 -37
  459. package/src/helpers/createSpec.js +0 -196
  460. package/src/helpers/defaultId.js +0 -30
  461. package/src/helpers/defaultSummary.js +0 -15
  462. package/src/helpers/defaultTags.js +0 -16
  463. package/src/helpers/getComponentTitle.js +0 -22
  464. package/src/helpers/getDefaultSchemaAttributes.js +0 -32
  465. package/src/helpers/getHttpMethod.js +0 -19
  466. package/src/helpers/getIdPrefix.js +0 -7
  467. package/src/helpers/getOrFail.js +0 -24
  468. package/src/helpers/getOrFail.spec.js +0 -17
  469. package/src/helpers/getSuccessStatusCode.js +0 -15
  470. package/src/helpers/handler.js +0 -21
  471. package/src/helpers/loadSync.js +0 -14
  472. package/src/helpers/logError.js +0 -33
  473. package/src/helpers/logRequest.js +0 -36
  474. package/src/helpers/maskSecrets.js +0 -42
  475. package/src/helpers/specMiddleware.js +0 -81
  476. package/src/index.d.ts +0 -350
  477. package/src/index.js +0 -35
  478. package/src/operations/Create.js +0 -39
  479. package/src/operations/Delete.js +0 -54
  480. package/src/operations/Index.js +0 -107
  481. package/src/operations/Read.js +0 -46
  482. package/src/operations/Update.js +0 -50
  483. package/src/security/JwtAuthorization.js +0 -125
  484. package/src/security/SystemAuthorization.js +0 -73
  485. package/src/security/index.js +0 -9
  486. package/src/security/verifyToken.js +0 -17
  487. package/src/test/createAccessToken.js +0 -23
  488. package/src/test/execute.js +0 -84
  489. package/src/test/index.js +0 -11
  490. package/src/test/keys.js +0 -39
  491. package/src/test/wait.js +0 -5
  492. /package/{specs → .composer}/Documents.yaml +0 -0
  493. /package/{specs → .composer}/Enums.yaml +0 -0
  494. /package/{specs → .composer}/Operations.yaml +0 -0
  495. /package/{specs → .composer}/Parameters.yaml +0 -0
  496. /package/{specs → .composer}/Scenarios.yaml +0 -0
  497. /package/{specs → .composer}/Schemas.yaml +0 -0
@@ -0,0 +1,448 @@
1
+ import { ulid } from 'ulid';
2
+ import Component from '../Component';
3
+ import { Schema, type PropertiesSchemaSource, got } from '@kravc/schema';
4
+ import Context, { type QueryMap, type MutationMap } from '../Context';
5
+ import { get, set, omit, pick, cloneDeep, capitalize } from 'lodash';
6
+
7
+ const DEFAULT_INDEX_SORT = 'desc';
8
+ const DEFAULT_INDEX_LIMIT = 300;
9
+ const DEFAULT_PARTITION_KEY = 'partition';
10
+
11
+ export type IndexOptions = {
12
+ sort?: 'asc' | 'desc';
13
+ limit?: number;
14
+ index?: string;
15
+ exclusiveStartKey?: string;
16
+ }
17
+
18
+ export type IndexAllOptions = {
19
+ sort?: 'asc' | 'desc';
20
+ index?: string;
21
+ }
22
+
23
+ export type DefaultAttributes = {
24
+ id: string;
25
+ createdAt: string;
26
+ createdBy: string;
27
+ createdByUserName?: string;
28
+ updatedAt?: string;
29
+ updatedBy?: string;
30
+ updatedByUserName?: string;
31
+ };
32
+
33
+ type Constructor<T, D extends Document<T> = Document<T>> = {
34
+ new(context: Context, attributes: T): D;
35
+
36
+ _index(query: QueryMap, options: IndexOptions): Promise<{
37
+ count: number;
38
+ items: T[];
39
+ lastEvaluatedKey?: string;
40
+ }>;
41
+
42
+ _indexAll(query: QueryMap, options: IndexAllOptions): Promise<{
43
+ count: number;
44
+ items: T[];
45
+ }>;
46
+
47
+ _read(query: QueryMap, options: unknown): Promise<T>;
48
+
49
+ _create(attributes: T): Promise<void>;
50
+
51
+ _update<T>(query: QueryMap, mutation: MutationMap): Promise<T>;
52
+
53
+ _delete(query: QueryMap): Promise<void>;
54
+ };
55
+
56
+ /** Abstract document class. */
57
+ class Document<Attributes> extends Component<Attributes> {
58
+ private static _bodySchema: Schema;
59
+
60
+ private _previousAttributes: Attributes | undefined;
61
+
62
+ /** Returns partition key of a document. */
63
+ static get partitionKey(): string {
64
+ return DEFAULT_PARTITION_KEY;
65
+ }
66
+
67
+ /** Returns prefix for new IDs. */
68
+ static get idPrefix(): string {
69
+ return this.name;
70
+ }
71
+
72
+ /** Returns attribute name to sort index action results by. */
73
+ static get indexSortBy(): string {
74
+ return this.idKey;
75
+ }
76
+
77
+ /** Defines default sort direction for index action results. */
78
+ static get indexDefaultSort(): 'asc' | 'desc' {
79
+ return DEFAULT_INDEX_SORT;
80
+ }
81
+
82
+ /** Defines default limit for index action. */
83
+ static get indexDefaultLimit(): number {
84
+ return DEFAULT_INDEX_LIMIT;
85
+ }
86
+
87
+ /** Generates ID for new document unless it's defined in parameters. */
88
+ static createId(attributes: Record<string, unknown>): string {
89
+ const id = get(attributes, this.idKey) as string;
90
+ const hasId = !!id;
91
+
92
+ if (hasId) {
93
+ return id;
94
+ }
95
+
96
+ return `${this.idPrefix}_` + ulid();
97
+ }
98
+
99
+ /** Returns default attributes schema source. */
100
+ static get defaultAttributesSchemaSource(): PropertiesSchemaSource {
101
+ const documentTitle = this.getTitle(false);
102
+
103
+ return {
104
+ id: {
105
+ description: capitalize(documentTitle) + ' ID',
106
+ required: true
107
+ },
108
+ createdAt: {
109
+ description: `Date and time when ${documentTitle} was created`,
110
+ format: 'date-time',
111
+ required: true
112
+ },
113
+ createdBy: {
114
+ description: `ID of a user who created ${documentTitle}`,
115
+ required: true
116
+ },
117
+ createdByUserName: {
118
+ description: `Name of a user who created ${documentTitle}`
119
+ },
120
+ updatedAt: {
121
+ description: `Date and time when ${documentTitle} was updated`,
122
+ format: 'date-time'
123
+ },
124
+ updatedBy: {
125
+ description: `ID of a user who updated ${documentTitle}`
126
+ },
127
+ updatedByUserName: {
128
+ description: `Name of a user who updated ${documentTitle}`
129
+ }
130
+ };
131
+ }
132
+
133
+ /** Extends document schema with default attributes. */
134
+ static set schema(schema: Schema) {
135
+ this._schema = schema.extend(this.defaultAttributesSchemaSource, this.id);
136
+ this._bodySchema = schema.clone(`${this.id}Body`);
137
+ }
138
+
139
+ /** Returns schema to validate document attributes. */
140
+ static get schema(): Schema {
141
+ if (!this._schema) {
142
+ throw new Error(`Schema is not set for "${this.id}"`);
143
+ }
144
+
145
+ return this._schema;
146
+ }
147
+
148
+ /** Returns body schema of a document. */
149
+ static get bodySchema() {
150
+ return this._bodySchema;
151
+ }
152
+
153
+ /** Returns schema for document create and update mutations. */
154
+ static get mutationSchema(): Schema {
155
+ return this.bodySchema;
156
+ }
157
+
158
+ /** Returns partition to save document based on context and parameters. */
159
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
160
+ static getPartition(_context: Context, _parameters: Record<string, unknown>): string | undefined {
161
+ return undefined;
162
+ }
163
+
164
+ /** Extends parameters with partition of a document. */
165
+ static _extendWithPartition(context: Context, parameters: Record<string, unknown>): void {
166
+ const hasPartition = !!get(parameters, this.partitionKey);
167
+
168
+ if (hasPartition) {
169
+ return;
170
+ }
171
+
172
+ const partition = this.getPartition(context, parameters);
173
+
174
+ if (!partition) {
175
+ return;
176
+ }
177
+
178
+ set(parameters, this.partitionKey, partition);
179
+ }
180
+
181
+ /** Extends mutation with created stamps. */
182
+ static _extendWithCreatedStamps(context: Context, mutation: MutationMap) {
183
+ const timestamp = new Date().toJSON();
184
+
185
+ mutation.createdAt = timestamp;
186
+ mutation.createdBy = context.identityId;
187
+ mutation.createdByUserName = context.identityName;
188
+ }
189
+
190
+ /** Extends mutation with updated stamps. */
191
+ static _extendWithUpdatedStamps(context: Context, mutation: MutationMap) {
192
+ const timestamp = new Date().toJSON();
193
+
194
+ mutation.updatedAt = timestamp;
195
+ mutation.updatedBy = context.identityId;
196
+ mutation.updatedByUserName = context.identityName;
197
+ }
198
+
199
+ /** Returns documents in batches. */
200
+ static async index<T, D extends Document<T> = Document<T>>(
201
+ this: Constructor<T, D>,
202
+ context: Context,
203
+ query: QueryMap = {},
204
+ options: IndexOptions = {}
205
+ ): Promise<{
206
+ count: number;
207
+ objects: D[];
208
+ lastEvaluatedKey?: string;
209
+ }> {
210
+ const _this = this as unknown as typeof Document;
211
+ _this._extendWithPartition(context, query);
212
+
213
+ if (!options.limit) {
214
+ options.limit = _this.indexDefaultLimit;
215
+ }
216
+
217
+ if (!options.sort) {
218
+ options.sort = _this.indexDefaultSort;
219
+ }
220
+
221
+ const { items, count, lastEvaluatedKey, ...otherPagination } = await this._index(query, options);
222
+ const objects = items.map(attributes => new this(context, attributes));
223
+
224
+ return { objects, count, lastEvaluatedKey, ...otherPagination };
225
+ }
226
+
227
+ /** Returns all documents. */
228
+ static async indexAll<T, D extends Document<T> = Document<T>>(
229
+ this: Constructor<T, D>,
230
+ context: Context,
231
+ query: QueryMap = {},
232
+ options: IndexAllOptions = {}
233
+ ): Promise<{
234
+ count: number;
235
+ objects: D[];
236
+ }> {
237
+ const _this = this as unknown as typeof Document;
238
+ _this._extendWithPartition(context, query);
239
+
240
+ if (!options.sort) {
241
+ options.sort = _this.indexDefaultSort;
242
+ }
243
+
244
+ const { items, count } = await this._indexAll(query, options);
245
+ const objects = items.map(attributes => new this(context, attributes));
246
+
247
+ return { objects, count };
248
+ }
249
+
250
+ /** Returns a document by ID attribute. */
251
+ static async read<T, D extends Document<T> = Document<T>>(
252
+ this: Constructor<T, D>,
253
+ context: Context,
254
+ query: QueryMap,
255
+ options?: unknown
256
+ ): Promise<D> {
257
+ const _this = this as unknown as typeof Document;
258
+ _this._extendWithPartition(context, query);
259
+
260
+ const attributes = await this._read(query, options);
261
+ const object = new this(context, attributes);
262
+
263
+ return object;
264
+ }
265
+
266
+ /** Creates a document. */
267
+ static async create<T, D extends Document<T> = Document<T>>(
268
+ this: Constructor<T, D>,
269
+ context: Context,
270
+ query: QueryMap | MutationMap,
271
+ mutation?: MutationMap
272
+ ): Promise<D> {
273
+ const _this = this as unknown as typeof Document;
274
+
275
+ // NOTE: This allows implementing the create-unless-exists flow, which first
276
+ // checks existence of the document via before hooks. If it does
277
+ // exist, they add it to the context. Then the operation's action
278
+ // method would do nothing and just return the document from the context.
279
+ const createdDocument = context.get('createdDocument') as D;
280
+ const shouldNotCreate = createdDocument?.componentId === this.name;
281
+
282
+ if (shouldNotCreate) {
283
+ return createdDocument;
284
+ }
285
+
286
+ if (!mutation) {
287
+ mutation = query;
288
+ query = {};
289
+ }
290
+
291
+ const { validator } = context;
292
+ const attributes = validator.normalize(mutation, _this.id) as MutationMap;
293
+
294
+ const idValue = _this.createId(attributes);
295
+ set(attributes, _this.idKey, idValue);
296
+
297
+ _this._extendWithCreatedStamps(context, attributes);
298
+ _this._extendWithPartition(context, attributes);
299
+
300
+ await _this.beforeCreate(context, query, attributes);
301
+
302
+ await this._create(attributes as T);
303
+ const object = new this(context, attributes as T);
304
+
305
+ await _this.afterCreate(context, query, mutation, object);
306
+
307
+ return object;
308
+ }
309
+
310
+ /** Before create hook. */
311
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
312
+ static async beforeCreate(_context: Context, _query: QueryMap, _mutation: MutationMap): Promise<void> {
313
+ return;
314
+ }
315
+
316
+ /** After create hook. */
317
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
318
+ static async afterCreate(_context: Context, _query: QueryMap, _mutation: MutationMap, _createdDocument: unknown): Promise<void> {
319
+ return;
320
+ }
321
+
322
+ /** Updates a document. */
323
+ static async update<T, D extends Document<T> = Document<T>>(
324
+ this: Constructor<T, D>,
325
+ context: Context,
326
+ query: QueryMap,
327
+ mutation: MutationMap
328
+ ): Promise<D> {
329
+ const _this = this as unknown as typeof Document;
330
+
331
+ mutation = omit(mutation, Object.keys(_this.defaultAttributesSchemaSource));
332
+
333
+ _this._extendWithUpdatedStamps(context, mutation);
334
+ _this._extendWithPartition(context, query);
335
+
336
+ await _this.beforeUpdate(context, query, mutation);
337
+
338
+ /* NOTE: In some workflows operation before action helper may be doing
339
+ some verifications with the document to be updated. Here we
340
+ allow to cache it in the context. */
341
+ const idValue = got(query, _this.idKey, 'Query parameter "$PATH" is required') as string;
342
+
343
+ const previousDocument = context.get(idValue) as D;
344
+ let previousAttributes = previousDocument?.attributes;
345
+
346
+ /* NOTE: Ensure that document to be updated exists and save it in the
347
+ context so can be referenced in the after action helper. */
348
+ if (!previousAttributes) {
349
+ previousAttributes = await this._read(query, {});
350
+ }
351
+
352
+ const updatedAttributes = await this._update(query, mutation) as T;
353
+ const object = new this(context, updatedAttributes);
354
+
355
+ object._previousAttributes = previousAttributes;
356
+
357
+ await _this.afterUpdate(context, query, mutation, object);
358
+
359
+ return object;
360
+ }
361
+
362
+ /** Before update hook. */
363
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
364
+ static async beforeUpdate(_context: Context, _query: QueryMap, _mutation: MutationMap): Promise<void> {
365
+ return;
366
+ }
367
+
368
+ /** After update hook. */
369
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
370
+ static async afterUpdate(_context: Context, _query: QueryMap, _mutation: MutationMap, _updatedDocument: unknown): Promise<void> {
371
+ return;
372
+ }
373
+
374
+ /** Deletes a document. */
375
+ static async delete<T, D extends Document<T> = Document<T>>(
376
+ this: Constructor<T, D>,
377
+ context: Context,
378
+ query: QueryMap,
379
+ ): Promise<D> {
380
+ const _this = this as unknown as typeof Document;
381
+
382
+ _this._extendWithPartition(context, query);
383
+
384
+ await _this.beforeDelete(context, query);
385
+
386
+ const attributes = await this._read(query, {});
387
+ const object = new this(context, attributes);
388
+
389
+ await this._delete(query);
390
+
391
+ await _this.afterDelete(context, query, object);
392
+
393
+ return object;
394
+ }
395
+
396
+ /** Before delete hook. */
397
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
398
+ static async beforeDelete(_context: Context, _query: QueryMap): Promise<void> {
399
+ return;
400
+ }
401
+
402
+ /** After delete hook. */
403
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
404
+ static async afterDelete(_context: Context, _query: QueryMap, _deletedDocument: unknown): Promise<void> {
405
+ return;
406
+ }
407
+
408
+ /** Returns document ID. */
409
+ get id(): string {
410
+ const klass = this.constructor as unknown as typeof Document;
411
+ return got(this.attributes as Record<string, string>, klass.idKey);
412
+ }
413
+
414
+ /** Returns previous attributes after update action. */
415
+ get previousAttributes() {
416
+ return this._previousAttributes || null;
417
+ }
418
+
419
+ /** Flags if document attribute has been changed via update action. */
420
+ hasAttributeChanged(path: string): boolean {
421
+ if (!this.previousAttributes) {
422
+ throw Error(`${this.componentId} ${this.id} has not been updated`);
423
+ }
424
+
425
+ const currentValue = get(this.attributes, path);
426
+ const previousValue = get(this.previousAttributes, path);
427
+
428
+ const hasChanged = previousValue !== currentValue;
429
+
430
+ return hasChanged;
431
+ }
432
+
433
+ /** Updates document attributes. */
434
+ async update(mutation: MutationMap): Promise<void> {
435
+ const klass = this.constructor as unknown as Constructor<Attributes, Document<Attributes>> & typeof Document;
436
+
437
+ this.context.set(this.id, this);
438
+
439
+ const query = pick(this.attributes, [ klass.idKey, klass.partitionKey ]);
440
+ const object = await klass.update(this.context, query, mutation);
441
+
442
+ this._previousAttributes = cloneDeep(this.attributes) as Attributes;
443
+
444
+ set(this, '_attributes', object.attributes);
445
+ }
446
+ }
447
+
448
+ export default Document;
@@ -0,0 +1,152 @@
1
+ import { got } from '@kravc/schema';
2
+ import type { QueryMap, MutationMap } from '../Context';
3
+ import { get, set, last, unset, cloneDeep, sortBy } from 'lodash';
4
+ import { DocumentExistsError, DocumentNotFoundError } from '../Operation';
5
+ import Document, { type IndexOptions, type IndexAllOptions } from './Document';
6
+
7
+ type Item = {
8
+ id: string;
9
+ [index: string]: unknown;
10
+ };
11
+
12
+ const _MEMORY_STORE = {} as Record<string, Record<string, Item>>;
13
+
14
+ /** Example implementation of a document class stored in memory. */
15
+ class MemoryDocument<T> extends Document<T> {
16
+ /** Returns collection where documents are stored. */
17
+ static get collection() {
18
+ const collectionName = this.name;
19
+
20
+ const hasCollection = !!_MEMORY_STORE[collectionName];
21
+
22
+ if (!hasCollection) {
23
+ _MEMORY_STORE[collectionName] = {};
24
+ }
25
+
26
+ return _MEMORY_STORE[collectionName];
27
+ }
28
+
29
+ /** Resets collection. */
30
+ static async reset() {
31
+ const collectionName = this.name;
32
+
33
+ delete _MEMORY_STORE[collectionName];
34
+ }
35
+
36
+ /** Implements interface to get documents in batches. */
37
+ static async _index<T>(query: QueryMap, options: IndexOptions): Promise<{
38
+ count: number;
39
+ items: T[];
40
+ lastEvaluatedKey?: string;
41
+ }> {
42
+ const {
43
+ sort,
44
+ limit,
45
+ exclusiveStartKey
46
+ } = options;
47
+
48
+ /** Filters result item to match query. */
49
+ const filter = (item: Item) =>
50
+ Object
51
+ .keys(query)
52
+ .every(key => item[key] === query[key]);
53
+
54
+ const sortedItems = sort === 'desc'
55
+ ? sortBy(Object.values(this.collection), this.indexSortBy).reverse()
56
+ : sortBy(Object.values(this.collection), this.indexSortBy);
57
+
58
+ const filteredItems = sortedItems
59
+ .filter(filter)
60
+ .map(cloneDeep) as T[];
61
+
62
+ let exclusiveStartKeyIndex = -1;
63
+
64
+ if (exclusiveStartKey) {
65
+ exclusiveStartKeyIndex = filteredItems
66
+ .findIndex(item => got(item, this.idKey) === exclusiveStartKey);
67
+ }
68
+
69
+ const items = limit
70
+ ? filteredItems.slice(exclusiveStartKeyIndex + 1, exclusiveStartKeyIndex + 1 + limit)
71
+ : filteredItems.slice(exclusiveStartKeyIndex + 1, filteredItems.length);
72
+
73
+ const count = items.length;
74
+
75
+ let lastEvaluatedKey = get(last(items), this.idKey);
76
+
77
+ const isLastItemIncluded = get(last(sortedItems), this.idKey) === lastEvaluatedKey;
78
+
79
+ if (isLastItemIncluded) {
80
+ lastEvaluatedKey = undefined;
81
+ }
82
+
83
+ return {
84
+ items,
85
+ count,
86
+ lastEvaluatedKey,
87
+ };
88
+ }
89
+
90
+ /** Implements interface to get all documents. */
91
+ static async _indexAll<T>(query: QueryMap, options: IndexAllOptions): Promise<{
92
+ count: number;
93
+ items: T[];
94
+ }> {
95
+ const { items, count } = await this._index<T>(query, options);
96
+
97
+ return {
98
+ items,
99
+ count,
100
+ };
101
+ }
102
+
103
+ /** Implements interface to get a document. */
104
+ static async _read<T>(query: QueryMap): Promise<T> {
105
+ const idValue = got(query, this.idKey, 'Query parameter "$PATH" is required') as string;
106
+
107
+ const item = get(this.collection, idValue) as T;
108
+
109
+ if (!item) {
110
+ throw new DocumentNotFoundError(this, query);
111
+ }
112
+
113
+ return cloneDeep(item);
114
+ }
115
+
116
+ /** Implements interface to save a document, returns false if document is not created. */
117
+ static async _create<T>(attributes: T): Promise<void> {
118
+ const idValue = got(attributes, this.idKey, 'Attribute "$PATH" is required') as string;
119
+
120
+ const item = get(this.collection, idValue) as T;
121
+
122
+ if (item) {
123
+ throw new DocumentExistsError(this, attributes as Record<string, unknown>);
124
+ }
125
+
126
+ set(this.collection, idValue, attributes);
127
+ }
128
+
129
+ /** Implements interface to update a document. */
130
+ static async _update<T>(query: QueryMap, mutation: MutationMap): Promise<T> {
131
+ const idValue = got(query, this.idKey, 'Query parameter "$PATH" is required') as string;
132
+
133
+ const componentTitle = this.getTitle();
134
+ const item = got(this.collection, idValue, `${componentTitle} with ID "$PATH" is not found`) as T;
135
+
136
+ set(this.collection, idValue, { ...item, ...mutation });
137
+
138
+ return cloneDeep({ ...item, ...mutation });
139
+ }
140
+
141
+ /** Implements interface to delete a document. */
142
+ static async _delete<T>(query: QueryMap): Promise<void> {
143
+ const idValue = got(query, this.idKey, 'Query parameter "$PATH" is required') as string;
144
+
145
+ const componentTitle = this.getTitle();
146
+ got(this.collection, idValue, `${componentTitle} with ID "$PATH" is not found`) as T;
147
+
148
+ unset(this.collection, idValue);
149
+ }
150
+ }
151
+
152
+ export default MemoryDocument;